@rejourneyco/react-native 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 (152) hide show
  1. package/android/build.gradle.kts +135 -0
  2. package/android/consumer-rules.pro +10 -0
  3. package/android/proguard-rules.pro +1 -0
  4. package/android/src/main/AndroidManifest.xml +15 -0
  5. package/android/src/main/java/com/rejourney/RejourneyModuleImpl.kt +2981 -0
  6. package/android/src/main/java/com/rejourney/capture/ANRHandler.kt +206 -0
  7. package/android/src/main/java/com/rejourney/capture/ActivityTracker.kt +98 -0
  8. package/android/src/main/java/com/rejourney/capture/CaptureEngine.kt +1553 -0
  9. package/android/src/main/java/com/rejourney/capture/CaptureHeuristics.kt +375 -0
  10. package/android/src/main/java/com/rejourney/capture/CrashHandler.kt +153 -0
  11. package/android/src/main/java/com/rejourney/capture/MotionEvent.kt +215 -0
  12. package/android/src/main/java/com/rejourney/capture/SegmentUploader.kt +512 -0
  13. package/android/src/main/java/com/rejourney/capture/VideoEncoder.kt +773 -0
  14. package/android/src/main/java/com/rejourney/capture/ViewHierarchyScanner.kt +633 -0
  15. package/android/src/main/java/com/rejourney/capture/ViewSerializer.kt +286 -0
  16. package/android/src/main/java/com/rejourney/core/Constants.kt +117 -0
  17. package/android/src/main/java/com/rejourney/core/Logger.kt +93 -0
  18. package/android/src/main/java/com/rejourney/core/Types.kt +124 -0
  19. package/android/src/main/java/com/rejourney/lifecycle/SessionLifecycleService.kt +162 -0
  20. package/android/src/main/java/com/rejourney/network/DeviceAuthManager.kt +747 -0
  21. package/android/src/main/java/com/rejourney/network/HttpClientProvider.kt +16 -0
  22. package/android/src/main/java/com/rejourney/network/NetworkMonitor.kt +272 -0
  23. package/android/src/main/java/com/rejourney/network/UploadManager.kt +1363 -0
  24. package/android/src/main/java/com/rejourney/network/UploadWorker.kt +492 -0
  25. package/android/src/main/java/com/rejourney/privacy/PrivacyMask.kt +645 -0
  26. package/android/src/main/java/com/rejourney/touch/GestureClassifier.kt +233 -0
  27. package/android/src/main/java/com/rejourney/touch/KeyboardTracker.kt +158 -0
  28. package/android/src/main/java/com/rejourney/touch/TextInputTracker.kt +181 -0
  29. package/android/src/main/java/com/rejourney/touch/TouchInterceptor.kt +591 -0
  30. package/android/src/main/java/com/rejourney/utils/EventBuffer.kt +284 -0
  31. package/android/src/main/java/com/rejourney/utils/OEMDetector.kt +154 -0
  32. package/android/src/main/java/com/rejourney/utils/PerfTiming.kt +235 -0
  33. package/android/src/main/java/com/rejourney/utils/Telemetry.kt +297 -0
  34. package/android/src/main/java/com/rejourney/utils/WindowUtils.kt +84 -0
  35. package/android/src/newarch/java/com/rejourney/RejourneyModule.kt +187 -0
  36. package/android/src/newarch/java/com/rejourney/RejourneyPackage.kt +40 -0
  37. package/android/src/oldarch/java/com/rejourney/RejourneyModule.kt +218 -0
  38. package/android/src/oldarch/java/com/rejourney/RejourneyPackage.kt +23 -0
  39. package/ios/Capture/RJANRHandler.h +42 -0
  40. package/ios/Capture/RJANRHandler.m +328 -0
  41. package/ios/Capture/RJCaptureEngine.h +275 -0
  42. package/ios/Capture/RJCaptureEngine.m +2062 -0
  43. package/ios/Capture/RJCaptureHeuristics.h +80 -0
  44. package/ios/Capture/RJCaptureHeuristics.m +903 -0
  45. package/ios/Capture/RJCrashHandler.h +46 -0
  46. package/ios/Capture/RJCrashHandler.m +313 -0
  47. package/ios/Capture/RJMotionEvent.h +183 -0
  48. package/ios/Capture/RJMotionEvent.m +183 -0
  49. package/ios/Capture/RJPerformanceManager.h +100 -0
  50. package/ios/Capture/RJPerformanceManager.m +373 -0
  51. package/ios/Capture/RJPixelBufferDownscaler.h +42 -0
  52. package/ios/Capture/RJPixelBufferDownscaler.m +85 -0
  53. package/ios/Capture/RJSegmentUploader.h +146 -0
  54. package/ios/Capture/RJSegmentUploader.m +778 -0
  55. package/ios/Capture/RJVideoEncoder.h +247 -0
  56. package/ios/Capture/RJVideoEncoder.m +1036 -0
  57. package/ios/Capture/RJViewControllerTracker.h +73 -0
  58. package/ios/Capture/RJViewControllerTracker.m +508 -0
  59. package/ios/Capture/RJViewHierarchyScanner.h +215 -0
  60. package/ios/Capture/RJViewHierarchyScanner.m +1464 -0
  61. package/ios/Capture/RJViewSerializer.h +119 -0
  62. package/ios/Capture/RJViewSerializer.m +498 -0
  63. package/ios/Core/RJConstants.h +124 -0
  64. package/ios/Core/RJConstants.m +88 -0
  65. package/ios/Core/RJLifecycleManager.h +85 -0
  66. package/ios/Core/RJLifecycleManager.m +308 -0
  67. package/ios/Core/RJLogger.h +61 -0
  68. package/ios/Core/RJLogger.m +211 -0
  69. package/ios/Core/RJTypes.h +176 -0
  70. package/ios/Core/RJTypes.m +66 -0
  71. package/ios/Core/Rejourney.h +64 -0
  72. package/ios/Core/Rejourney.mm +2495 -0
  73. package/ios/Network/RJDeviceAuthManager.h +94 -0
  74. package/ios/Network/RJDeviceAuthManager.m +967 -0
  75. package/ios/Network/RJNetworkMonitor.h +68 -0
  76. package/ios/Network/RJNetworkMonitor.m +267 -0
  77. package/ios/Network/RJRetryManager.h +73 -0
  78. package/ios/Network/RJRetryManager.m +325 -0
  79. package/ios/Network/RJUploadManager.h +267 -0
  80. package/ios/Network/RJUploadManager.m +2296 -0
  81. package/ios/Privacy/RJPrivacyMask.h +163 -0
  82. package/ios/Privacy/RJPrivacyMask.m +922 -0
  83. package/ios/Rejourney.h +63 -0
  84. package/ios/Touch/RJGestureClassifier.h +130 -0
  85. package/ios/Touch/RJGestureClassifier.m +333 -0
  86. package/ios/Touch/RJTouchInterceptor.h +169 -0
  87. package/ios/Touch/RJTouchInterceptor.m +772 -0
  88. package/ios/Utils/RJEventBuffer.h +112 -0
  89. package/ios/Utils/RJEventBuffer.m +358 -0
  90. package/ios/Utils/RJGzipUtils.h +33 -0
  91. package/ios/Utils/RJGzipUtils.m +89 -0
  92. package/ios/Utils/RJKeychainManager.h +48 -0
  93. package/ios/Utils/RJKeychainManager.m +111 -0
  94. package/ios/Utils/RJPerfTiming.h +209 -0
  95. package/ios/Utils/RJPerfTiming.m +264 -0
  96. package/ios/Utils/RJTelemetry.h +92 -0
  97. package/ios/Utils/RJTelemetry.m +320 -0
  98. package/ios/Utils/RJWindowUtils.h +66 -0
  99. package/ios/Utils/RJWindowUtils.m +133 -0
  100. package/lib/commonjs/NativeRejourney.js +40 -0
  101. package/lib/commonjs/components/Mask.js +79 -0
  102. package/lib/commonjs/index.js +1381 -0
  103. package/lib/commonjs/sdk/autoTracking.js +1259 -0
  104. package/lib/commonjs/sdk/constants.js +151 -0
  105. package/lib/commonjs/sdk/errorTracking.js +199 -0
  106. package/lib/commonjs/sdk/index.js +50 -0
  107. package/lib/commonjs/sdk/metricsTracking.js +204 -0
  108. package/lib/commonjs/sdk/navigation.js +151 -0
  109. package/lib/commonjs/sdk/networkInterceptor.js +412 -0
  110. package/lib/commonjs/sdk/utils.js +363 -0
  111. package/lib/commonjs/types/expo-router.d.js +2 -0
  112. package/lib/commonjs/types/index.js +2 -0
  113. package/lib/module/NativeRejourney.js +38 -0
  114. package/lib/module/components/Mask.js +72 -0
  115. package/lib/module/index.js +1284 -0
  116. package/lib/module/sdk/autoTracking.js +1233 -0
  117. package/lib/module/sdk/constants.js +145 -0
  118. package/lib/module/sdk/errorTracking.js +189 -0
  119. package/lib/module/sdk/index.js +12 -0
  120. package/lib/module/sdk/metricsTracking.js +187 -0
  121. package/lib/module/sdk/navigation.js +143 -0
  122. package/lib/module/sdk/networkInterceptor.js +401 -0
  123. package/lib/module/sdk/utils.js +342 -0
  124. package/lib/module/types/expo-router.d.js +2 -0
  125. package/lib/module/types/index.js +2 -0
  126. package/lib/typescript/NativeRejourney.d.ts +147 -0
  127. package/lib/typescript/components/Mask.d.ts +39 -0
  128. package/lib/typescript/index.d.ts +117 -0
  129. package/lib/typescript/sdk/autoTracking.d.ts +204 -0
  130. package/lib/typescript/sdk/constants.d.ts +120 -0
  131. package/lib/typescript/sdk/errorTracking.d.ts +32 -0
  132. package/lib/typescript/sdk/index.d.ts +9 -0
  133. package/lib/typescript/sdk/metricsTracking.d.ts +58 -0
  134. package/lib/typescript/sdk/navigation.d.ts +33 -0
  135. package/lib/typescript/sdk/networkInterceptor.d.ts +47 -0
  136. package/lib/typescript/sdk/utils.d.ts +148 -0
  137. package/lib/typescript/types/index.d.ts +624 -0
  138. package/package.json +102 -0
  139. package/rejourney.podspec +21 -0
  140. package/src/NativeRejourney.ts +165 -0
  141. package/src/components/Mask.tsx +80 -0
  142. package/src/index.ts +1459 -0
  143. package/src/sdk/autoTracking.ts +1373 -0
  144. package/src/sdk/constants.ts +134 -0
  145. package/src/sdk/errorTracking.ts +231 -0
  146. package/src/sdk/index.ts +11 -0
  147. package/src/sdk/metricsTracking.ts +232 -0
  148. package/src/sdk/navigation.ts +157 -0
  149. package/src/sdk/networkInterceptor.ts +440 -0
  150. package/src/sdk/utils.ts +369 -0
  151. package/src/types/expo-router.d.ts +7 -0
  152. package/src/types/index.ts +739 -0
