@kafitra/react-native-live-tracking 0.1.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 (132) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +396 -0
  3. package/android/build.gradle +71 -0
  4. package/android/gradle.properties +7 -0
  5. package/android/src/main/AndroidManifest.xml +40 -0
  6. package/android/src/main/java/com/livetracking/LiveTrackingModuleImpl.kt +728 -0
  7. package/android/src/main/java/com/livetracking/LiveTrackingPackage.kt +16 -0
  8. package/android/src/main/java/com/livetracking/location/LocationEngine.kt +93 -0
  9. package/android/src/main/java/com/livetracking/network/NetworkListener.kt +127 -0
  10. package/android/src/main/java/com/livetracking/optimizer/ActivityRecognitionHandler.kt +248 -0
  11. package/android/src/main/java/com/livetracking/optimizer/MotionSleepManager.kt +130 -0
  12. package/android/src/main/java/com/livetracking/permissions/PermissionHandler.kt +145 -0
  13. package/android/src/main/java/com/livetracking/queue/QueueEngine.kt +167 -0
  14. package/android/src/main/java/com/livetracking/queue/QueuedLocation.kt +16 -0
  15. package/android/src/main/java/com/livetracking/queue/TrackingDatabase.kt +239 -0
  16. package/android/src/main/java/com/livetracking/receiver/BootReceiver.kt +53 -0
  17. package/android/src/main/java/com/livetracking/service/TrackingForegroundService.kt +145 -0
  18. package/android/src/main/java/com/livetracking/sync/FirebaseSyncEngine.kt +277 -0
  19. package/android/src/main/java/com/livetracking/sync/LocationDataPoint.kt +31 -0
  20. package/android/src/main/java/com/livetracking/sync/SyncEngineController.kt +220 -0
  21. package/android/src/main/java/com/livetracking/sync/SyncTargetConfig.kt +20 -0
  22. package/android/src/main/java/com/livetracking/sync/TargetHandler.kt +601 -0
  23. package/android/src/newarch/java/com/livetracking/LiveTrackingModule.kt +64 -0
  24. package/android/src/oldarch/java/com/livetracking/LiveTrackingModule.kt +70 -0
  25. package/android/src/test/java/com/livetracking/BackoffCalculationTest.kt +216 -0
  26. package/android/src/test/java/com/livetracking/BatchAccumulatorTest.kt +391 -0
  27. package/android/src/test/java/com/livetracking/BootReceiverTest.kt +247 -0
  28. package/android/src/test/java/com/livetracking/FirebaseSyncEngineTest.kt +337 -0
  29. package/android/src/test/java/com/livetracking/LocationEngineTest.kt +202 -0
  30. package/android/src/test/java/com/livetracking/MotionSleepManagerTest.kt +420 -0
  31. package/android/src/test/java/com/livetracking/OfflineQueueTest.kt +462 -0
  32. package/android/src/test/java/com/livetracking/PermissionHandlerTest.kt +200 -0
  33. package/android/src/test/java/com/livetracking/QueueEngineTest.kt +335 -0
  34. package/android/src/test/java/com/livetracking/SyncEngineControllerTest.kt +855 -0
  35. package/ios/ActivityRecognitionHandler.swift +196 -0
  36. package/ios/BackgroundModeHelper.swift +132 -0
  37. package/ios/FirebaseSyncEngine.swift +276 -0
  38. package/ios/LiveTracking-Bridging-Header.h +2 -0
  39. package/ios/LiveTracking.m +37 -0
  40. package/ios/LiveTracking.swift +773 -0
  41. package/ios/LocationDataPoint.swift +56 -0
  42. package/ios/LocationEngine.swift +160 -0
  43. package/ios/MotionSleepManager.swift +151 -0
  44. package/ios/NetworkListener.swift +105 -0
  45. package/ios/OfflineQueueManager.swift +503 -0
  46. package/ios/PermissionHandler.swift +148 -0
  47. package/ios/QueueEngine.swift +249 -0
  48. package/ios/SyncEngineController.swift +396 -0
  49. package/ios/SyncTargetConfig.swift +36 -0
  50. package/ios/TargetHandler.swift +715 -0
  51. package/ios/Tests/ActivityRecognitionHandlerTests.swift +259 -0
  52. package/ios/Tests/FirebaseSyncEngineTests.swift +303 -0
  53. package/ios/Tests/LocationEngineTests.swift +244 -0
  54. package/ios/Tests/MotionSleepManagerTests.swift +355 -0
  55. package/ios/Tests/NetworkListenerTests.swift +188 -0
  56. package/ios/Tests/OfflineQueueFlushTests.swift +375 -0
  57. package/ios/Tests/PermissionHandlerTests.swift +238 -0
  58. package/ios/Tests/QueueEngineTests.swift +346 -0
  59. package/ios/TrackingCleanup.swift +93 -0
  60. package/ios/TrackingNotificationManager.swift +187 -0
  61. package/lib/commonjs/EventEmitter.js +113 -0
  62. package/lib/commonjs/EventEmitter.js.map +1 -0
  63. package/lib/commonjs/LiveTracking.js +134 -0
  64. package/lib/commonjs/LiveTracking.js.map +1 -0
  65. package/lib/commonjs/NativeLiveTracking.js +21 -0
  66. package/lib/commonjs/NativeLiveTracking.js.map +1 -0
  67. package/lib/commonjs/filters/distanceTimeFilter.js +63 -0
  68. package/lib/commonjs/filters/distanceTimeFilter.js.map +1 -0
  69. package/lib/commonjs/index.js +103 -0
  70. package/lib/commonjs/index.js.map +1 -0
  71. package/lib/commonjs/serialization/locationSerializer.js +51 -0
  72. package/lib/commonjs/serialization/locationSerializer.js.map +1 -0
  73. package/lib/commonjs/types.js +77 -0
  74. package/lib/commonjs/types.js.map +1 -0
  75. package/lib/commonjs/utils/distance.js +63 -0
  76. package/lib/commonjs/utils/distance.js.map +1 -0
  77. package/lib/commonjs/utils/retry.js +80 -0
  78. package/lib/commonjs/utils/retry.js.map +1 -0
  79. package/lib/commonjs/validation.js +463 -0
  80. package/lib/commonjs/validation.js.map +1 -0
  81. package/lib/module/EventEmitter.js +105 -0
  82. package/lib/module/EventEmitter.js.map +1 -0
  83. package/lib/module/LiveTracking.js +127 -0
  84. package/lib/module/LiveTracking.js.map +1 -0
  85. package/lib/module/NativeLiveTracking.js +16 -0
  86. package/lib/module/NativeLiveTracking.js.map +1 -0
  87. package/lib/module/filters/distanceTimeFilter.js +58 -0
  88. package/lib/module/filters/distanceTimeFilter.js.map +1 -0
  89. package/lib/module/index.js +32 -0
  90. package/lib/module/index.js.map +1 -0
  91. package/lib/module/serialization/locationSerializer.js +45 -0
  92. package/lib/module/serialization/locationSerializer.js.map +1 -0
  93. package/lib/module/types.js +94 -0
  94. package/lib/module/types.js.map +1 -0
  95. package/lib/module/utils/distance.js +56 -0
  96. package/lib/module/utils/distance.js.map +1 -0
  97. package/lib/module/utils/retry.js +72 -0
  98. package/lib/module/utils/retry.js.map +1 -0
  99. package/lib/module/validation.js +456 -0
  100. package/lib/module/validation.js.map +1 -0
  101. package/lib/typescript/EventEmitter.d.ts +65 -0
  102. package/lib/typescript/EventEmitter.d.ts.map +1 -0
  103. package/lib/typescript/LiveTracking.d.ts +23 -0
  104. package/lib/typescript/LiveTracking.d.ts.map +1 -0
  105. package/lib/typescript/NativeLiveTracking.d.ts +25 -0
  106. package/lib/typescript/NativeLiveTracking.d.ts.map +1 -0
  107. package/lib/typescript/filters/distanceTimeFilter.d.ts +44 -0
  108. package/lib/typescript/filters/distanceTimeFilter.d.ts.map +1 -0
  109. package/lib/typescript/index.d.ts +21 -0
  110. package/lib/typescript/index.d.ts.map +1 -0
  111. package/lib/typescript/serialization/locationSerializer.d.ts +39 -0
  112. package/lib/typescript/serialization/locationSerializer.d.ts.map +1 -0
  113. package/lib/typescript/types.d.ts +217 -0
  114. package/lib/typescript/types.d.ts.map +1 -0
  115. package/lib/typescript/utils/distance.d.ts +38 -0
  116. package/lib/typescript/utils/distance.d.ts.map +1 -0
  117. package/lib/typescript/utils/retry.d.ts +60 -0
  118. package/lib/typescript/utils/retry.d.ts.map +1 -0
  119. package/lib/typescript/validation.d.ts +26 -0
  120. package/lib/typescript/validation.d.ts.map +1 -0
  121. package/package.json +126 -0
  122. package/react-native-live-tracking.podspec +47 -0
  123. package/src/EventEmitter.ts +118 -0
  124. package/src/LiveTracking.ts +159 -0
  125. package/src/NativeLiveTracking.ts +29 -0
  126. package/src/filters/distanceTimeFilter.ts +75 -0
  127. package/src/index.ts +51 -0
  128. package/src/serialization/locationSerializer.ts +57 -0
  129. package/src/types.ts +252 -0
  130. package/src/utils/distance.ts +68 -0
  131. package/src/utils/retry.ts +75 -0
  132. package/src/validation.ts +552 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,YAAY,MAAM,gBAAgB,CAAC;AAE1C,eAAe,YAAY,CAAC;AAC5B,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAGzD,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,YAAY,EACV,UAAU,EACV,kBAAkB,EAClB,gBAAgB,EAChB,yBAAyB,EACzB,qBAAqB,EACrB,cAAc,EACd,cAAc,EACd,YAAY,EACZ,aAAa,EACb,cAAc,EACd,WAAW,EACX,sBAAsB,EACtB,YAAY,EACZ,kBAAkB,GACnB,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAG/E,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAG7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAGrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAGpE,OAAO,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAC;AAChF,YAAY,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAGhF,OAAO,EAAE,qBAAqB,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Location serialization for Firebase sync targets.
