@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,46 @@
1
+ //
2
+ // RJCrashHandler.h
3
+ // Rejourney
4
+ //
5
+ // Handles uncaught exceptions and signals to generate crash reports.
6
+ //
7
+
8
+ #import <Foundation/Foundation.h>
9
+
10
+ NS_ASSUME_NONNULL_BEGIN
11
+
12
+ /**
13
+ * Block type for pre-crash callbacks.
14
+ * These are called synchronously before the crash report is written.
15
+ * Use sparingly - only for critical cleanup like flushing video segments.
16
+ */
17
+ typedef void (^RJPreCrashCallback)(void);
18
+
19
+ @interface RJCrashHandler : NSObject
20
+
21
+ + (instancetype)sharedInstance;
22
+
23
+ /// Starts monitoring for crashes
24
+ - (void)startMonitoring;
25
+
26
+ /// Checks if there is a pending crash report from a previous launch
27
+ - (BOOL)hasPendingCrashReport;
28
+
29
+ /// Loads the pending crash report and clears it from disk
30
+ - (nullable NSDictionary *)loadAndPurgePendingCrashReport;
31
+
32
+ /**
33
+ * Registers a callback to be invoked immediately when a crash is detected,
34
+ * before the crash report is written. This allows critical cleanup operations
35
+ * like flushing video segments.
36
+ *
37
+ * @warning Callbacks must be extremely fast and async-signal-safe for signal handlers.
38
+ * Exception handlers have more flexibility but should still be quick.
39
+ *
40
+ * @param callback The callback block to invoke on crash.
41
+ */
42
+ - (void)registerPreCrashCallback:(RJPreCrashCallback)callback;
43
+
44
+ @end
45
+
46
+ NS_ASSUME_NONNULL_END
@@ -0,0 +1,313 @@
1
+ //
2
+ // RJCrashHandler.m
3
+ // Rejourney
4
+ //
5
+ // Industry-standard crash handling with proper signal handling and
6
+ // fingerprinting.
7
+ //
8
+
9
+ #import "RJCrashHandler.h"
10
+ #import "../Core/RJLogger.h"
11
+ #import <CommonCrypto/CommonDigest.h>
12
+ #import <UIKit/UIKit.h>
13
+ #include <execinfo.h>
14
+ #include <signal.h>
15
+
16
+ static NSUncaughtExceptionHandler *originalExceptionHandler = NULL;
17
+ static NSString *const kRJCrashReportFileName = @"rj_crash_report.json";
18
+ static NSString *const kRJCurrentSessionIdKey = @"rj_current_session_id";
19
+
20
+ static struct sigaction originalSigActions[32];
21
+ static volatile sig_atomic_t handlingSignal = 0;
22
+
23
+ static RJPreCrashCallback rj_preCrashCallback = nil;
24
+
25
+ static void rj_invokePreCrashCallback(void);
26
+
27
+ @implementation RJCrashHandler
28
+
29
+ + (instancetype)sharedInstance {
30
+ static RJCrashHandler *sharedInstance = nil;
31
+ static dispatch_once_t onceToken;
32
+ dispatch_once(&onceToken, ^{
33
+ sharedInstance = [[self alloc] init];
34
+ });
35
+ return sharedInstance;
36
+ }
37
+
38
+ - (void)registerPreCrashCallback:(RJPreCrashCallback)callback {
39
+ rj_preCrashCallback = [callback copy];
40
+ RJLogDebug(@"Registered pre-crash callback for video segment recovery");
41
+ }
42
+
43
+ - (void)startMonitoring {
44
+
45
+ originalExceptionHandler = NSGetUncaughtExceptionHandler();
46
+ NSSetUncaughtExceptionHandler(&rj_uncaughtExceptionHandler);
47
+
48
+
49
+
50
+ int signals[] = {SIGABRT, SIGILL, SIGSEGV, SIGFPE, SIGBUS, SIGPIPE, SIGTRAP};
51
+ int numSignals = sizeof(signals) / sizeof(signals[0]);
52
+
53
+ for (int i = 0; i < numSignals; i++) {
54
+ struct sigaction action;
55
+ memset(&action, 0, sizeof(action));
56
+ action.sa_sigaction = rj_signalActionHandler;
57
+ action.sa_flags = SA_SIGINFO | SA_ONSTACK;
58
+ sigemptyset(&action.sa_mask);
59
+
60
+
61
+ sigaction(signals[i], &action, &originalSigActions[signals[i]]);
62
+ }
63
+
64
+ RJLogDebug(@"RJCrashHandler started monitoring (using sigaction)");
65
+ }
66
+
67
+ static void rj_invokePreCrashCallback(void) {
68
+ if (rj_preCrashCallback) {
69
+ @try {
70
+ rj_preCrashCallback();
71
+ } @catch (NSException *e) {
72
+
73
+ }
74
+ }
75
+ }
76
+
77
+ - (BOOL)hasPendingCrashReport {
78
+ NSString *path = [self crashReportPath];
79
+ return [[NSFileManager defaultManager] fileExistsAtPath:path];
80
+ }
81
+
82
+ - (NSDictionary *)loadAndPurgePendingCrashReport {
83
+ NSString *path = [self crashReportPath];
84
+ if (![[NSFileManager defaultManager] fileExistsAtPath:path]) {
85
+ return nil;
86
+ }
87
+
88
+ NSData *data = [NSData dataWithContentsOfFile:path];
89
+ if (!data)
90
+ return nil;
91
+
92
+ NSDictionary *report = [NSJSONSerialization JSONObjectWithData:data
93
+ options:0
94
+ error:nil];
95
+
96
+
97
+ [[NSFileManager defaultManager] removeItemAtPath:path error:nil];
98
+
99
+ return report;
100
+ }
101
+
102
+ #pragma mark - Private Methods
103
+
104
+ - (NSString *)crashReportPath {
105
+ NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory,
106
+ NSUserDomainMask, YES);
107
+ NSString *cacheDir = [paths objectAtIndex:0];
108
+ return [cacheDir stringByAppendingPathComponent:kRJCrashReportFileName];
109
+ }
110
+
111
+ #pragma mark - Fingerprinting
112
+
113
+ + (NSString *)generateFingerprintForException:(NSString *)exceptionName
114
+ stackTrace:(NSArray *)stackTrace {
115
+ NSMutableString *input =
116
+ [NSMutableString stringWithString:exceptionName ?: @""];
117
+
118
+
119
+ NSInteger frameCount = MIN(5, stackTrace.count);
120
+ for (NSInteger i = 0; i < frameCount; i++) {
121
+ NSString *frame = stackTrace[i];
122
+
123
+ NSString *cleaned = [frame
124
+ stringByReplacingOccurrencesOfString:@"0x[0-9a-fA-F]+"
125
+ withString:@""
126
+ options:NSRegularExpressionSearch
127
+ range:NSMakeRange(0, frame.length)];
128
+ [input appendString:cleaned];
129
+ }
130
+
131
+
132
+ const char *cStr = [input UTF8String];
133
+ unsigned char digest[CC_SHA256_DIGEST_LENGTH];
134
+ CC_SHA256(cStr, (CC_LONG)strlen(cStr), digest);
135
+
136
+ NSMutableString *fingerprint =
137
+ [NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH * 2];
138
+ for (int i = 0; i < 8; i++) {
139
+ [fingerprint appendFormat:@"%02x", digest[i]];
140
+ }
141
+
142
+ return fingerprint;
143
+ }
144
+
145
+ #pragma mark - Handlers
146
+
147
+ void rj_uncaughtExceptionHandler(NSException *exception) {
148
+ RJLogDebug(@"[CRASH] EXCEPTION DETECTED: %@ - %@", exception.name,
149
+ exception.reason);
150
+
151
+
152
+
153
+ rj_invokePreCrashCallback();
154
+
155
+ NSString *sessionId = [[NSUserDefaults standardUserDefaults]
156
+ stringForKey:kRJCurrentSessionIdKey];
157
+
158
+ NSMutableDictionary *report = [NSMutableDictionary new];
159
+ report[@"timestamp"] = @([[NSDate date] timeIntervalSince1970] * 1000);
160
+ report[@"exceptionName"] = exception.name;
161
+ report[@"reason"] = exception.reason ?: @"";
162
+
163
+
164
+
165
+ NSArray *stackSymbols = exception.callStackSymbols;
166
+ if (!stackSymbols || stackSymbols.count == 0) {
167
+
168
+ void *callstack[128];
169
+ int frames = backtrace(callstack, 128);
170
+ char **strs = backtrace_symbols(callstack, frames);
171
+ NSMutableArray *stack = [NSMutableArray arrayWithCapacity:frames];
172
+ for (int i = 0; i < frames; i++) {
173
+ [stack addObject:[NSString stringWithUTF8String:strs[i]]];
174
+ }
175
+ free(strs);
176
+ stackSymbols = stack;
177
+ RJLogDebug(@"[CRASH] Used backtrace() fallback for stack trace (%d frames)",
178
+ frames);
179
+ } else {
180
+ RJLogDebug(@"[CRASH] Using exception.callStackSymbols (%lu frames)",
181
+ (unsigned long)stackSymbols.count);
182
+ }
183
+
184
+ report[@"stackTrace"] = stackSymbols ?: @[];
185
+
186
+ if (sessionId) {
187
+ report[@"sessionId"] = sessionId;
188
+ }
189
+
190
+
191
+ report[@"fingerprint"] =
192
+ [RJCrashHandler generateFingerprintForException:exception.name
193
+ stackTrace:stackSymbols ?: @[]];
194
+
195
+ UIDevice *device = [UIDevice currentDevice];
196
+ report[@"deviceMetadata"] = @{
197
+ @"model" : device.model,
198
+ @"systemName" : device.systemName,
199
+ @"systemVersion" : device.systemVersion,
200
+ @"identifierForVendor" : device.identifierForVendor.UUIDString ?: @"unknown"
201
+ };
202
+
203
+ NSData *jsonData =
204
+ [NSJSONSerialization dataWithJSONObject:report
205
+ options:NSJSONWritingPrettyPrinted
206
+ error:nil];
207
+
208
+ NSString *path = [[RJCrashHandler sharedInstance] crashReportPath];
209
+ [jsonData writeToFile:path atomically:YES];
210
+
211
+ RJLogDebug(@"[CRASH] Crash report saved to %@", path);
212
+
213
+ if (originalExceptionHandler) {
214
+ originalExceptionHandler(exception);
215
+ }
216
+ }
217
+
218
+ void rj_signalActionHandler(int signal, siginfo_t *info, void *context) {
219
+
220
+ if (handlingSignal) {
221
+ return;
222
+ }
223
+ handlingSignal = 1;
224
+
225
+ RJLogDebug(@"[CRASH] SIGNAL DETECTED: %d at address %p", signal,
226
+ info->si_addr);
227
+
228
+
229
+
230
+
231
+
232
+
233
+ rj_invokePreCrashCallback();
234
+
235
+ NSString *sessionId = [[NSUserDefaults standardUserDefaults]
236
+ stringForKey:kRJCurrentSessionIdKey];
237
+
238
+ NSMutableDictionary *report = [NSMutableDictionary new];
239
+ report[@"timestamp"] = @([[NSDate date] timeIntervalSince1970] * 1000);
240
+
241
+
242
+ NSString *signalName;
243
+ switch (signal) {
244
+ case SIGABRT:
245
+ signalName = @"SIGABRT (Abort)";
246
+ break;
247
+ case SIGSEGV:
248
+ signalName = @"SIGSEGV (Segmentation Fault)";
249
+ break;
250
+ case SIGBUS:
251
+ signalName = @"SIGBUS (Bus Error)";
252
+ break;
253
+ case SIGFPE:
254
+ signalName = @"SIGFPE (Floating Point Exception)";
255
+ break;
256
+ case SIGILL:
257
+ signalName = @"SIGILL (Illegal Instruction)";
258
+ break;
259
+ case SIGPIPE:
260
+ signalName = @"SIGPIPE (Broken Pipe)";
261
+ break;
262
+ case SIGTRAP:
263
+ signalName = @"SIGTRAP (Trace Trap)";
264
+ break;
265
+ default:
266
+ signalName = [NSString stringWithFormat:@"Signal %d", signal];
267
+ break;
268
+ }
269
+
270
+ report[@"exceptionName"] = signalName;
271
+ report[@"reason"] = [NSString
272
+ stringWithFormat:@"%@ at address %p", signalName, info->si_addr];
273
+ if (sessionId) {
274
+ report[@"sessionId"] = sessionId;
275
+ }
276
+
277
+
278
+ void *callstack[128];
279
+ int frames = backtrace(callstack, 128);
280
+ char **strs = backtrace_symbols(callstack, frames);
281
+ NSMutableArray *stack = [NSMutableArray arrayWithCapacity:frames];
282
+ for (int i = 0; i < frames; i++) {
283
+ [stack addObject:[NSString stringWithUTF8String:strs[i]]];
284
+ }
285
+ free(strs);
286
+ report[@"stackTrace"] = stack;
287
+
288
+
289
+ report[@"fingerprint"] =
290
+ [RJCrashHandler generateFingerprintForException:signalName
291
+ stackTrace:stack];
292
+
293
+ UIDevice *device = [UIDevice currentDevice];
294
+ report[@"deviceMetadata"] = @{
295
+ @"model" : device.model,
296
+ @"systemName" : device.systemName,
297
+ @"systemVersion" : device.systemVersion
298
+ };
299
+
300
+ NSData *jsonData =
301
+ [NSJSONSerialization dataWithJSONObject:report
302
+ options:NSJSONWritingPrettyPrinted
303
+ error:nil];
304
+ NSString *path = [[RJCrashHandler sharedInstance] crashReportPath];
305
+ [jsonData writeToFile:path atomically:YES];
306
+
307
+
308
+ struct sigaction *original = &originalSigActions[signal];
309
+ sigaction(signal, original, NULL);
310
+ raise(signal);
311
+ }
312
+
313
+ @end
@@ -0,0 +1,183 @@
1
+ //
2
+ // RJMotionEvent.h
3
+ // Rejourney
4
+ //
5
+ // Motion event data structure for gesture replay reconstruction.
6
+ // Motion events capture scroll/pan/swipe dynamics for timeline events.
7
+ //
8
+ // Licensed under the Apache License, Version 2.0 (the "License");
9
+ // you may not use this file except in compliance with the License.
10
+ // You may obtain a copy of the License at
11
+ //
12
+ // http://www.apache.org/licenses/LICENSE-2.0
13
+ //
14
+ // Unless required by applicable law or agreed to in writing, software
15
+ // distributed under the License is distributed on an "AS IS" BASIS,
16
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ // See the License for the specific language governing permissions and
18
+ // limitations under the License.
19
+ //
20
+ // Copyright (c) 2026 Rejourney
21
+ //
22
+
23
+ #import <CoreGraphics/CoreGraphics.h>
24
+ #import <Foundation/Foundation.h>
25
+
26
+ NS_ASSUME_NONNULL_BEGIN
27
+
28
+ /**
29
+ * Motion curve types for animation reconstruction.
30
+ */
31
+ typedef NS_ENUM(NSInteger, RJMotionCurve) {
32
+ /// Linear motion (constant velocity)
33
+ RJMotionCurveLinear = 0,
34
+
35
+ /// Exponential decay (iOS scroll deceleration)
36
+ RJMotionCurveExponentialDecay = 1,
37
+
38
+ /// Ease out (quick start, slow end)
39
+ RJMotionCurveEaseOut = 2,
40
+
41
+ /// Bounce (overshoots then settles)
42
+ RJMotionCurveBounce = 3,
43
+
44
+ /// Spring (elastic oscillation)
45
+ RJMotionCurveSpring = 4
46
+ };
47
+
48
+ /**
49
+ * Motion event types.
50
+ */
51
+ typedef NS_ENUM(NSInteger, RJMotionType) {
52
+ /// Scroll gesture motion
53
+ RJMotionTypeScroll = 0,
54
+
55
+ /// Pan gesture motion
56
+ RJMotionTypePan = 1,
57
+
58
+ /// Swipe gesture motion
59
+ RJMotionTypeSwipe = 2,
60
+
61
+ /// Fling (momentum) motion
62
+ RJMotionTypeFling = 3
63
+ };
64
+
65
+ /**
66
+ * Represents a motion event for replay reconstruction.
67
+ *
68
+ * Motion events capture the dynamics of scroll/pan/swipe gestures
69
+ * so that the player can reconstruct smooth motion between sparse keyframes.
70
+ *
71
+ * ## Usage
72
+ * @code
73
+ * RJMotionEvent *event = [[RJMotionEvent alloc] init];
74
+ * event.type = RJMotionTypeScroll;
75
+ * event.t0 = 1234.0; // start time in ms
76
+ * event.t1 = 1560.0; // end time in ms
77
+ * event.dx = 0; // horizontal displacement
78
+ * event.dy = -820; // vertical displacement
79
+ * event.v0 = 2.1; // initial velocity
80
+ * event.curve = RJMotionCurveExponentialDecay;
81
+ *
82
+ * NSDictionary *dict = [event toDictionary];
83
+ * @endcode
84
+ */
85
+ @interface RJMotionEvent : NSObject
86
+
87
+ #pragma mark - Motion Properties
88
+
89
+ /// Type of motion (scroll, pan, swipe, fling)
90
+ @property(nonatomic, assign) RJMotionType type;
91
+
92
+ /// Start timestamp in milliseconds
93
+ @property(nonatomic, assign) NSTimeInterval t0;
94
+
95
+ /// End timestamp in milliseconds
96
+ @property(nonatomic, assign) NSTimeInterval t1;
97
+
98
+ /// Horizontal displacement in points
99
+ @property(nonatomic, assign) CGFloat dx;
100
+
101
+ /// Vertical displacement in points
102
+ @property(nonatomic, assign) CGFloat dy;
103
+
104
+ /// Initial velocity in points per second
105
+ @property(nonatomic, assign) CGFloat v0;
106
+
107
+ /// Final velocity in points per second (usually 0 for deceleration)
108
+ @property(nonatomic, assign) CGFloat v1;
109
+
110
+ /// Motion curve for interpolation
111
+ @property(nonatomic, assign) RJMotionCurve curve;
112
+
113
+ /// Target view identifier (optional)
114
+ @property(nonatomic, copy, nullable) NSString *targetId;
115
+
116
+ #pragma mark - Computed Properties
117
+
118
+ /// Duration in milliseconds
119
+ @property(nonatomic, readonly) NSTimeInterval duration;
120
+
121
+ /// Total distance traveled
122
+ @property(nonatomic, readonly) CGFloat distance;
123
+
124
+ /// Average velocity
125
+ @property(nonatomic, readonly) CGFloat averageVelocity;
126
+
127
+ /// Direction angle in radians
128
+ @property(nonatomic, readonly) CGFloat direction;
129
+
130
+ #pragma mark - Serialization
131
+
132
+ /**
133
+ * Converts the motion event to a dictionary for JSON serialization.
134
+ *
135
+ * @return Dictionary with all motion event properties.
136
+ */
137
+ - (NSDictionary *)toDictionary;
138
+
139
+ /**
140
+ * Creates a motion event from a dictionary.
141
+ *
142
+ * @param dict Dictionary with motion event properties.
143
+ * @return Motion event or nil if dictionary is invalid.
144
+ */
145
+ + (nullable instancetype)eventFromDictionary:(NSDictionary *)dict;
146
+
147
+ #pragma mark - Curve Helpers
148
+
149
+ /**
150
+ * Returns the string name for a motion curve.
151
+ */
152
+ + (NSString *)curveNameForType:(RJMotionCurve)curve;
153
+
154
+ /**
155
+ * Parses a curve name string to enum value.
156
+ */
157
+ + (RJMotionCurve)curveTypeFromName:(NSString *)name;
158
+
159
+ /**
160
+ * Returns the string name for a motion type.
161
+ */
162
+ + (NSString *)motionTypeName:(RJMotionType)type;
163
+
164
+ /**
165
+ * Parses a motion type name string to enum value.
166
+ */
167
+ + (RJMotionType)motionTypeFromName:(NSString *)name;
168
+
169
+ #pragma mark - Instance Convenience Methods
170
+
171
+ /**
172
+ * Returns the string name for this event's motion type.
173
+ */
174
+ - (NSString *)typeName;
175
+
176
+ /**
177
+ * Returns the string name for this event's curve type.
178
+ */
179
+ - (NSString *)curveName;
180
+
181
+ @end
182
+
183
+ NS_ASSUME_NONNULL_END