@@ -0,0 +1,68 @@
1
+ //
2
+ // RJNetworkMonitor.h
3
+ // Rejourney
4
+ //
5
+ // Network quality monitoring using NWPathMonitor.
6
+ //
7
+ // Copyright (c) 2026 Rejourney
8
+ //
9
+
10
+ #import <Foundation/Foundation.h>
11
+
12
+ NS_ASSUME_NONNULL_BEGIN
13
+
14
+ /// Network type enumeration
15
+ typedef NS_ENUM(NSInteger, RJNetworkType) {
16
+ RJNetworkTypeNone = 0,
17
+ RJNetworkTypeWiFi,
18
+ RJNetworkTypeCellular,
19
+ RJNetworkTypeWired,
20
+ RJNetworkTypeOther
21
+ };
22
+
23
+ /// Cellular generation enumeration
24
+ typedef NS_ENUM(NSInteger, RJCellularGeneration) {
25
+ RJCellularGenerationUnknown = 0,
26
+ RJCellularGeneration2G,
27
+ RJCellularGeneration3G,
28
+ RJCellularGeneration4G,
29
+ RJCellularGeneration5G
30
+ };
31
+
32
+ /// Network quality snapshot
33
+ @interface RJNetworkQuality : NSObject
34
+
35
+ @property(nonatomic, assign) RJNetworkType networkType;
36
+ @property(nonatomic, assign) RJCellularGeneration cellularGeneration;
37
+ @property(nonatomic, assign) BOOL isConstrained; // Low data mode
38
+ @property(nonatomic, assign) BOOL isExpensive; // Metered connection
39
+ @property(nonatomic, assign) NSTimeInterval timestamp;
40
+
41
+ - (NSDictionary *)toDictionary;
42
+
43
+ @end
44
+
45
+ /// Protocol for network quality change notifications
46
+ @protocol RJNetworkMonitorDelegate <NSObject>
47
+ @optional
48
+ - (void)networkMonitor:(id)monitor
49
+ didDetectNetworkChange:(RJNetworkQuality *)quality;
50
+ @end
51
+
52
+ /// Network quality monitor using NWPathMonitor
53
+ @interface RJNetworkMonitor : NSObject
54
+
55
+ @property(nonatomic, weak, nullable) id<RJNetworkMonitorDelegate> delegate;
56
+ @property(nonatomic, readonly) RJNetworkQuality *currentQuality;
57
+
58
+ + (instancetype)sharedInstance;
59
+
60
+ - (void)startMonitoring;
61
+ - (void)stopMonitoring;
62
+
63
+ /// Get current network quality snapshot
64
+ - (RJNetworkQuality *)captureNetworkQuality;
65
+
66
+ @end
67
+
68
+ NS_ASSUME_NONNULL_END
@@ -0,0 +1,267 @@
1
+ //
2
+ // RJNetworkMonitor.m
3
+ // Rejourney
4
+ //
5
+ // Network quality monitoring implementation using NWPathMonitor.
6
+ //
7
+ // Copyright (c) 2026 Rejourney
8
+ //
9
+
10
+ #import "RJNetworkMonitor.h"
11
+ #import <TargetConditionals.h>
12
+
13
+ #if TARGET_OS_IOS
14
+ #import <CoreTelephony/CTCarrier.h>
15
+ #import <CoreTelephony/CTTelephonyNetworkInfo.h>
16
+ #import <Network/Network.h>
17
+ #endif
18
+
19
+ #import "../Core/RJLogger.h"
20
+
21
+ #pragma mark - RJNetworkQuality Implementation
22
+
23
+ @implementation RJNetworkQuality
24
+
25
+ - (instancetype)init {
26
+ self = [super init];
27
+ if (self) {
28
+ _networkType = RJNetworkTypeNone;
29
+ _cellularGeneration = RJCellularGenerationUnknown;
30
+ _isConstrained = NO;
31
+ _isExpensive = NO;
32
+ _timestamp = [[NSDate date] timeIntervalSince1970] * 1000;
33
+ }
34
+ return self;
35
+ }
36
+
37
+ - (NSDictionary *)toDictionary {
38
+ NSString *networkTypeString;
39
+ switch (self.networkType) {
40
+ case RJNetworkTypeWiFi:
41
+ networkTypeString = @"wifi";
42
+ break;
43
+ case RJNetworkTypeCellular:
44
+ networkTypeString = @"cellular";
45
+ break;
46
+ case RJNetworkTypeWired:
47
+ networkTypeString = @"wired";
48
+ break;
49
+ case RJNetworkTypeOther:
50
+ networkTypeString = @"other";
51
+ break;
52
+ default:
53
+ networkTypeString = @"none";
54
+ break;
55
+ }
56
+
57
+ NSString *cellularGenString;
58
+ switch (self.cellularGeneration) {
59
+ case RJCellularGeneration2G:
60
+ cellularGenString = @"2G";
61
+ break;
62
+ case RJCellularGeneration3G:
63
+ cellularGenString = @"3G";
64
+ break;
65
+ case RJCellularGeneration4G:
66
+ cellularGenString = @"4G";
67
+ break;
68
+ case RJCellularGeneration5G:
69
+ cellularGenString = @"5G";
70
+ break;
71
+ default:
72
+ cellularGenString = @"unknown";
73
+ break;
74
+ }
75
+
76
+ return @{
77
+ @"networkType" : networkTypeString,
78
+ @"cellularGeneration" : cellularGenString,
79
+ @"isConstrained" : @(self.isConstrained),
80
+ @"isExpensive" : @(self.isExpensive),
81
+ @"timestamp" : @(self.timestamp)
82
+ };
83
+ }
84
+
85
+ @end
86
+
87
+ #pragma mark - RJNetworkMonitor Implementation
88
+
89
+ @interface RJNetworkMonitor ()
90
+
91
+ @property(nonatomic, strong) dispatch_queue_t monitorQueue;
92
+ #if TARGET_OS_IOS
93
+ @property(nonatomic, strong)
94
+ nw_path_monitor_t pathMonitor API_AVAILABLE(ios(12.0));
95
+ @property(nonatomic, strong) CTTelephonyNetworkInfo *telephonyInfo;
96
+ #endif
97
+ @property(nonatomic, strong) RJNetworkQuality *currentQuality;
98
+ @property(nonatomic, assign) BOOL isMonitoring;
99
+
100
+ @end
101
+
102
+ @implementation RJNetworkMonitor
103
+
104
+ + (instancetype)sharedInstance {
105
+ static RJNetworkMonitor *instance = nil;
106
+ static dispatch_once_t onceToken;
107
+ dispatch_once(&onceToken, ^{
108
+ instance = [[RJNetworkMonitor alloc] init];
109
+ });
110
+ return instance;
111
+ }
112
+
113
+ - (instancetype)init {
114
+ self = [super init];
115
+ if (self) {
116
+ _monitorQueue = dispatch_queue_create("com.rejourney.network.monitor",
117
+ DISPATCH_QUEUE_SERIAL);
118
+ #if TARGET_OS_IOS
119
+ _telephonyInfo = [[CTTelephonyNetworkInfo alloc] init];
120
+ #endif
121
+ _currentQuality = [[RJNetworkQuality alloc] init];
122
+ _isMonitoring = NO;
123
+ }
124
+ return self;
125
+ }
126
+
127
+ - (void)startMonitoring {
128
+ if (self.isMonitoring)
129
+ return;
130
+
131
+ #if TARGET_OS_IOS
132
+ if (@available(iOS 12.0, *)) {
133
+ self.pathMonitor = nw_path_monitor_create();
134
+ nw_path_monitor_set_queue(self.pathMonitor, self.monitorQueue);
135
+
136
+ __weak typeof(self) weakSelf = self;
137
+ nw_path_monitor_set_update_handler(self.pathMonitor, ^(nw_path_t path) {
138
+ [weakSelf handlePathUpdate:path];
139
+ });
140
+
141
+ nw_path_monitor_start(self.pathMonitor);
142
+ self.isMonitoring = YES;
143
+ RJLogDebug(@"Network monitoring started");
144
+ } else {
145
+ RJLogWarning(@"NWPathMonitor requires iOS 12.0+");
146
+ }
147
+ #else
148
+ RJLogWarning(@"Network monitoring not available on this platform");
149
+ #endif
150
+ }
151
+
152
+ - (void)stopMonitoring {
153
+ if (!self.isMonitoring)
154
+ return;
155
+
156
+ #if TARGET_OS_IOS
157
+ if (@available(iOS 12.0, *)) {
158
+ if (self.pathMonitor) {
159
+ nw_path_monitor_cancel(self.pathMonitor);
160
+ self.pathMonitor = nil;
161
+ }
162
+ }
163
+ #endif
164
+
165
+ self.isMonitoring = NO;
166
+ RJLogDebug(@"Network monitoring stopped");
167
+ }
168
+
169
+ #if TARGET_OS_IOS
170
+ - (void)handlePathUpdate:(nw_path_t)path API_AVAILABLE(ios(12.0)) {
171
+ RJNetworkQuality *quality = [[RJNetworkQuality alloc] init];
172
+
173
+
174
+ nw_path_status_t status = nw_path_get_status(path);
175
+ if (status == nw_path_status_satisfied ||
176
+ status == nw_path_status_satisfiable) {
177
+ if (nw_path_uses_interface_type(path, nw_interface_type_wifi)) {
178
+ quality.networkType = RJNetworkTypeWiFi;
179
+ } else if (nw_path_uses_interface_type(path, nw_interface_type_cellular)) {
180
+ quality.networkType = RJNetworkTypeCellular;
181
+ quality.cellularGeneration = [self detectCellularGeneration];
182
+ } else if (nw_path_uses_interface_type(path, nw_interface_type_wired)) {
183
+ quality.networkType = RJNetworkTypeWired;
184
+ } else {
185
+ quality.networkType = RJNetworkTypeOther;
186
+ }
187
+ } else {
188
+ quality.networkType = RJNetworkTypeNone;
189
+ }
190
+
191
+
192
+ quality.isConstrained = nw_path_is_constrained(path);
193
+ quality.isExpensive = nw_path_is_expensive(path);
194
+ quality.timestamp = [[NSDate date] timeIntervalSince1970] * 1000;
195
+
196
+
197
+ self.currentQuality = quality;
198
+
199
+
200
+ if (self.delegate &&
201
+ [self.delegate respondsToSelector:@selector(networkMonitor:
202
+ didDetectNetworkChange:)]) {
203
+ dispatch_async(dispatch_get_main_queue(), ^{
204
+ [self.delegate networkMonitor:self didDetectNetworkChange:quality];
205
+ });
206
+ }
207
+
208
+ RJLogDebug(@"Network changed: %@", [quality toDictionary]);
209
+ }
210
+
211
+ - (RJCellularGeneration)detectCellularGeneration {
212
+ NSString *radioTech = nil;
213
+
214
+ if (@available(iOS 12.0, *)) {
215
+ NSDictionary *radioTechDict =
216
+ self.telephonyInfo.serviceCurrentRadioAccessTechnology;
217
+ radioTech = radioTechDict.allValues.firstObject;
218
+ } else {
219
+ #pragma clang diagnostic push
220
+ #pragma clang diagnostic ignored "-Wdeprecated-declarations"
221
+ radioTech = self.telephonyInfo.currentRadioAccessTechnology;
222
+ #pragma clang diagnostic pop
223
+ }
224
+
225
+ if (!radioTech)
226
+ return RJCellularGenerationUnknown;
227
+
228
+
229
+ if (@available(iOS 14.1, *)) {
230
+ if ([radioTech isEqualToString:CTRadioAccessTechnologyNRNSA] ||
231
+ [radioTech isEqualToString:CTRadioAccessTechnologyNR]) {
232
+ return RJCellularGeneration5G;
233
+ }
234
+ }
235
+
236
+
237
+ if ([radioTech isEqualToString:CTRadioAccessTechnologyLTE]) {
238
+ return RJCellularGeneration4G;
239
+ }
240
+
241
+
242
+ if ([radioTech isEqualToString:CTRadioAccessTechnologyWCDMA] ||
243
+ [radioTech isEqualToString:CTRadioAccessTechnologyHSDPA] ||
244
+ [radioTech isEqualToString:CTRadioAccessTechnologyHSUPA] ||
245
+ [radioTech isEqualToString:CTRadioAccessTechnologyCDMA1x] ||
246
+ [radioTech isEqualToString:CTRadioAccessTechnologyCDMAEVDORev0] ||
247
+ [radioTech isEqualToString:CTRadioAccessTechnologyCDMAEVDORevA] ||
248
+ [radioTech isEqualToString:CTRadioAccessTechnologyCDMAEVDORevB] ||
249
+ [radioTech isEqualToString:CTRadioAccessTechnologyeHRPD]) {
250
+ return RJCellularGeneration3G;
251
+ }
252
+
253
+
254
+ if ([radioTech isEqualToString:CTRadioAccessTechnologyGPRS] ||
255
+ [radioTech isEqualToString:CTRadioAccessTechnologyEdge]) {
256
+ return RJCellularGeneration2G;
257
+ }
258
+
259
+ return RJCellularGenerationUnknown;
260
+ }
261
+ #endif
262
+
263
+ - (RJNetworkQuality *)captureNetworkQuality {
264
+ return self.currentQuality;
265
+ }
266
+
267
+ @end
@@ -0,0 +1,73 @@
1
+ //
2
+ // RJRetryManager.h
3
+ // Rejourney
4
+ //
5
+ // Retry queue and circuit breaker for upload resilience.
6
+ //
7
+ // Copyright (c) 2026 Rejourney
8
+ //
9
+
10
+ #import <Foundation/Foundation.h>
11
+
12
+ NS_ASSUME_NONNULL_BEGIN
13
+
14
+ /// Completion handler for retry operations
15
+ typedef void (^RJRetryCompletionHandler)(BOOL success);
16
+
17
+ /// Block type for performing the actual upload
18
+ typedef BOOL (^RJUploadBlock)(NSArray<NSDictionary *> *events);
19
+
20
+ /**
21
+ * Manages upload retry queue with exponential backoff and circuit breaker.
22
+ */
23
+ @interface RJRetryManager : NSObject
24
+
25
+ /// Whether the circuit breaker is currently open (blocking requests)
26
+ @property(nonatomic, readonly) BOOL isCircuitOpen;
27
+
28
+ /// Number of consecutive upload failures
29
+ @property(nonatomic, readonly) NSInteger consecutiveFailureCount;
30
+
31
+ /// Whether manager is shutting down
32
+ @property(nonatomic, assign) BOOL isShuttingDown;
33
+
34
+ /// Block to perform actual upload (set by owner)
35
+ @property(nonatomic, copy, nullable) RJUploadBlock uploadBlock;
36
+
37
+ /**
38
+ * Add a failed batch to the retry queue.
39
+ *
40
+ * @param events Array of event dictionaries
41
+ */
42
+ - (void)addToRetryQueueWithEvents:(NSArray<NSDictionary *> *)events;
43
+
44
+ /**
45
+ * Record a successful upload (resets failure count, closes circuit).
46
+ */
47
+ - (void)recordUploadSuccess;
48
+
49
+ /**
50
+ * Record a failed upload (increments failure count, may open circuit).
51
+ */
52
+ - (void)recordUploadFailure;
53
+
54
+ /**
55
+ * Persist pending uploads to disk for later retry.
56
+ */
57
+ - (void)persistPendingUploads;
58
+
59
+ /**
60
+ * Load persisted failed uploads and queue them for retry.
61
+ */
62
+ - (void)loadAndRetryPersistedUploads;
63
+
64
+ /**
65
+ * Check if circuit breaker should block requests.
66
+ *
67
+ * @return YES if requests should proceed, NO if blocked by circuit breaker.
68
+ */
69
+ - (BOOL)shouldAllowRequest;
70
+
71
+ @end
72
+
73
+ NS_ASSUME_NONNULL_END