3
+ *
4
+ * Transforms LocationData into a generic payload suitable for any
5
+ * sync target, regardless of write method (set, push, update).
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ import type { LocationData } from '../types';
10
+ /**
11
+ * Serialized location payload for any sync target.
12
+ *
13
+ * Contains required fields (latitude, longitude, timestamp, accuracy)
14
+ * and optional sensor fields (speed, heading, altitude) which are
15
+ * included as `null` when unavailable from the device sensor.
16
+ * Placeholder values (0, -1) are never used for unavailable fields.
17
+ */
18
+ export interface TargetLocationPayload {
19
+ latitude: number;
20
+ longitude: number;
21
+ timestamp: number;
22
+ accuracy: number;
23
+ speed: number | null;
24
+ heading: number | null;
25
+ altitude: number | null;
26
+ }
27
+ /**
28
+ * Serialize a LocationData object for a generic Firebase sync target.
29
+ *
30
+ * Produces a payload containing all required location fields and optional
31
+ * sensor fields. When optional fields (speed, heading/bearing, altitude)
32
+ * are unavailable from the device sensor, they are included as `null`.
33
+ * Default placeholder values (0, -1) are never written for unavailable fields.
34
+ *
35
+ * @param location - The location data to serialize
36
+ * @returns Serialized payload for the sync target
37
+ */
38
+ export declare function serializeLocationForTarget(location: LocationData): TargetLocationPayload;
39
+ //# sourceMappingURL=locationSerializer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"locationSerializer.d.ts","sourceRoot":"","sources":["../../../src/serialization/locationSerializer.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAI7C;;;;;;;GAOG;AACH,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAID;;;;;;;;;;GAUG;AACH,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,YAAY,GACrB,qBAAqB,CAUvB"}
@@ -0,0 +1,217 @@
1
+ /**
2
+ * TypeScript type definitions for react-native-live-tracking.
3
+ *
4
+ * @packageDocumentation
5
+ */
6
+ /**
7
+ * Internal state machine for tracking lifecycle.
8
+ */
9
+ export declare enum TrackingState {
10
+ IDLE = "idle",
11
+ CONFIGURED = "configured",
12
+ TRACKING = "tracking",
13
+ MOTION_SLEEP = "motion_sleep",
14
+ PAUSED_GPS = "paused_gps"
15
+ }
16
+ /**
17
+ * Strategy used by the distance/time filter.
18
+ * - 'interval': accept when enough time has elapsed
19
+ * - 'distance': accept when enough distance has been covered
20
+ * - 'both': accept only when both conditions are met (default)
21
+ */
22
+ export type OptimizationMode = 'interval' | 'distance' | 'both';
23
+ /**
24
+ * Optimization parameters for location tracking.
25
+ */
26
+ export interface OptimizationConfig {
27
+ /** Minimum time interval between location updates in milliseconds. Default: 10000 */
28
+ intervalMs?: number;
29
+ /** Minimum distance change in meters to trigger an update. Default: 10 */
30
+ distanceFilterMeters?: number;
31
+ /** Whether to reduce GPS accuracy when device is still. Default: true */
32
+ stopWhenStill?: boolean;
33
+ /** Filter strategy: 'interval', 'distance', or 'both'. Default: 'both' */
34
+ mode?: OptimizationMode;
35
+ }
36
+ /**
37
+ * Android foreground service notification configuration.
38
+ */
39
+ export interface AndroidNotificationConfig {
40
+ /** Whether to show the foreground service notification. Default: true */
41
+ enabled?: boolean;
42
+ /** Notification title */
43
+ title: string;
44
+ /** Notification body text */
45
+ text: string;
46
+ /** Notification icon resource name */
47
+ icon?: string;
48
+ /** Notification channel ID */
49
+ channelId?: string;
50
+ /** Notification channel name */
51
+ channelName?: string;
52
+ }
53
+ /**
54
+ * iOS persistent notification configuration.
55
+ * Shows a local notification while tracking is active (similar to Android's foreground service notification).
56
+ */
57
+ export interface IOSNotificationConfig {
58
+ /** Whether to show the persistent local notification. Default: true */
59
+ enabled?: boolean;
60
+ /** Notification title */
61
+ title: string;
62
+ /** Notification body text */
63
+ text: string;
64
+ }
65
+ /**
66
+ * A user-defined sync target specifying a Firebase path, write method,
67
+ * and optional batching/offline queue settings.
68
+ */
69
+ export interface SyncTarget {
70
+ /** Firebase path to write to */
71
+ path: string;
72
+ /** Write method: 'set' (overwrite), 'push' (append), 'update' (merge) */
73
+ method: 'set' | 'push' | 'update';
74
+ /** Number of points to accumulate before writing. Default: 1 (immediate) */
75
+ batchSize?: number;
76
+ /** Whether to persist data offline when device has no connectivity */
77
+ offlineQueue?: boolean;
78
+ }
79
+ /**
80
+ * Firebase connection and sync target configuration.
81
+ */
82
+ export interface FirebaseConfig {
83
+ /** Firebase service type: Realtime Database or Firestore */
84
+ service: 'RTDB' | 'Firestore';
85
+ /** Array of sync targets (at least one required) */
86
+ targets: [SyncTarget, ...SyncTarget[]];
87
+ }
88
+ /**
89
+ * Main configuration object passed to `configure()`.
90
+ */
91
+ export interface TrackingConfig {
92
+ /** Optimization settings for battery and update frequency */
93
+ optimization: OptimizationConfig;
94
+ /** Android foreground service notification settings (Android only) */
95
+ androidNotification?: AndroidNotificationConfig;
96
+ /** iOS persistent notification settings (iOS only) */
97
+ iosNotification?: IOSNotificationConfig;
98
+ /** Firebase connection and path configuration */
99
+ firebase: FirebaseConfig;
100
+ }
101
+ /**
102
+ * Location data emitted by the library on each valid location update.
103
+ */
104
+ export interface LocationData {
105
+ /** Latitude in degrees (-90 to 90) */
106
+ latitude: number;
107
+ /** Longitude in degrees (-180 to 180) */
108
+ longitude: number;
109
+ /** Unix timestamp in milliseconds */
110
+ timestamp: number;
111
+ /** Horizontal accuracy in meters */
112
+ accuracy: number;
113
+ /** Speed in meters per second, or null if unavailable */
114
+ speed: number | null;
115
+ /** Altitude in meters above sea level, or null if unavailable */
116
+ altitude: number | null;
117
+ /** Bearing/heading in degrees (0-360), or null if unavailable */
118
+ bearing: number | null;
119
+ }
120
+ /**
121
+ * Error object emitted by the library when tracking issues occur.
122
+ */
123
+ export interface TrackingError {
124
+ /** Error code identifier (e.g., 'PERMISSION_DENIED', 'GPS_DISABLED') */
125
+ code: string;
126
+ /** Human-readable error message */
127
+ message: string;
128
+ /** Whether the error is recoverable (auto-retry or user action can fix) */
129
+ recoverable: boolean;
130
+ /** Additional error context */
131
+ details?: Record<string, unknown>;
132
+ }
133
+ /**
134
+ * Current tracking status snapshot.
135
+ */
136
+ export interface TrackingStatus {
137
+ /** Current state of the tracking lifecycle */
138
+ state: TrackingState;
139
+ /** Whether the device currently has network connectivity */
140
+ isOnline: boolean;
141
+ /** Number of locations waiting in the offline queue */
142
+ queuedLocations: number;
143
+ /** Last known location, or null if no location has been received */
144
+ lastLocation: LocationData | null;
145
+ /** Current battery optimization mode */
146
+ batteryOptimization: 'full_accuracy' | 'low_power' | 'disabled';
147
+ }
148
+ /**
149
+ * Single configuration validation error.
150
+ */
151
+ export interface ConfigError {
152
+ /** Dot-notation path to the invalid field (e.g., 'firebase.service') */
153
+ field: string;
154
+ /** Human-readable description of the validation error */
155
+ message: string;
156
+ /** Machine-readable error code */
157
+ code: string;
158
+ }
159
+ /**
160
+ * Result of configuration validation.
161
+ */
162
+ export interface ConfigValidationResult {
163
+ /** Whether the configuration is valid */
164
+ valid: boolean;
165
+ /** List of validation errors (empty if valid) */
166
+ errors: ConfigError[];
167
+ }
168
+ /**
169
+ * Subscription handle returned by event listener registrations.
170
+ * Call `remove()` to unsubscribe from the event.
171
+ */
172
+ export interface Subscription {
173
+ /** Unsubscribe from the event */
174
+ remove(): void;
175
+ }
176
+ /**
177
+ * Main public API interface for the react-native-live-tracking library.
178
+ */
179
+ export interface LiveTrackingModule {
180
+ /**
181
+ * Configure the tracking library with the given parameters.
182
+ * Must be called before `start()`.
183
+ */
184
+ configure(config: TrackingConfig): Promise<void>;
185
+ /**
186
+ * Start location tracking. Requires `configure()` to have been called first.
187
+ */
188
+ start(): Promise<void>;
189
+ /**
190
+ * Stop location tracking and clean up resources.
191
+ */
192
+ stop(): Promise<void>;
193
+ /**
194
+ * Register a callback for location updates.
195
+ * Returns a Subscription that can be used to unsubscribe.
196
+ */
197
+ onLocationUpdate(callback: (location: LocationData) => void): Subscription;
198
+ /**
199
+ * Register a callback for tracking errors.
200
+ * Returns a Subscription that can be used to unsubscribe.
201
+ */
202
+ onError(callback: (error: TrackingError) => void): Subscription;
203
+ /**
204
+ * Get the current tracking status.
205
+ */
206
+ getStatus(): Promise<TrackingStatus>;
207
+ /**
208
+ * Get the number of locations currently queued for sync.
209
+ */
210
+ getQueuedLocations(): Promise<number>;
211
+ /**
212
+ * Get the number of queued locations per target path.
213
+ * Returns a record mapping each configured target path to its queued location count.
214
+ */
215
+ getQueuedLocationsByTarget(): Promise<Record<string, number>>;
216
+ }
217
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Distance calculation utility using the Haversine formula.
3
+ *
4
+ * The Haversine formula determines the great-circle distance between two points
5
+ * on a sphere given their longitudes and latitudes. This is used by the
6
+ * Distance/Time Matrix filter to determine if a new location update has moved
7
+ * far enough from the last known position.
8
+ *
9
+ * @packageDocumentation
10
+ */
11
+ /**
12
+ * Earth's mean radius in meters.
13
+ * Used as the sphere radius in the Haversine formula.
14
+ */
15
+ export declare const EARTH_RADIUS_METERS = 6371000;
16
+ /**
17
+ * Calculates the distance in meters between two geographic coordinates
18
+ * using the Haversine formula.
19
+ *
20
+ * The Haversine formula accounts for the curvature of the Earth and provides
21
+ * accurate results for short and medium distances. It assumes a spherical Earth
22
+ * with a mean radius of 6,371,000 meters.
23
+ *
24
+ * @param lat1 - Latitude of the first point in degrees (-90 to 90)
25
+ * @param lng1 - Longitude of the first point in degrees (-180 to 180)
26
+ * @param lat2 - Latitude of the second point in degrees (-90 to 90)
27
+ * @param lng2 - Longitude of the second point in degrees (-180 to 180)
28
+ * @returns Distance between the two points in meters
29
+ *
30
+ * @example
31
+ * ```typescript
32
+ * // Distance between Jakarta and Bandung (approximately 120 km)
33
+ * const distance = calculateDistance(-6.2088, 106.8456, -6.9175, 107.6191);
34
+ * console.log(distance); // ~120,000 meters
35
+ * ```
36
+ */
37
+ export declare function calculateDistance(lat1: number, lng1: number, lat2: number, lng2: number): number;
38
+ //# sourceMappingURL=distance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"distance.d.ts","sourceRoot":"","sources":["../../../src/utils/distance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;GAGG;AACH,eAAO,MAAM,mBAAmB,UAAU,CAAC;AAY3C;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,GACX,MAAM,CAcR"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Exponential backoff retry utilities for Firebase write operations.
3
+ *
4
+ * Used by the Firebase Sync Engine to determine delay between retry attempts
5
+ * when writes fail due to network issues or transient errors.
6
+ *
7
+ * @module utils/retry
8
+ */
9
+ /** Default base delay in milliseconds for exponential backoff */
10
+ export declare const DEFAULT_BASE_DELAY = 1000;
11
+ /** Default maximum jitter in milliseconds (±) to avoid thundering herd */
12
+ export declare const DEFAULT_MAX_JITTER = 200;
13
+ /** Maximum retry attempts for sync targets using 'set' or 'update' write methods */
14
+ export declare const MAX_RETRIES_SET_UPDATE = 3;
15
+ /** Maximum retry attempts for sync targets using 'push' write method */
16
+ export declare const MAX_RETRIES_PUSH = 5;
17
+ /**
18
+ * Calculates the delay before the next retry attempt using exponential backoff
19
+ * with random jitter.
20
+ *
21
+ * Formula: delay = baseDelay × 2^(attempt - 1) + random(-maxJitter, +maxJitter)
22
+ *
23
+ * The result is clamped to a minimum of 0 to prevent negative delays.
24
+ *
25
+ * @param attempt - The retry attempt number (1-indexed, first retry = 1)
26
+ * @param baseDelay - The base delay in milliseconds (default: 1000ms)
27
+ * @param maxJitter - The maximum jitter offset in milliseconds (default: 200ms).
28
+ * A random value between -maxJitter and +maxJitter is added to the delay.
29
+ * @returns The calculated delay in milliseconds (never negative)
30
+ *
31
+ * @example
32
+ * ```typescript
33
+ * // First retry: ~1000ms ± 200ms
34
+ * const delay1 = calculateBackoffDelay(1);
35
+ *
36
+ * // Second retry: ~2000ms ± 200ms
37
+ * const delay2 = calculateBackoffDelay(2);
38
+ *
39
+ * // Third retry: ~4000ms ± 200ms
40
+ * const delay3 = calculateBackoffDelay(3);
41
+ * ```
42
+ */
43
+ export declare function calculateBackoffDelay(attempt: number, baseDelay?: number, maxJitter?: number): number;
44
+ /**
45
+ * Determines whether a retry should be attempted based on the current attempt
46
+ * number and the maximum allowed retries.
47
+ *
48
+ * @param attempt - The current attempt number (1-indexed)
49
+ * @param maxRetries - The maximum number of retries allowed
50
+ * @returns `true` if the attempt is within the allowed retry limit, `false` otherwise
51
+ *
52
+ * @example
53
+ * ```typescript
54
+ * shouldRetry(1, 3); // true - first retry is allowed
55
+ * shouldRetry(3, 3); // true - third retry is allowed
56
+ * shouldRetry(4, 3); // false - exceeds max retries
57
+ * ```
58
+ */
59
+ export declare function shouldRetry(attempt: number, maxRetries: number): boolean;
60
+ //# sourceMappingURL=retry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../../src/utils/retry.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,iEAAiE;AACjE,eAAO,MAAM,kBAAkB,OAAO,CAAC;AAEvC,0EAA0E;AAC1E,eAAO,MAAM,kBAAkB,MAAM,CAAC;AAEtC,oFAAoF;AACpF,eAAO,MAAM,sBAAsB,IAAI,CAAC;AAExC,wEAAwE;AACxE,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAElC;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,MAAM,EACf,SAAS,GAAE,MAA2B,EACtC,SAAS,GAAE,MAA2B,GACrC,MAAM,CAIR;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAExE"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Configuration validation and default value application for react-native-live-tracking.
3
+ *
4
+ * @packageDocumentation
5
+ */
6
+ import type { ConfigValidationResult, TrackingConfig } from './types';
7
+ /**
8
+ * Validates a raw configuration object and returns a structured result
9
+ * indicating whether the config is valid or contains errors.
10
+ *
11
+ * @param config - The raw configuration object to validate (unknown type for safety)
12
+ * @returns A ConfigValidationResult with validity status and any errors found
13
+ */
14
+ export declare function validateConfig(config: unknown): ConfigValidationResult;
15
+ /**
16
+ * Applies default values to a valid TrackingConfig object.
17
+ * Should only be called after validateConfig returns valid: true.
18
+ *
19
+ * Note: Sync target defaults (batchSize, offlineQueue) are handled per-target
20
+ * at the native layer. Targets pass through without modification here.
21
+ *
22
+ * @param config - A valid TrackingConfig object
23
+ * @returns A new TrackingConfig with all defaults applied
24
+ */
25
+ export declare function applyDefaults(config: TrackingConfig): TrackingConfig;
26
+ //# sourceMappingURL=validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/validation.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAEV,sBAAsB,EACtB,cAAc,EACf,MAAM,SAAS,CAAC;AAoBjB;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,GAAG,sBAAsB,CAmCtE;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,cAAc,GAAG,cAAc,CAgBpE"}
package/package.json ADDED
@@ -0,0 +1,126 @@
1
+ {
2
+ "name": "@kafitra/react-native-live-tracking",
3
+ "version": "0.1.0",
4
+ "description": "Real-time location tracking library for React Native with Firebase synchronization",
5
+ "main": "lib/commonjs/index",
6
+ "module": "lib/module/index",
7
+ "types": "lib/typescript/index.d.ts",
8
+ "react-native": "src/index",
9
+ "source": "src/index",
10
+ "files": [
11
+ "src",
12
+ "lib",
13
+ "android",
14
+ "ios",
15
+ "cpp",
16
+ "*.podspec",
17
+ "!ios/build",
18
+ "!android/build",
19
+ "!android/gradle",
20
+ "!android/gradlew",
21
+ "!android/gradlew.bat",
22
+ "!android/local.properties",
23
+ "!**/__tests__",
24
+ "!**/__fixtures__",
25
+ "!**/__mocks__",
26
+ "!**/.*"
27
+ ],
28
+ "scripts": {
29
+ "test": "jest",
30
+ "typecheck": "tsc --noEmit",
31
+ "lint": "eslint \"**/*.{js,ts,tsx}\"",
32
+ "clean": "del-cli lib",
33
+ "prepare": "bob build",
34
+ "release": "release-it"
35
+ },
36
+ "keywords": [
37
+ "react-native",
38
+ "ios",
39
+ "android",
40
+ "location",
41
+ "tracking",
42
+ "firebase",
43
+ "background",
44
+ "gps",
45
+ "live-tracking"
46
+ ],
47
+ "repository": {
48
+ "type": "git",
49
+ "url": "git+https://github.com/kafitramarna/react-native-live-tracking.git"
50
+ },
51
+ "author": "kafitramarna",
52
+ "license": "MIT",
53
+ "bugs": {
54
+ "url": "https://github.com/kafitramarna/react-native-live-tracking/issues"
55
+ },
56
+ "homepage": "https://github.com/kafitramarna/react-native-live-tracking#readme",
57
+ "publishConfig": {
58
+ "registry": "https://registry.npmjs.org/",
59
+ "access": "public"
60
+ },
61
+ "devDependencies": {
62
+ "@react-native/eslint-config": "^0.73.0",
63
+ "@types/jest": "^29.5.5",
64
+ "@types/react": "^18.2.0",
65
+ "del-cli": "^5.1.0",
66
+ "eslint": "^8.51.0",
67
+ "fast-check": "^3.13.0",
68
+ "jest": "^29.7.0",
69
+ "react": "18.2.0",
70
+ "react-native": "0.73.0",
71
+ "react-native-builder-bob": "^0.23.0",
72
+ "ts-jest": "^29.1.1",
73
+ "typescript": "^5.2.2"
74
+ },
75
+ "peerDependencies": {
76
+ "react": "*",
77
+ "react-native": ">=0.70.0"
78
+ },
79
+ "engines": {
80
+ "node": ">= 18.0.0"
81
+ },
82
+ "codegenConfig": {
83
+ "name": "RNLiveTrackingSpec",
84
+ "type": "modules",
85
+ "jsSrcsDir": "src",
86
+ "ios": {
87
+ "componentProvider": {}
88
+ }
89
+ },
90
+ "react-native-builder-bob": {
91
+ "source": "src",
92
+ "output": "lib",
93
+ "targets": [
94
+ "commonjs",
95
+ "module",
96
+ [
97
+ "typescript",
98
+ {
99
+ "project": "tsconfig.build.json"
100
+ }
101
+ ]
102
+ ]
103
+ },
104
+ "jest": {
105
+ "preset": "ts-jest",
106
+ "testEnvironment": "node",
107
+ "setupFiles": [
108
+ "./__tests__/setup.ts"
109
+ ],
110
+ "moduleFileExtensions": [
111
+ "ts",
112
+ "tsx",
113
+ "js",
114
+ "jsx",
115
+ "json"
116
+ ],
117
+ "testMatch": [
118
+ "**/__tests__/**/*.test.ts"
119
+ ],
120
+ "testPathIgnorePatterns": [
121
+ "/node_modules/",
122
+ "/lib/",
123
+ "/example/"
124
+ ]
125
+ }
126
+ }
@@ -0,0 +1,47 @@
1
+ require "json"
2
+
3
+ package = JSON.parse(File.read(File.join(__dir__, "package.json")))
4
+
5
+ folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32'
6
+
7
+ Pod::Spec.new do |s|
8
+ s.name = "react-native-live-tracking"
9
+ s.version = package["version"]
10
+ s.summary = package["description"]
11
+ s.homepage = package["homepage"]
12
+ s.license = package["license"]
13
+ s.authors = package["author"]
14
+
15
+ s.platforms = { :ios => min_ios_version_supported }
16
+ s.source = { :git => package["repository"]["url"], :tag => "#{s.version}" }
17
+
18
+ s.source_files = "ios/*.{h,m,mm,swift}"
19
+
20
+ # Use install_modules_dependencies helper to install the dependencies if React Native version >=0.71.0.
21
+ # See https://github.com/facebook/react-native/blob/febf6b7f33fdb4904669f99d795ebb4c80f770e3/scripts/cocoapods/new_architecture.rb#L79.
22
+ if respond_to?(:install_modules_dependencies, true)
23
+ install_modules_dependencies(s)
24
+ else
25
+ s.dependency "React-Core"
26
+
27
+ # Don't install the dependencies when we run `pod install` in the old architecture.
28
+ if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then
29
+ s.compiler_flags = folly_compiler_flags + " -DRCT_NEW_ARCH_ENABLED=1"
30
+ s.pod_target_xcconfig = {
31
+ "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\"",
32
+ "OTHER_CPLUSPLUSFLAGS" => "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1",
33
+ "CLANG_CXX_LANGUAGE_STANDARD" => "c++17"
34
+ }
35
+ s.dependency "React-Codegen"
36
+ s.dependency "RCT-Folly"
37
+ s.dependency "RCTRequired"
38
+ s.dependency "RCTTypeSafety"
39
+ s.dependency "ReactCommon/turbomodule/core"
40
+ end
41
+ end
42
+
43
+ s.swift_version = "5.0"
44
+
45
+ s.dependency "FirebaseDatabase"
46
+ s.dependency "FirebaseFirestore"
47
+ end