expo-background-tracking 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.
package/src/types.ts ADDED
@@ -0,0 +1,410 @@
1
+ /**
2
+ * expo-background-tracking — Type definitions.
3
+ * API surface modeled after transistorsoft/react-native-background-geolocation.
4
+ */
5
+
6
+ // ---------------------------------------------------------------------------
7
+ // Enums / constants
8
+ // ---------------------------------------------------------------------------
9
+
10
+ export enum DesiredAccuracy {
11
+ NAVIGATION = -2,
12
+ HIGH = -1,
13
+ MEDIUM = 10,
14
+ LOW = 100,
15
+ VERY_LOW = 1000,
16
+ LOWEST = 3000,
17
+ }
18
+
19
+ export enum LogLevel {
20
+ OFF = 0,
21
+ ERROR = 1,
22
+ WARNING = 2,
23
+ INFO = 3,
24
+ DEBUG = 4,
25
+ VERBOSE = 5,
26
+ }
27
+
28
+ export enum ActivityType {
29
+ OTHER = 1,
30
+ AUTOMOTIVE_NAVIGATION = 2,
31
+ FITNESS = 3,
32
+ OTHER_NAVIGATION = 4,
33
+ AIRBORNE = 5,
34
+ }
35
+
36
+ export enum PersistMode {
37
+ ALL = 2,
38
+ LOCATION = 1,
39
+ GEOFENCE = -1,
40
+ NONE = 0,
41
+ }
42
+
43
+ export enum AuthorizationStatus {
44
+ NOT_DETERMINED = 0,
45
+ RESTRICTED = 1,
46
+ DENIED = 2,
47
+ ALWAYS = 3,
48
+ WHEN_IN_USE = 4,
49
+ }
50
+
51
+ export enum AccuracyAuthorization {
52
+ FULL = 0,
53
+ REDUCED = 1,
54
+ }
55
+
56
+ export type MotionActivityType =
57
+ | 'still'
58
+ | 'walking'
59
+ | 'on_foot'
60
+ | 'running'
61
+ | 'on_bicycle'
62
+ | 'in_vehicle'
63
+ | 'unknown';
64
+
65
+ export type GeofenceAction = 'ENTER' | 'EXIT' | 'DWELL';
66
+
67
+ export type TrackingMode = 0 | 1; // 0 = geofences-only, 1 = location + geofences
68
+
69
+ export type LocationError =
70
+ | 0 // success
71
+ | 1 // permission denied
72
+ | 2 // network error
73
+ | 3 // location unavailable
74
+ | 408 // timeout
75
+ | 499; // cancelled
76
+
77
+ // ---------------------------------------------------------------------------
78
+ // Location
79
+ // ---------------------------------------------------------------------------
80
+
81
+ export interface Coords {
82
+ latitude: number;
83
+ longitude: number;
84
+ accuracy: number;
85
+ speed: number;
86
+ speed_accuracy?: number;
87
+ heading: number;
88
+ heading_accuracy?: number;
89
+ altitude: number;
90
+ altitude_accuracy?: number;
91
+ ellipsoidal_altitude?: number;
92
+ }
93
+
94
+ export interface Battery {
95
+ level: number; // 0..1, -1 unknown
96
+ is_charging: boolean;
97
+ }
98
+
99
+ export interface ActivityChangeEvent {
100
+ activity: MotionActivityType;
101
+ confidence: number; // 0..100
102
+ }
103
+
104
+ export interface Location {
105
+ uuid: string;
106
+ timestamp: string; // ISO-8601
107
+ age?: number;
108
+ odometer: number;
109
+ is_moving: boolean;
110
+ coords: Coords;
111
+ activity: ActivityChangeEvent;
112
+ battery: Battery;
113
+ extras?: Record<string, unknown>;
114
+ event?: 'motionchange' | 'geofence' | 'heartbeat' | 'providerchange';
115
+ mock?: boolean;
116
+ sample?: boolean;
117
+ }
118
+
119
+ export interface MotionChangeEvent {
120
+ isMoving: boolean;
121
+ location: Location;
122
+ }
123
+
124
+ export interface HeartbeatEvent {
125
+ location: Location;
126
+ }
127
+
128
+ // ---------------------------------------------------------------------------
129
+ // Geofence
130
+ // ---------------------------------------------------------------------------
131
+
132
+ export interface Geofence {
133
+ identifier: string;
134
+ radius?: number; // metres (circular)
135
+ latitude?: number;
136
+ longitude?: number;
137
+ /** Polygon geofence: list of [latitude, longitude] vertices. */
138
+ vertices?: Array<[number, number]>;
139
+ notifyOnEntry?: boolean;
140
+ notifyOnExit?: boolean;
141
+ notifyOnDwell?: boolean;
142
+ loiteringDelay?: number; // ms before DWELL fires
143
+ extras?: Record<string, unknown>;
144
+ }
145
+
146
+ export interface GeofenceEvent {
147
+ identifier: string;
148
+ action: GeofenceAction;
149
+ location: Location;
150
+ extras?: Record<string, unknown>;
151
+ }
152
+
153
+ export interface GeofencesChangeEvent {
154
+ on: Geofence[];
155
+ off: string[];
156
+ }
157
+
158
+ // ---------------------------------------------------------------------------
159
+ // HTTP / Authorization
160
+ // ---------------------------------------------------------------------------
161
+
162
+ export interface HttpEvent {
163
+ success: boolean;
164
+ status: number;
165
+ responseText: string;
166
+ }
167
+
168
+ export interface Authorization {
169
+ strategy?: 'JWT' | 'BASIC';
170
+ accessToken?: string;
171
+ refreshToken?: string;
172
+ refreshUrl?: string;
173
+ refreshPayload?: Record<string, string>;
174
+ refreshHeaders?: Record<string, string>;
175
+ expires?: number;
176
+ }
177
+
178
+ export interface AuthorizationEvent {
179
+ success: boolean;
180
+ status?: number;
181
+ response?: Record<string, unknown>;
182
+ error?: string;
183
+ }
184
+
185
+ // ---------------------------------------------------------------------------
186
+ // Provider / connectivity / power
187
+ // ---------------------------------------------------------------------------
188
+
189
+ export interface ProviderChangeEvent {
190
+ enabled: boolean;
191
+ status: AuthorizationStatus;
192
+ network: boolean;
193
+ gps: boolean;
194
+ accuracyAuthorization: AccuracyAuthorization;
195
+ }
196
+
197
+ export interface ConnectivityChangeEvent {
198
+ connected: boolean;
199
+ }
200
+
201
+ // ---------------------------------------------------------------------------
202
+ // Schedule
203
+ // ---------------------------------------------------------------------------
204
+
205
+ /** e.g. "1-5 09:00-17:00" (ISO day numbers 1=Monday … 7=Sunday) */
206
+ export type ScheduleItem = string;
207
+
208
+ export interface ScheduleEvent {
209
+ enabled: boolean;
210
+ state: State;
211
+ }
212
+
213
+ // ---------------------------------------------------------------------------
214
+ // Notification (Android foreground service — dev build only)
215
+ // ---------------------------------------------------------------------------
216
+
217
+ export interface Notification {
218
+ title?: string;
219
+ text?: string;
220
+ color?: string;
221
+ channelName?: string;
222
+ smallIcon?: string;
223
+ largeIcon?: string;
224
+ priority?: number;
225
+ sticky?: boolean;
226
+ actions?: string[];
227
+ }
228
+
229
+ // ---------------------------------------------------------------------------
230
+ // Config
231
+ // ---------------------------------------------------------------------------
232
+
233
+ export interface Config {
234
+ // --- Geolocation
235
+ desiredAccuracy?: DesiredAccuracy;
236
+ distanceFilter?: number;
237
+ stationaryRadius?: number;
238
+ locationTimeout?: number;
239
+ useSignificantChangesOnly?: boolean;
240
+ pausesLocationUpdatesAutomatically?: boolean;
241
+ showsBackgroundLocationIndicator?: boolean;
242
+ activityType?: ActivityType;
243
+ deferTime?: number;
244
+ disableElasticity?: boolean;
245
+ elasticityMultiplier?: number;
246
+ stopAfterElapsedMinutes?: number;
247
+ geofenceProximityRadius?: number;
248
+ geofenceInitialTriggerEntry?: boolean;
249
+ geofenceModeHighAccuracy?: boolean;
250
+
251
+ // --- Activity recognition / motion
252
+ isMoving?: boolean;
253
+ stopTimeout?: number; // minutes
254
+ motionTriggerDelay?: number; // ms
255
+ disableMotionActivityUpdates?: boolean;
256
+ disableStopDetection?: boolean;
257
+ stopOnStationary?: boolean;
258
+
259
+ // --- HTTP & persistence
260
+ url?: string;
261
+ method?: 'POST' | 'PUT' | 'OPTIONS';
262
+ httpRootProperty?: string;
263
+ params?: Record<string, unknown>;
264
+ headers?: Record<string, string>;
265
+ extras?: Record<string, unknown>;
266
+ autoSync?: boolean;
267
+ autoSyncThreshold?: number;
268
+ batchSync?: boolean;
269
+ maxBatchSize?: number;
270
+ locationTemplate?: string;
271
+ geofenceTemplate?: string;
272
+ maxDaysToPersist?: number;
273
+ maxRecordsToPersist?: number;
274
+ persistMode?: PersistMode;
275
+ httpTimeout?: number;
276
+ authorization?: Authorization;
277
+ disableAutoSyncOnCellular?: boolean;
278
+
279
+ // --- Application
280
+ stopOnTerminate?: boolean;
281
+ startOnBoot?: boolean;
282
+ heartbeatInterval?: number; // seconds
283
+ schedule?: ScheduleItem[];
284
+ preventSuspend?: boolean;
285
+ foregroundService?: boolean;
286
+ notification?: Notification;
287
+
288
+ // --- Logging & debug
289
+ debug?: boolean;
290
+ logLevel?: LogLevel;
291
+ logMaxDays?: number;
292
+
293
+ // --- Permissions
294
+ locationAuthorizationRequest?: 'Always' | 'WhenInUse' | 'Any';
295
+ backgroundPermissionRationale?: {
296
+ title?: string;
297
+ message?: string;
298
+ positiveAction?: string;
299
+ negativeAction?: string;
300
+ };
301
+
302
+ // --- Misc
303
+ reset?: boolean;
304
+ }
305
+
306
+ // ---------------------------------------------------------------------------
307
+ // State
308
+ // ---------------------------------------------------------------------------
309
+
310
+ export interface State extends Config {
311
+ enabled: boolean;
312
+ isMoving?: boolean;
313
+ schedulerEnabled: boolean;
314
+ trackingMode: TrackingMode;
315
+ odometer: number;
316
+ didLaunchInBackground?: boolean;
317
+ isFirstBoot?: boolean;
318
+ }
319
+
320
+ // ---------------------------------------------------------------------------
321
+ // getCurrentPosition options
322
+ // ---------------------------------------------------------------------------
323
+
324
+ export interface CurrentPositionRequest {
325
+ timeout?: number; // seconds
326
+ maximumAge?: number; // ms
327
+ persist?: boolean;
328
+ samples?: number;
329
+ desiredAccuracy?: number; // metres
330
+ extras?: Record<string, unknown>;
331
+ }
332
+
333
+ export interface WatchPositionRequest {
334
+ interval?: number; // ms
335
+ desiredAccuracy?: DesiredAccuracy;
336
+ persist?: boolean;
337
+ extras?: Record<string, unknown>;
338
+ }
339
+
340
+ // ---------------------------------------------------------------------------
341
+ // Sensors / device / SQL
342
+ // ---------------------------------------------------------------------------
343
+
344
+ export interface Sensors {
345
+ platform: 'ios' | 'android' | string;
346
+ accelerometer: boolean;
347
+ gyroscope: boolean;
348
+ magnetometer: boolean;
349
+ motion_hardware: boolean;
350
+ }
351
+
352
+ export interface DeviceInfo {
353
+ model: string;
354
+ manufacturer: string;
355
+ version: string;
356
+ platform: string;
357
+ framework: string;
358
+ }
359
+
360
+ export interface SQLQuery {
361
+ start?: number; // timestamp ms
362
+ end?: number;
363
+ limit?: number;
364
+ order?: -1 | 1;
365
+ }
366
+
367
+ // ---------------------------------------------------------------------------
368
+ // Headless / background events
369
+ // ---------------------------------------------------------------------------
370
+
371
+ export interface HeadlessEvent {
372
+ name:
373
+ | 'location'
374
+ | 'motionchange'
375
+ | 'geofence'
376
+ | 'heartbeat'
377
+ | 'http'
378
+ | 'providerchange'
379
+ | 'connectivitychange'
380
+ | 'powersavechange'
381
+ | 'schedule'
382
+ | 'enabledchange'
383
+ | 'activitychange'
384
+ | 'authorization'
385
+ | 'geofenceschange'
386
+ | 'notificationaction';
387
+ params: unknown;
388
+ }
389
+
390
+ export type HeadlessTask = (event: HeadlessEvent) => Promise<void>;
391
+
392
+ // ---------------------------------------------------------------------------
393
+ // Subscription
394
+ // ---------------------------------------------------------------------------
395
+
396
+ export interface Subscription {
397
+ remove: () => void;
398
+ }
399
+
400
+ export type EventName = HeadlessEvent['name'];
401
+
402
+ // ---------------------------------------------------------------------------
403
+ // Persisted log entry
404
+ // ---------------------------------------------------------------------------
405
+
406
+ export interface LogEntry {
407
+ timestamp: string;
408
+ level: string;
409
+ message: string;
410
+ }