@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,456 @@
1
+ /**
2
+ * Configuration validation and default value application for react-native-live-tracking.
3
+ *
4
+ * @packageDocumentation
5
+ */
6
+
7
+ // ─── Default Values ──────────────────────────────────────────────────────────
8
+
9
+ const DEFAULT_INTERVAL_MS = 10000;
10
+ const DEFAULT_DISTANCE_FILTER_METERS = 10;
11
+ const DEFAULT_STOP_WHEN_STILL = true;
12
+ const DEFAULT_MODE = 'both';
13
+ const VALID_OPTIMIZATION_MODES = ['interval', 'distance', 'both'];
14
+
15
+ // ─── Validation Constants ────────────────────────────────────────────────────
16
+
17
+ const MAX_TARGETS = 20;
18
+ const MAX_PATH_LENGTH = 768;
19
+ const MAX_BATCH_SIZE = 1000;
20
+ const VALID_METHODS = ['set', 'push', 'update'];
21
+
22
+ // ─── Validation ──────────────────────────────────────────────────────────────
23
+
24
+ /**
25
+ * Validates a raw configuration object and returns a structured result
26
+ * indicating whether the config is valid or contains errors.
27
+ *
28
+ * @param config - The raw configuration object to validate (unknown type for safety)
29
+ * @returns A ConfigValidationResult with validity status and any errors found
30
+ */
31
+ export function validateConfig(config) {
32
+ const errors = [];
33
+
34
+ // Check that config is an object
35
+ if (config === null || config === undefined || typeof config !== 'object') {
36
+ errors.push({
37
+ field: 'config',
38
+ message: 'Configuration must be a non-null object',
39
+ code: 'INVALID_TYPE'
40
+ });
41
+ return {
42
+ valid: false,
43
+ errors
44
+ };
45
+ }
46
+ const cfg = config;
47
+
48
+ // Validate optimization
49
+ validateOptimization(cfg['optimization'], errors);
50
+
51
+ // Validate firebase
52
+ validateFirebase(cfg['firebase'], errors);
53
+
54
+ // Validate androidNotification (optional)
55
+ if (cfg['androidNotification'] !== undefined) {
56
+ validateAndroidNotification(cfg['androidNotification'], errors);
57
+ }
58
+
59
+ // Validate iosNotification (optional)
60
+ if (cfg['iosNotification'] !== undefined) {
61
+ validateIOSNotification(cfg['iosNotification'], errors);
62
+ }
63
+ return {
64
+ valid: errors.length === 0,
65
+ errors
66
+ };
67
+ }
68
+
69
+ /**
70
+ * Applies default values to a valid TrackingConfig object.
71
+ * Should only be called after validateConfig returns valid: true.
72
+ *
73
+ * Note: Sync target defaults (batchSize, offlineQueue) are handled per-target
74
+ * at the native layer. Targets pass through without modification here.
75
+ *
76
+ * @param config - A valid TrackingConfig object
77
+ * @returns A new TrackingConfig with all defaults applied
78
+ */
79
+ export function applyDefaults(config) {
80
+ return {
81
+ ...config,
82
+ optimization: {
83
+ intervalMs: config.optimization.intervalMs ?? DEFAULT_INTERVAL_MS,
84
+ distanceFilterMeters: config.optimization.distanceFilterMeters ?? DEFAULT_DISTANCE_FILTER_METERS,
85
+ stopWhenStill: config.optimization.stopWhenStill ?? DEFAULT_STOP_WHEN_STILL,
86
+ mode: config.optimization.mode ?? DEFAULT_MODE
87
+ },
88
+ firebase: {
89
+ service: config.firebase.service,
90
+ targets: config.firebase.targets
91
+ }
92
+ };
93
+ }
94
+
95
+ // ─── Internal Validation Helpers ─────────────────────────────────────────────
96
+
97
+ function validateOptimization(optimization, errors) {
98
+ if (optimization === undefined || optimization === null) {
99
+ errors.push({
100
+ field: 'optimization',
101
+ message: 'optimization is required and must be an object',
102
+ code: 'REQUIRED_FIELD'
103
+ });
104
+ return;
105
+ }
106
+ if (typeof optimization !== 'object') {
107
+ errors.push({
108
+ field: 'optimization',
109
+ message: 'optimization must be an object',
110
+ code: 'INVALID_TYPE'
111
+ });
112
+ return;
113
+ }
114
+ const opt = optimization;
115
+
116
+ // intervalMs (optional, but if provided must be positive number)
117
+ if (opt['intervalMs'] !== undefined) {
118
+ if (typeof opt['intervalMs'] !== 'number' || !isFinite(opt['intervalMs'])) {
119
+ errors.push({
120
+ field: 'optimization.intervalMs',
121
+ message: 'intervalMs must be a finite number',
122
+ code: 'INVALID_TYPE'
123
+ });
124
+ } else if (opt['intervalMs'] <= 0) {
125
+ errors.push({
126
+ field: 'optimization.intervalMs',
127
+ message: 'intervalMs must be greater than 0',
128
+ code: 'OUT_OF_RANGE'
129
+ });
130
+ }
131
+ }
132
+
133
+ // distanceFilterMeters (optional, but if provided must be positive number)
134
+ if (opt['distanceFilterMeters'] !== undefined) {
135
+ if (typeof opt['distanceFilterMeters'] !== 'number' || !isFinite(opt['distanceFilterMeters'])) {
136
+ errors.push({
137
+ field: 'optimization.distanceFilterMeters',
138
+ message: 'distanceFilterMeters must be a finite number',
139
+ code: 'INVALID_TYPE'
140
+ });
141
+ } else if (opt['distanceFilterMeters'] <= 0) {
142
+ errors.push({
143
+ field: 'optimization.distanceFilterMeters',
144
+ message: 'distanceFilterMeters must be greater than 0',
145
+ code: 'OUT_OF_RANGE'
146
+ });
147
+ }
148
+ }
149
+
150
+ // stopWhenStill (optional, but if provided must be boolean)
151
+ if (opt['stopWhenStill'] !== undefined) {
152
+ if (typeof opt['stopWhenStill'] !== 'boolean') {
153
+ errors.push({
154
+ field: 'optimization.stopWhenStill',
155
+ message: 'stopWhenStill must be a boolean',
156
+ code: 'INVALID_TYPE'
157
+ });
158
+ }
159
+ }
160
+
161
+ // mode (optional, but if provided must be 'interval', 'distance', or 'both')
162
+ if (opt['mode'] !== undefined) {
163
+ if (typeof opt['mode'] !== 'string' || !VALID_OPTIMIZATION_MODES.includes(opt['mode'])) {
164
+ errors.push({
165
+ field: 'optimization.mode',
166
+ message: `optimization.mode must be 'interval', 'distance', or 'both'`,
167
+ code: 'INVALID_VALUE'
168
+ });
169
+ }
170
+ }
171
+ }
172
+ function validateFirebase(firebase, errors) {
173
+ if (firebase === undefined || firebase === null) {
174
+ errors.push({
175
+ field: 'firebase',
176
+ message: 'firebase is required and must be an object',
177
+ code: 'REQUIRED_FIELD'
178
+ });
179
+ return;
180
+ }
181
+ if (typeof firebase !== 'object') {
182
+ errors.push({
183
+ field: 'firebase',
184
+ message: 'firebase must be an object',
185
+ code: 'INVALID_TYPE'
186
+ });
187
+ return;
188
+ }
189
+ const fb = firebase;
190
+
191
+ // Detect deprecated fields
192
+ validateDeprecatedFields(fb, errors);
193
+
194
+ // service (required, must be 'RTDB' or 'Firestore')
195
+ if (fb['service'] === undefined || fb['service'] === null) {
196
+ errors.push({
197
+ field: 'firebase.service',
198
+ message: "firebase.service is required and must be 'RTDB' or 'Firestore'",
199
+ code: 'REQUIRED_FIELD'
200
+ });
201
+ } else if (fb['service'] !== 'RTDB' && fb['service'] !== 'Firestore') {
202
+ errors.push({
203
+ field: 'firebase.service',
204
+ message: `firebase.service must be 'RTDB' or 'Firestore', got '${String(fb['service'])}'`,
205
+ code: 'INVALID_VALUE'
206
+ });
207
+ }
208
+
209
+ // Validate targets array
210
+ validateTargets(fb['targets'], errors);
211
+ }
212
+ function validateDeprecatedFields(fb, errors) {
213
+ if (fb['currentLocationPath'] !== undefined) {
214
+ errors.push({
215
+ field: 'firebase.currentLocationPath',
216
+ message: 'currentLocationPath is deprecated. Migrate to the targets array by adding a SyncTarget with method \'set\'',
217
+ code: 'DEPRECATED_FIELD'
218
+ });
219
+ }
220
+ if (fb['historyPath'] !== undefined) {
221
+ errors.push({
222
+ field: 'firebase.historyPath',
223
+ message: 'historyPath is deprecated. Migrate to the targets array by adding a SyncTarget with method \'push\'',
224
+ code: 'DEPRECATED_FIELD'
225
+ });
226
+ }
227
+ if (fb['historyBatchSize'] !== undefined) {
228
+ errors.push({
229
+ field: 'firebase.historyBatchSize',
230
+ message: 'historyBatchSize is deprecated. Migrate to per-target batchSize in the targets array',
231
+ code: 'DEPRECATED_FIELD'
232
+ });
233
+ }
234
+ }
235
+ function validateTargets(targets, errors) {
236
+ if (targets === undefined || targets === null || !Array.isArray(targets)) {
237
+ errors.push({
238
+ field: 'firebase.targets',
239
+ message: 'firebase.targets is required and must be an array',
240
+ code: 'REQUIRED_FIELD'
241
+ });
242
+ return;
243
+ }
244
+ if (targets.length === 0) {
245
+ errors.push({
246
+ field: 'firebase.targets',
247
+ message: 'firebase.targets must contain at least 1 sync target',
248
+ code: 'INVALID_VALUE'
249
+ });
250
+ return;
251
+ }
252
+ if (targets.length > MAX_TARGETS) {
253
+ errors.push({
254
+ field: 'firebase.targets',
255
+ message: `firebase.targets must contain at most ${MAX_TARGETS} sync targets, got ${targets.length}`,
256
+ code: 'INVALID_VALUE'
257
+ });
258
+ }
259
+
260
+ // Validate each target
261
+ const seenPaths = new Set();
262
+ for (let i = 0; i < targets.length; i++) {
263
+ const target = targets[i];
264
+ const prefix = `firebase.targets[${i}]`;
265
+ if (target === null || target === undefined || typeof target !== 'object') {
266
+ errors.push({
267
+ field: prefix,
268
+ message: `${prefix} must be an object`,
269
+ code: 'INVALID_TYPE'
270
+ });
271
+ continue;
272
+ }
273
+ const t = target;
274
+
275
+ // Validate path
276
+ validateTargetPath(t['path'], i, prefix, errors, seenPaths);
277
+
278
+ // Validate method
279
+ validateTargetMethod(t['method'], i, prefix, errors);
280
+
281
+ // Validate batchSize (optional)
282
+ if (t['batchSize'] !== undefined) {
283
+ validateTargetBatchSize(t['batchSize'], i, prefix, errors);
284
+ }
285
+
286
+ // Validate offlineQueue (optional)
287
+ if (t['offlineQueue'] !== undefined) {
288
+ validateTargetOfflineQueue(t['offlineQueue'], i, prefix, errors);
289
+ }
290
+ }
291
+ }
292
+ function validateTargetPath(path, _index, prefix, errors, seenPaths) {
293
+ if (path === undefined || path === null || typeof path !== 'string') {
294
+ errors.push({
295
+ field: `${prefix}.path`,
296
+ message: `${prefix}.path is required and must be a string`,
297
+ code: 'REQUIRED_FIELD'
298
+ });
299
+ return;
300
+ }
301
+ if (path.trim().length === 0) {
302
+ errors.push({
303
+ field: `${prefix}.path`,
304
+ message: `${prefix}.path must not be empty or whitespace-only`,
305
+ code: 'INVALID_VALUE'
306
+ });
307
+ return;
308
+ }
309
+ if (path.length > MAX_PATH_LENGTH) {
310
+ errors.push({
311
+ field: `${prefix}.path`,
312
+ message: `${prefix}.path must not exceed ${MAX_PATH_LENGTH} characters, got ${path.length}`,
313
+ code: 'INVALID_VALUE'
314
+ });
315
+ return;
316
+ }
317
+
318
+ // Check for duplicate paths (case-sensitive)
319
+ if (seenPaths.has(path)) {
320
+ errors.push({
321
+ field: `${prefix}.path`,
322
+ message: `${prefix}.path '${path}' is a duplicate; each target must have a unique path`,
323
+ code: 'DUPLICATE_VALUE'
324
+ });
325
+ } else {
326
+ seenPaths.add(path);
327
+ }
328
+ }
329
+ function validateTargetMethod(method, _index, prefix, errors) {
330
+ if (method === undefined || method === null) {
331
+ errors.push({
332
+ field: `${prefix}.method`,
333
+ message: `${prefix}.method is required and must be 'set', 'push', or 'update'`,
334
+ code: 'REQUIRED_FIELD'
335
+ });
336
+ return;
337
+ }
338
+ if (typeof method !== 'string' || !VALID_METHODS.includes(method)) {
339
+ errors.push({
340
+ field: `${prefix}.method`,
341
+ message: `${prefix}.method must be 'set', 'push', or 'update', got '${String(method)}'`,
342
+ code: 'INVALID_VALUE'
343
+ });
344
+ }
345
+ }
346
+ function validateTargetBatchSize(batchSize, _index, prefix, errors) {
347
+ if (typeof batchSize !== 'number' || !isFinite(batchSize) || !Number.isInteger(batchSize)) {
348
+ errors.push({
349
+ field: `${prefix}.batchSize`,
350
+ message: `${prefix}.batchSize must be a positive integer between 1 and ${MAX_BATCH_SIZE}`,
351
+ code: 'INVALID_VALUE'
352
+ });
353
+ return;
354
+ }
355
+ if (batchSize < 1 || batchSize > MAX_BATCH_SIZE) {
356
+ errors.push({
357
+ field: `${prefix}.batchSize`,
358
+ message: `${prefix}.batchSize must be between 1 and ${MAX_BATCH_SIZE}, got ${batchSize}`,
359
+ code: 'OUT_OF_RANGE'
360
+ });
361
+ }
362
+ }
363
+ function validateTargetOfflineQueue(offlineQueue, _index, prefix, errors) {
364
+ if (typeof offlineQueue !== 'boolean') {
365
+ errors.push({
366
+ field: `${prefix}.offlineQueue`,
367
+ message: `${prefix}.offlineQueue must be a boolean`,
368
+ code: 'INVALID_TYPE'
369
+ });
370
+ }
371
+ }
372
+ function validateAndroidNotification(notification, errors) {
373
+ if (typeof notification !== 'object' || notification === null) {
374
+ errors.push({
375
+ field: 'androidNotification',
376
+ message: 'androidNotification must be an object',
377
+ code: 'INVALID_TYPE'
378
+ });
379
+ return;
380
+ }
381
+ const notif = notification;
382
+
383
+ // enabled (optional, but if provided must be boolean)
384
+ if (notif['enabled'] !== undefined && typeof notif['enabled'] !== 'boolean') {
385
+ errors.push({
386
+ field: 'androidNotification.enabled',
387
+ message: 'androidNotification.enabled must be a boolean',
388
+ code: 'INVALID_TYPE'
389
+ });
390
+ }
391
+ const isEnabled = notif['enabled'] !== false;
392
+
393
+ // title and text are only required when notification is enabled
394
+ if (isEnabled) {
395
+ // title (required, non-empty string)
396
+ if (typeof notif['title'] !== 'string' || notif['title'].trim().length === 0) {
397
+ errors.push({
398
+ field: 'androidNotification.title',
399
+ message: 'androidNotification.title must be a non-empty string',
400
+ code: 'REQUIRED_FIELD'
401
+ });
402
+ }
403
+
404
+ // text (required, non-empty string)
405
+ if (typeof notif['text'] !== 'string' || notif['text'].trim().length === 0) {
406
+ errors.push({
407
+ field: 'androidNotification.text',
408
+ message: 'androidNotification.text must be a non-empty string',
409
+ code: 'REQUIRED_FIELD'
410
+ });
411
+ }
412
+ }
413
+ }
414
+ function validateIOSNotification(notification, errors) {
415
+ if (typeof notification !== 'object' || notification === null) {
416
+ errors.push({
417
+ field: 'iosNotification',
418
+ message: 'iosNotification must be an object',
419
+ code: 'INVALID_TYPE'
420
+ });
421
+ return;
422
+ }
423
+ const notif = notification;
424
+
425
+ // enabled (optional, but if provided must be boolean)
426
+ if (notif['enabled'] !== undefined && typeof notif['enabled'] !== 'boolean') {
427
+ errors.push({
428
+ field: 'iosNotification.enabled',
429
+ message: 'iosNotification.enabled must be a boolean',
430
+ code: 'INVALID_TYPE'
431
+ });
432
+ }
433
+ const isEnabled = notif['enabled'] !== false;
434
+
435
+ // title and text are only required when notification is enabled
436
+ if (isEnabled) {
437
+ // title (required, non-empty string)
438
+ if (typeof notif['title'] !== 'string' || notif['title'].trim().length === 0) {
439
+ errors.push({
440
+ field: 'iosNotification.title',
441
+ message: 'iosNotification.title must be a non-empty string',
442
+ code: 'REQUIRED_FIELD'
443
+ });
444
+ }
445
+
446
+ // text (required, non-empty string)
447
+ if (typeof notif['text'] !== 'string' || notif['text'].trim().length === 0) {
448
+ errors.push({
449
+ field: 'iosNotification.text',
450
+ message: 'iosNotification.text must be a non-empty string',
451
+ code: 'REQUIRED_FIELD'
452
+ });
453
+ }
454
+ }
455
+ }
456
+ //# sourceMappingURL=validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["DEFAULT_INTERVAL_MS","DEFAULT_DISTANCE_FILTER_METERS","DEFAULT_STOP_WHEN_STILL","DEFAULT_MODE","VALID_OPTIMIZATION_MODES","MAX_TARGETS","MAX_PATH_LENGTH","MAX_BATCH_SIZE","VALID_METHODS","validateConfig","config","errors","undefined","push","field","message","code","valid","cfg","validateOptimization","validateFirebase","validateAndroidNotification","validateIOSNotification","length","applyDefaults","optimization","intervalMs","distanceFilterMeters","stopWhenStill","mode","firebase","service","targets","opt","isFinite","includes","fb","validateDeprecatedFields","String","validateTargets","Array","isArray","seenPaths","Set","i","target","prefix","t","validateTargetPath","validateTargetMethod","validateTargetBatchSize","validateTargetOfflineQueue","path","_index","trim","has","add","method","batchSize","Number","isInteger","offlineQueue","notification","notif","isEnabled"],"sourceRoot":"../../src","sources":["validation.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Event listener system for react-native-live-tracking.
3
+ *
4
+ * Wraps NativeEventEmitter to provide typed event subscriptions
5
+ * for location updates and tracking errors.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ import type { LocationData, TrackingError, Subscription } from './types';
10
+ /**
11
+ * Directly use the global device event emitter.
12
+ *
13
+ * NativeEventEmitter's constructor accesses Platform.OS, which requires the
14
+ * PlatformConstants native module. In a broken or partially-initialised binary
15
+ * that module can be missing and crash the app before we can even report that
16
+ * LiveTracking is unavailable. DeviceEventEmitter avoids that dependency
17
+ * entirely while still delivering native events emitted by the LiveTracking
18
+ * RCTEventEmitter.
19
+ */
20
+ /**
21
+ * Register a callback for location updates.
22
+ *
23
+ * The callback is invoked each time a valid location update is emitted
24
+ * from the native layer after passing the Distance/Time Matrix filter.
25
+ *
26
+ * @param callback - Function called with LocationData on each update
27
+ * @returns Subscription with `remove()` method to unsubscribe
28
+ *
29
+ * @example
30
+ * ```ts
31
+ * const subscription = onLocationUpdate((location) => {
32
+ * console.log(location.latitude, location.longitude);
33
+ * });
34
+ * // Later: unsubscribe
35
+ * subscription.remove();
36
+ * ```
37
+ */
38
+ export declare function onLocationUpdate(callback: (location: LocationData) => void): Subscription;
39
+ /**
40
+ * Register a callback for tracking errors.
41
+ *
42
+ * The callback is invoked when an error occurs during tracking
43
+ * (e.g., permission denied, GPS disabled, Firebase write failure).
44
+ *
45
+ * @param callback - Function called with TrackingError on each error event
46
+ * @returns Subscription with `remove()` method to unsubscribe
47
+ *
48
+ * @example
49
+ * ```ts
50
+ * const subscription = onError((error) => {
51
+ * console.error(`[${error.code}] ${error.message}`);
52
+ * });
53
+ * // Later: unsubscribe
54
+ * subscription.remove();
55
+ * ```
56
+ */
57
+ export declare function onError(callback: (error: TrackingError) => void): Subscription;
58
+ /**
59
+ * Remove all event listeners registered through this module.
60
+ *
61
+ * Useful for cleanup when the tracking module is being torn down
62
+ * or when all subscriptions need to be cleared at once.
63
+ */
64
+ export declare function removeAllListeners(): void;
65
+ //# sourceMappingURL=EventEmitter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EventEmitter.d.ts","sourceRoot":"","sources":["../../src/EventEmitter.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEzE;;;;;;;;;GASG;AAEH;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,CAAC,QAAQ,EAAE,YAAY,KAAK,IAAI,GACzC,YAAY,CAsBd;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,OAAO,CACrB,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,GACvC,YAAY,CAmBd;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAGzC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * JavaScript LiveTracking module that wraps NativeModule calls.
3
+ *
4
+ * Provides the public API for configuring, starting, and stopping
5
+ * location tracking, with validation and state management.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ import type { LiveTrackingModule } from './types';
10
+ /**
11
+ * Resets the configured state. Only for use in tests.
12
+ * @internal
13
+ */
14
+ export declare function _resetConfiguredStateForTesting(): void;
15
+ /**
16
+ * LiveTracking module implementation.
17
+ *
18
+ * Wraps native module calls with validation, serialization,
19
+ * and state management on the JavaScript side.
20
+ */
21
+ declare const LiveTracking: LiveTrackingModule;
22
+ export default LiveTracking;
23
+ //# sourceMappingURL=LiveTracking.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LiveTracking.d.ts","sourceRoot":"","sources":["../../src/LiveTracking.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,OAAO,KAAK,EAMV,kBAAkB,EACnB,MAAM,SAAS,CAAC;AAwBjB;;;GAGG;AACH,wBAAgB,+BAA+B,IAAI,IAAI,CAEtD;AAED;;;;;GAKG;AACH,QAAA,MAAM,YAAY,EAAE,kBAiGnB,CAAC;AAEF,eAAe,YAAY,CAAC"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Codegen spec for react-native-live-tracking.
3
+ *
4
+ * Uses TurboModuleRegistry.get (not getEnforcing) so that a missing or
5
+ * not-yet-registered module returns null instead of throwing synchronously.
6
+ * A top-level throw would corrupt the module graph and leave upstream
7
+ * importers (TrackingProvider, AppNavigator) with undefined module records.
8
+ *
9
+ * File must be named Native*.ts and live in the codegenConfig.jsSrcsDir
10
+ * for RN's codegen to pick it up.
11
+ */
12
+ import type { TurboModule } from 'react-native';
13
+ export interface Spec extends TurboModule {
14
+ configure(config: string): Promise<void>;
15
+ start(): Promise<void>;
16
+ stop(): Promise<void>;
17
+ getStatus(): Promise<string>;
18
+ getQueuedLocations(): Promise<number>;
19
+ getQueuedLocationsByTarget(): Promise<string>;
20
+ addListener(eventName: string): void;
21
+ removeListeners(count: number): void;
22
+ }
23
+ declare const _default: Spec | null;
24
+ export default _default;
25
+ //# sourceMappingURL=NativeLiveTracking.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NativeLiveTracking.d.ts","sourceRoot":"","sources":["../../src/NativeLiveTracking.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD,MAAM,WAAW,IAAK,SAAQ,WAAW;IACvC,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7B,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IACtC,0BAA0B,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9C,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtC;wBAIgC,IAAI,GAAG,IAAI;AAD5C,wBAC6C"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Distance/Time Matrix filter for location updates.
3
+ *
4
+ * This filter implements the battery optimization strategy that accepts a new
5
+ * location update based on the selected mode:
6
+ * - 'both' (default): BOTH time and distance conditions must be met
7
+ * - 'interval': only the time condition must be met
8
+ * - 'distance': only the distance condition must be met
9
+ *
10
+ * @packageDocumentation
11
+ */
12
+ import type { LocationData, OptimizationConfig } from '../types';
13
+ /**
14
+ * Configuration subset required by the distance/time filter.
15
+ */
16
+ export type DistanceTimeFilterConfig = Required<Pick<OptimizationConfig, 'intervalMs' | 'distanceFilterMeters'>> & {
17
+ /** Filter strategy. Defaults to 'both' if not provided. */
18
+ mode?: 'interval' | 'distance' | 'both';
19
+ };
20
+ /**
21
+ * Determines whether a new location should be accepted based on the
22
+ * Distance/Time Matrix filter criteria.
23
+ *
24
+ * The filtering strategy depends on `config.mode`:
25
+ * - 'both': accepted only if both time and distance conditions are met
26
+ * - 'interval': accepted only if enough time has elapsed
27
+ * - 'distance': accepted only if enough distance has been covered
28
+ *
29
+ * @param lastLocation - The most recently accepted location
30
+ * @param newLocation - The candidate location to evaluate
31
+ * @param config - Filter configuration with intervalMs, distanceFilterMeters, and mode
32
+ * @returns `true` if the new location should be accepted, `false` otherwise
33
+ *
34
+ * @example
35
+ * ```typescript
36
+ * const accepted = shouldAcceptLocation(
37
+ * { latitude: -6.2088, longitude: 106.8456, timestamp: 1700000000000, accuracy: 5, speed: null, altitude: null, bearing: null },
38
+ * { latitude: -6.2090, longitude: 106.8460, timestamp: 1700000015000, accuracy: 5, speed: 1.2, altitude: null, bearing: null },
39
+ * { intervalMs: 10000, distanceFilterMeters: 10, mode: 'both' }
40
+ * );
41
+ * ```
42
+ */
43
+ export declare function shouldAcceptLocation(lastLocation: LocationData, newLocation: LocationData, config: DistanceTimeFilterConfig): boolean;
44
+ //# sourceMappingURL=distanceTimeFilter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"distanceTimeFilter.d.ts","sourceRoot":"","sources":["../../../src/filters/distanceTimeFilter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAEjE;;GAEG;AACH,MAAM,MAAM,wBAAwB,GAAG,QAAQ,CAC7C,IAAI,CAAC,kBAAkB,EAAE,YAAY,GAAG,sBAAsB,CAAC,CAChE,GAAG;IACF,2DAA2D;IAC3D,IAAI,CAAC,EAAE,UAAU,GAAG,UAAU,GAAG,MAAM,CAAC;CACzC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,YAAY,EAC1B,WAAW,EAAE,YAAY,EACzB,MAAM,EAAE,wBAAwB,GAC/B,OAAO,CAsBT"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * react-native-live-tracking
3
+ *
4
+ * Real-time location tracking library for React Native with Firebase synchronization.
5
+ * Supports both TurboModules (new architecture) and Bridge (old architecture).
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ import LiveTracking from './LiveTracking';
10
+ export default LiveTracking;
11
+ export { default as LiveTracking } from './LiveTracking';
12
+ export { TrackingState } from './types';
13
+ export type { SyncTarget, OptimizationConfig, OptimizationMode, AndroidNotificationConfig, IOSNotificationConfig, FirebaseConfig, TrackingConfig, LocationData, TrackingError, TrackingStatus, ConfigError, ConfigValidationResult, Subscription, LiveTrackingModule, } from './types';
14
+ export { onLocationUpdate, onError, removeAllListeners } from './EventEmitter';
15
+ export { validateConfig, applyDefaults } from './validation';
16
+ export { calculateDistance } from './utils/distance';
17
+ export { shouldAcceptLocation } from './filters/distanceTimeFilter';
18
+ export { serializeLocationForTarget } from './serialization/locationSerializer';
19
+ export type { TargetLocationPayload } from './serialization/locationSerializer';
20
+ export { calculateBackoffDelay, shouldRetry } from './utils/retry';
21
+ //# sourceMappingURL=index.d.ts.map