@bricks-soft/capacitor-location-tracking 0.0.0-stage → 8.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 (168) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +2759 -2
  3. package/android/build.gradle +106 -0
  4. package/android/consumer-rules.pro +42 -0
  5. package/android/src/main/AndroidManifest.xml +52 -0
  6. package/android/src/main/java/com/brickssoft/locationtracking/LocationTrackingPlugin.kt +431 -0
  7. package/android/src/main/java/com/brickssoft/locationtracking/api/LocationTrackingListener.kt +52 -0
  8. package/android/src/main/java/com/brickssoft/locationtracking/api/LocationTrackingNative.kt +267 -0
  9. package/android/src/main/java/com/brickssoft/locationtracking/api/NativeListeners.kt +270 -0
  10. package/android/src/main/java/com/brickssoft/locationtracking/api/NativeThread.kt +57 -0
  11. package/android/src/main/java/com/brickssoft/locationtracking/bridge/BridgeServices.kt +64 -0
  12. package/android/src/main/java/com/brickssoft/locationtracking/bridge/CallResponder.kt +41 -0
  13. package/android/src/main/java/com/brickssoft/locationtracking/bridge/OptionParsers.kt +281 -0
  14. package/android/src/main/java/com/brickssoft/locationtracking/bridge/PluginHandlers.kt +541 -0
  15. package/android/src/main/java/com/brickssoft/locationtracking/bridge/PluginPermissionHost.kt +76 -0
  16. package/android/src/main/java/com/brickssoft/locationtracking/bridge/WatchRegistry.kt +84 -0
  17. package/android/src/main/java/com/brickssoft/locationtracking/config/Config.kt +231 -0
  18. package/android/src/main/java/com/brickssoft/locationtracking/config/ConfigJson.kt +574 -0
  19. package/android/src/main/java/com/brickssoft/locationtracking/config/ConfigStore.kt +31 -0
  20. package/android/src/main/java/com/brickssoft/locationtracking/config/ConfigValidator.kt +170 -0
  21. package/android/src/main/java/com/brickssoft/locationtracking/config/RuntimeStateJson.kt +73 -0
  22. package/android/src/main/java/com/brickssoft/locationtracking/config/SharedPrefsConfigStore.kt +135 -0
  23. package/android/src/main/java/com/brickssoft/locationtracking/config/State.kt +45 -0
  24. package/android/src/main/java/com/brickssoft/locationtracking/core/AppDispatchers.kt +21 -0
  25. package/android/src/main/java/com/brickssoft/locationtracking/core/Clock.kt +41 -0
  26. package/android/src/main/java/com/brickssoft/locationtracking/core/Components.kt +217 -0
  27. package/android/src/main/java/com/brickssoft/locationtracking/core/Constants.kt +78 -0
  28. package/android/src/main/java/com/brickssoft/locationtracking/core/Errors.kt +27 -0
  29. package/android/src/main/java/com/brickssoft/locationtracking/core/EventBus.kt +39 -0
  30. package/android/src/main/java/com/brickssoft/locationtracking/core/ForceStopProbe.kt +63 -0
  31. package/android/src/main/java/com/brickssoft/locationtracking/core/Iso8601.kt +63 -0
  32. package/android/src/main/java/com/brickssoft/locationtracking/core/Logger.kt +68 -0
  33. package/android/src/main/java/com/brickssoft/locationtracking/core/RecordHooks.kt +47 -0
  34. package/android/src/main/java/com/brickssoft/locationtracking/core/TrackingEvent.kt +64 -0
  35. package/android/src/main/java/com/brickssoft/locationtracking/data/SqlSupport.kt +79 -0
  36. package/android/src/main/java/com/brickssoft/locationtracking/data/SqliteGeofenceStore.kt +144 -0
  37. package/android/src/main/java/com/brickssoft/locationtracking/data/SqliteLocationStore.kt +215 -0
  38. package/android/src/main/java/com/brickssoft/locationtracking/data/Stores.kt +45 -0
  39. package/android/src/main/java/com/brickssoft/locationtracking/data/TrackingDatabase.kt +111 -0
  40. package/android/src/main/java/com/brickssoft/locationtracking/device/DefaultDeviceInfoProvider.kt +104 -0
  41. package/android/src/main/java/com/brickssoft/locationtracking/device/DefaultDeviceMonitor.kt +335 -0
  42. package/android/src/main/java/com/brickssoft/locationtracking/device/DeviceMonitor.kt +36 -0
  43. package/android/src/main/java/com/brickssoft/locationtracking/device/DeviceStateMapping.kt +69 -0
  44. package/android/src/main/java/com/brickssoft/locationtracking/engine/DefaultTrackingEngine.kt +1281 -0
  45. package/android/src/main/java/com/brickssoft/locationtracking/engine/ElasticDistance.kt +68 -0
  46. package/android/src/main/java/com/brickssoft/locationtracking/engine/LocationRequests.kt +74 -0
  47. package/android/src/main/java/com/brickssoft/locationtracking/engine/MotionStateMachine.kt +291 -0
  48. package/android/src/main/java/com/brickssoft/locationtracking/engine/StationaryRegion.kt +41 -0
  49. package/android/src/main/java/com/brickssoft/locationtracking/engine/TrackingEngine.kt +60 -0
  50. package/android/src/main/java/com/brickssoft/locationtracking/engine/TrackingTimers.kt +90 -0
  51. package/android/src/main/java/com/brickssoft/locationtracking/geofence/DefaultGeofenceManager.kt +899 -0
  52. package/android/src/main/java/com/brickssoft/locationtracking/geofence/DwellTracker.kt +80 -0
  53. package/android/src/main/java/com/brickssoft/locationtracking/geofence/GeofenceManager.kt +33 -0
  54. package/android/src/main/java/com/brickssoft/locationtracking/geofence/PolygonMath.kt +194 -0
  55. package/android/src/main/java/com/brickssoft/locationtracking/heartbeat/DefaultHeartbeatScheduler.kt +713 -0
  56. package/android/src/main/java/com/brickssoft/locationtracking/heartbeat/HeartbeatAlarmReceiver.kt +69 -0
  57. package/android/src/main/java/com/brickssoft/locationtracking/heartbeat/HeartbeatAlarms.kt +100 -0
  58. package/android/src/main/java/com/brickssoft/locationtracking/heartbeat/HeartbeatScheduler.kt +25 -0
  59. package/android/src/main/java/com/brickssoft/locationtracking/heartbeat/HeartbeatWindow.kt +179 -0
  60. package/android/src/main/java/com/brickssoft/locationtracking/http/AuthorizationManager.kt +213 -0
  61. package/android/src/main/java/com/brickssoft/locationtracking/http/BodyBuilder.kt +73 -0
  62. package/android/src/main/java/com/brickssoft/locationtracking/http/HttpSupport.kt +118 -0
  63. package/android/src/main/java/com/brickssoft/locationtracking/http/HttpSyncer.kt +18 -0
  64. package/android/src/main/java/com/brickssoft/locationtracking/http/OkHttpSyncer.kt +551 -0
  65. package/android/src/main/java/com/brickssoft/locationtracking/http/StrictJson.kt +135 -0
  66. package/android/src/main/java/com/brickssoft/locationtracking/http/SyncPolicy.kt +109 -0
  67. package/android/src/main/java/com/brickssoft/locationtracking/http/TemplateRenderer.kt +143 -0
  68. package/android/src/main/java/com/brickssoft/locationtracking/logging/FileLogger.kt +461 -0
  69. package/android/src/main/java/com/brickssoft/locationtracking/logging/LogFileProvider.kt +9 -0
  70. package/android/src/main/java/com/brickssoft/locationtracking/logging/LogFormatter.kt +148 -0
  71. package/android/src/main/java/com/brickssoft/locationtracking/logging/LogStore.kt +30 -0
  72. package/android/src/main/java/com/brickssoft/locationtracking/model/DeviceModels.kt +176 -0
  73. package/android/src/main/java/com/brickssoft/locationtracking/model/GeofenceSpec.kt +25 -0
  74. package/android/src/main/java/com/brickssoft/locationtracking/model/ModelJson.kt +550 -0
  75. package/android/src/main/java/com/brickssoft/locationtracking/model/Record.kt +106 -0
  76. package/android/src/main/java/com/brickssoft/locationtracking/model/TrackedLocation.kt +53 -0
  77. package/android/src/main/java/com/brickssoft/locationtracking/permission/BackgroundRationaleDialog.kt +85 -0
  78. package/android/src/main/java/com/brickssoft/locationtracking/permission/CurrentActivityTracker.kt +72 -0
  79. package/android/src/main/java/com/brickssoft/locationtracking/permission/DefaultPermissionManager.kt +333 -0
  80. package/android/src/main/java/com/brickssoft/locationtracking/permission/PermissionManager.kt +54 -0
  81. package/android/src/main/java/com/brickssoft/locationtracking/position/DefaultPositionService.kt +277 -0
  82. package/android/src/main/java/com/brickssoft/locationtracking/position/PositionService.kt +39 -0
  83. package/android/src/main/java/com/brickssoft/locationtracking/position/PositionWatch.kt +115 -0
  84. package/android/src/main/java/com/brickssoft/locationtracking/processing/DefaultLocationProcessor.kt +93 -0
  85. package/android/src/main/java/com/brickssoft/locationtracking/processing/DefaultOdometer.kt +99 -0
  86. package/android/src/main/java/com/brickssoft/locationtracking/processing/DefaultRecordFactory.kt +166 -0
  87. package/android/src/main/java/com/brickssoft/locationtracking/processing/Geo.kt +56 -0
  88. package/android/src/main/java/com/brickssoft/locationtracking/processing/KalmanFilter.kt +72 -0
  89. package/android/src/main/java/com/brickssoft/locationtracking/processing/Processing.kt +48 -0
  90. package/android/src/main/java/com/brickssoft/locationtracking/provider/Backends.kt +187 -0
  91. package/android/src/main/java/com/brickssoft/locationtracking/provider/DefaultProviderFactory.kt +169 -0
  92. package/android/src/main/java/com/brickssoft/locationtracking/provider/ProviderPackaging.kt +135 -0
  93. package/android/src/main/java/com/brickssoft/locationtracking/provider/android/AndroidActivityBackend.kt +25 -0
  94. package/android/src/main/java/com/brickssoft/locationtracking/provider/android/AndroidGeofenceBackend.kt +181 -0
  95. package/android/src/main/java/com/brickssoft/locationtracking/provider/android/AndroidGeofenceReceiver.kt +115 -0
  96. package/android/src/main/java/com/brickssoft/locationtracking/provider/android/AndroidLocationBackend.kt +265 -0
  97. package/android/src/main/java/com/brickssoft/locationtracking/provider/android/AndroidProviderBundle.kt +31 -0
  98. package/android/src/main/java/com/brickssoft/locationtracking/provider/android/LocationProviders.kt +98 -0
  99. package/android/src/main/java/com/brickssoft/locationtracking/provider/gms/GmsActivityBackend.kt +80 -0
  100. package/android/src/main/java/com/brickssoft/locationtracking/provider/gms/GmsActivityReceiver.kt +62 -0
  101. package/android/src/main/java/com/brickssoft/locationtracking/provider/gms/GmsErrors.kt +72 -0
  102. package/android/src/main/java/com/brickssoft/locationtracking/provider/gms/GmsGeofenceBackend.kt +152 -0
  103. package/android/src/main/java/com/brickssoft/locationtracking/provider/gms/GmsGeofenceReceiver.kt +78 -0
  104. package/android/src/main/java/com/brickssoft/locationtracking/provider/gms/GmsLocationBackend.kt +176 -0
  105. package/android/src/main/java/com/brickssoft/locationtracking/provider/gms/GmsProviderBundle.kt +62 -0
  106. package/android/src/main/java/com/brickssoft/locationtracking/provider/gms/GmsReceiverSupport.kt +88 -0
  107. package/android/src/main/java/com/brickssoft/locationtracking/provider/gms/GmsTasks.kt +55 -0
  108. package/android/src/main/java/com/brickssoft/locationtracking/provider/hms/HmsActivityBackend.kt +71 -0
  109. package/android/src/main/java/com/brickssoft/locationtracking/provider/hms/HmsActivityReceiver.kt +57 -0
  110. package/android/src/main/java/com/brickssoft/locationtracking/provider/hms/HmsErrors.kt +76 -0
  111. package/android/src/main/java/com/brickssoft/locationtracking/provider/hms/HmsGeofenceBackend.kt +116 -0
  112. package/android/src/main/java/com/brickssoft/locationtracking/provider/hms/HmsGeofenceReceiver.kt +67 -0
  113. package/android/src/main/java/com/brickssoft/locationtracking/provider/hms/HmsIntents.kt +83 -0
  114. package/android/src/main/java/com/brickssoft/locationtracking/provider/hms/HmsLocationBackend.kt +197 -0
  115. package/android/src/main/java/com/brickssoft/locationtracking/provider/hms/HmsProviderBundle.kt +55 -0
  116. package/android/src/main/java/com/brickssoft/locationtracking/provider/hms/HmsTasks.kt +44 -0
  117. package/android/src/main/java/com/brickssoft/locationtracking/record/RecordSink.kt +95 -0
  118. package/android/src/main/java/com/brickssoft/locationtracking/service/BootCountStore.kt +44 -0
  119. package/android/src/main/java/com/brickssoft/locationtracking/service/BootReceiver.kt +175 -0
  120. package/android/src/main/java/com/brickssoft/locationtracking/service/DefaultServiceController.kt +196 -0
  121. package/android/src/main/java/com/brickssoft/locationtracking/service/LocationTrackingService.kt +319 -0
  122. package/android/src/main/java/com/brickssoft/locationtracking/service/NotificationActionReceiver.kt +42 -0
  123. package/android/src/main/java/com/brickssoft/locationtracking/service/NotificationFactory.kt +338 -0
  124. package/android/src/main/java/com/brickssoft/locationtracking/service/ServiceCommands.kt +204 -0
  125. package/android/src/main/java/com/brickssoft/locationtracking/service/ServiceController.kt +22 -0
  126. package/android/src/main/java/com/brickssoft/locationtracking/service/ServiceDeps.kt +61 -0
  127. package/android/src/main/java/com/brickssoft/locationtracking/service/WhileInUseStartCheck.kt +115 -0
  128. package/android/src/main/java/com/brickssoft/locationtracking/settings/DefaultDeviceSettings.kt +79 -0
  129. package/android/src/main/java/com/brickssoft/locationtracking/settings/DeviceSettings.kt +21 -0
  130. package/android/src/main/java/com/brickssoft/locationtracking/settings/OemPowerManagers.kt +198 -0
  131. package/android/src/main/res/drawable/lt_ic_notification.xml +11 -0
  132. package/android/src/main/res/values/lt_strings.xml +11 -0
  133. package/android/src/main/res/xml/lt_file_paths.xml +5 -0
  134. package/dist/esm/definitions.d.ts +719 -0
  135. package/dist/esm/definitions.js +2 -0
  136. package/dist/esm/definitions.js.map +1 -0
  137. package/dist/esm/events.d.ts +50 -0
  138. package/dist/esm/events.js +52 -0
  139. package/dist/esm/events.js.map +1 -0
  140. package/dist/esm/index.d.ts +3 -0
  141. package/dist/esm/index.js +5 -0
  142. package/dist/esm/index.js.map +1 -0
  143. package/dist/esm/plugin.d.ts +3 -0
  144. package/dist/esm/plugin.js +10 -0
  145. package/dist/esm/plugin.js.map +1 -0
  146. package/dist/esm/web/config.d.ts +19 -0
  147. package/dist/esm/web/config.js +243 -0
  148. package/dist/esm/web/config.js.map +1 -0
  149. package/dist/esm/web/device.d.ts +9 -0
  150. package/dist/esm/web/device.js +90 -0
  151. package/dist/esm/web/device.js.map +1 -0
  152. package/dist/esm/web/errors.d.ts +14 -0
  153. package/dist/esm/web/errors.js +19 -0
  154. package/dist/esm/web/errors.js.map +1 -0
  155. package/dist/esm/web/geolocation.d.ts +26 -0
  156. package/dist/esm/web/geolocation.js +117 -0
  157. package/dist/esm/web/geolocation.js.map +1 -0
  158. package/dist/esm/web/location.d.ts +7 -0
  159. package/dist/esm/web/location.js +70 -0
  160. package/dist/esm/web/location.js.map +1 -0
  161. package/dist/esm/web.d.ts +164 -0
  162. package/dist/esm/web.js +328 -0
  163. package/dist/esm/web.js.map +1 -0
  164. package/dist/plugin.cjs.js +945 -0
  165. package/dist/plugin.cjs.js.map +1 -0
  166. package/dist/plugin.js +948 -0
  167. package/dist/plugin.js.map +1 -0
  168. package/package.json +59 -4
@@ -0,0 +1,328 @@
1
+ // Owned by Unit 1 (TS wrapper + web).
2
+ import { WebPlugin } from '@capacitor/core';
3
+ import { cloneJson, defaultConfig, isPlainObject, mergeConfig, webState } from './web/config';
4
+ import { webDeviceInfo } from './web/device';
5
+ import { positionErrorInfo, webError } from './web/errors';
6
+ import { browserGeolocation, probeLocationPermission, queryLocationPermission, sampleBestPosition, } from './web/geolocation';
7
+ import { toLocation } from './web/location';
8
+ const ALL_PERMISSIONS = ['location', 'notifications', 'activityRecognition', 'backgroundLocation'];
9
+ function highAccuracy(accuracy) {
10
+ return accuracy === undefined || accuracy === 'high';
11
+ }
12
+ function nonNegative(value, fallback) {
13
+ return typeof value === 'number' && value >= 0 ? value : fallback;
14
+ }
15
+ /** The defaults plus `options.config` (optional; must be an object when given). */
16
+ function configFromDefaults(options) {
17
+ const given = options ? options.config : undefined;
18
+ if (given !== undefined && given !== null && !isPlainObject(given)) {
19
+ throw webError('INVALID_ARGUMENT', 'config must be an object.');
20
+ }
21
+ return mergeConfig(defaultConfig(), given || undefined);
22
+ }
23
+ /**
24
+ * Web implementation. It covers `getCurrentPosition`, `watchPosition` and `clearWatch` (via `navigator.geolocation`),
25
+ * an in-memory config and state, permissions and device info. Nothing is persisted or uploaded, and tracking cannot
26
+ * be started. Every other method rejects with `UNIMPLEMENTED`.
27
+ *
28
+ * Like the Android bridge, methods other than `ready`, `getState`, `checkPermissions`, `requestPermissions` and
29
+ * `getDeviceInfo` reject with `NOT_READY` until `ready()` has resolved.
30
+ */
31
+ export class LocationTrackingWeb extends WebPlugin {
32
+ constructor() {
33
+ super(...arguments);
34
+ this.config = defaultConfig();
35
+ this.isReady = false;
36
+ this.lastPosition = null;
37
+ this.watchSeq = 0;
38
+ this.watches = new Map();
39
+ }
40
+ async ready(options) {
41
+ const config = configFromDefaults(options);
42
+ // reset:false applies the given config only on the first ready(); afterwards the current config wins.
43
+ if (!options || options.reset !== false || !this.isReady) {
44
+ this.config = config;
45
+ }
46
+ this.isReady = true;
47
+ return webState(this.config);
48
+ }
49
+ async setConfig(options) {
50
+ this.requireReady();
51
+ if (!options || !isPlainObject(options.config)) {
52
+ throw webError('INVALID_ARGUMENT', 'config must be an object.');
53
+ }
54
+ this.config = mergeConfig(this.config, options.config);
55
+ return webState(this.config);
56
+ }
57
+ async reset(options) {
58
+ this.requireReady();
59
+ this.config = configFromDefaults(options);
60
+ return webState(this.config);
61
+ }
62
+ async getState() {
63
+ return webState(this.config);
64
+ }
65
+ async start() {
66
+ throw this.unimplemented('Not implemented on web.');
67
+ }
68
+ async startGeofences() {
69
+ throw this.unimplemented('Not implemented on web.');
70
+ }
71
+ async stop() {
72
+ throw this.unimplemented('Not implemented on web.');
73
+ }
74
+ async changePace(_options) {
75
+ throw this.unimplemented('Not implemented on web.');
76
+ }
77
+ /**
78
+ * Takes `samples` fixes within `timeout` and resolves the most accurate one. With `maximumAge > 0`, a fix this
79
+ * plugin received at most that long ago is returned right away. Like a persisted record on Android, the result is
80
+ * also emitted as a `location` event unless `persist` is false.
81
+ */
82
+ async getCurrentPosition(options) {
83
+ var _a;
84
+ this.requireReady();
85
+ const geolocation = this.requireGeolocation();
86
+ const o = options || {};
87
+ const maximumAge = nonNegative(o.maximumAge, 0);
88
+ const cached = this.lastPosition;
89
+ let position;
90
+ if (maximumAge > 0 && cached && Date.now() - cached.timestamp <= maximumAge) {
91
+ position = cached;
92
+ }
93
+ else {
94
+ const samples = typeof o.samples === 'number' && o.samples >= 1 ? Math.floor(o.samples) : 3;
95
+ position = await sampleBestPosition(geolocation, {
96
+ samples,
97
+ timeout: nonNegative(o.timeout, nonNegative((_a = this.config.geolocation) === null || _a === void 0 ? void 0 : _a.locationTimeout, 30000)),
98
+ maximumAge,
99
+ enableHighAccuracy: highAccuracy(o.desiredAccuracy),
100
+ });
101
+ }
102
+ this.lastPosition = position;
103
+ const location = toLocation(position, 'current_position', this.recordExtras(o.extras));
104
+ if (o.persist !== false) {
105
+ this.emit('location', location);
106
+ }
107
+ return location;
108
+ }
109
+ /**
110
+ * Starts `navigator.geolocation.watchPosition` and resolves its id. The callback gets each fix as a
111
+ * `watch_position` Location, or `(null, { code, message })` on error. `interval` is ignored: the browser decides
112
+ * how often fixes arrive. With `persist: true` each fix is also emitted as a `location` event.
113
+ */
114
+ async watchPosition(options, callback) {
115
+ this.requireReady();
116
+ if (typeof callback !== 'function') {
117
+ throw webError('INVALID_ARGUMENT', 'watchPosition requires a callback.');
118
+ }
119
+ const geolocation = this.requireGeolocation();
120
+ const o = options || {};
121
+ const callExtras = cloneJson(o.extras);
122
+ const persist = o.persist === true;
123
+ const entry = { active: true, geolocation, browserId: 0 };
124
+ try {
125
+ entry.browserId = geolocation.watchPosition((position) => {
126
+ // Browsers may still deliver a queued fix after clearWatch.
127
+ if (!entry.active) {
128
+ return;
129
+ }
130
+ this.lastPosition = position;
131
+ const location = toLocation(position, 'watch_position', this.recordExtras(callExtras));
132
+ if (persist) {
133
+ this.emit('location', location);
134
+ }
135
+ callback(location);
136
+ }, (error) => {
137
+ if (entry.active) {
138
+ callback(null, positionErrorInfo(error));
139
+ }
140
+ }, { enableHighAccuracy: highAccuracy(o.desiredAccuracy), maximumAge: 0 });
141
+ }
142
+ catch (e) {
143
+ throw webError('UNAVAILABLE', e instanceof Error ? e.message : String(e));
144
+ }
145
+ const id = `web-watch-${++this.watchSeq}`;
146
+ this.watches.set(id, entry);
147
+ return id;
148
+ }
149
+ /** Stops a watch. Unknown ids are ignored. */
150
+ async clearWatch(options) {
151
+ this.requireReady();
152
+ if (!options || typeof options.id !== 'string') {
153
+ throw webError('INVALID_ARGUMENT', 'id must be a string.');
154
+ }
155
+ const entry = this.watches.get(options.id);
156
+ if (!entry) {
157
+ return;
158
+ }
159
+ this.watches.delete(options.id);
160
+ entry.active = false;
161
+ entry.geolocation.clearWatch(entry.browserId);
162
+ }
163
+ async getOdometer() {
164
+ throw this.unimplemented('Not implemented on web.');
165
+ }
166
+ async setOdometer(_options) {
167
+ throw this.unimplemented('Not implemented on web.');
168
+ }
169
+ async resetOdometer() {
170
+ throw this.unimplemented('Not implemented on web.');
171
+ }
172
+ async getLocations(_options) {
173
+ throw this.unimplemented('Not implemented on web.');
174
+ }
175
+ async getCount() {
176
+ throw this.unimplemented('Not implemented on web.');
177
+ }
178
+ async insertLocation(_options) {
179
+ throw this.unimplemented('Not implemented on web.');
180
+ }
181
+ async destroyLocations() {
182
+ throw this.unimplemented('Not implemented on web.');
183
+ }
184
+ async destroyLocation(_options) {
185
+ throw this.unimplemented('Not implemented on web.');
186
+ }
187
+ async sync() {
188
+ throw this.unimplemented('Not implemented on web.');
189
+ }
190
+ async addGeofence(_options) {
191
+ throw this.unimplemented('Not implemented on web.');
192
+ }
193
+ async addGeofences(_options) {
194
+ throw this.unimplemented('Not implemented on web.');
195
+ }
196
+ async removeGeofence(_options) {
197
+ throw this.unimplemented('Not implemented on web.');
198
+ }
199
+ async removeGeofences(_options) {
200
+ throw this.unimplemented('Not implemented on web.');
201
+ }
202
+ async getGeofences() {
203
+ throw this.unimplemented('Not implemented on web.');
204
+ }
205
+ async getGeofence(_options) {
206
+ throw this.unimplemented('Not implemented on web.');
207
+ }
208
+ async geofenceExists(_options) {
209
+ throw this.unimplemented('Not implemented on web.');
210
+ }
211
+ async getHeartbeatStatus() {
212
+ throw this.unimplemented('Not implemented on web.');
213
+ }
214
+ async getProviderState() {
215
+ throw this.unimplemented('Not implemented on web.');
216
+ }
217
+ async isPowerSaveMode() {
218
+ throw this.unimplemented('Not implemented on web.');
219
+ }
220
+ async getBatteryOptimizationStatus() {
221
+ throw this.unimplemented('Not implemented on web.');
222
+ }
223
+ async openBatteryOptimizationSettings() {
224
+ throw this.unimplemented('Not implemented on web.');
225
+ }
226
+ async getPowerManagerInfo() {
227
+ throw this.unimplemented('Not implemented on web.');
228
+ }
229
+ async openPowerManagerSettings() {
230
+ throw this.unimplemented('Not implemented on web.');
231
+ }
232
+ async openLocationSettings() {
233
+ throw this.unimplemented('Not implemented on web.');
234
+ }
235
+ async openAppSettings() {
236
+ throw this.unimplemented('Not implemented on web.');
237
+ }
238
+ /** Best-effort values parsed from `navigator.userAgent`; `platform` is `'web'`. */
239
+ async getDeviceInfo() {
240
+ const nav = typeof navigator !== 'undefined' && navigator ? navigator : undefined;
241
+ return webDeviceInfo(nav && typeof nav.userAgent === 'string' ? nav.userAgent : '', nav ? nav.platform : undefined);
242
+ }
243
+ async getSensors() {
244
+ throw this.unimplemented('Not implemented on web.');
245
+ }
246
+ /** `location` comes from the Permissions API (`'prompt'` when it cannot tell); the other three are `'granted'`. */
247
+ async checkPermissions() {
248
+ const location = await queryLocationPermission();
249
+ return {
250
+ location: location || 'prompt',
251
+ backgroundLocation: 'granted',
252
+ activityRecognition: 'granted',
253
+ notifications: 'granted',
254
+ };
255
+ }
256
+ /** When `location` is requested and still undecided, asks for a fix so the browser prompts, then reports. */
257
+ async requestPermissions(options) {
258
+ const requested = options && Array.isArray(options.permissions) ? options.permissions : ALL_PERMISSIONS;
259
+ const status = await this.checkPermissions();
260
+ const geolocation = browserGeolocation();
261
+ if (requested.indexOf('location') < 0 || status.location !== 'prompt' || !geolocation) {
262
+ return status;
263
+ }
264
+ const answer = await probeLocationPermission(geolocation);
265
+ // A granted probe is proof, even for a one-time grant the Permissions API still reports as 'prompt'. Otherwise
266
+ // prefer the Permissions API: a dismissed prompt fails the probe as denied but leaves the permission at 'prompt'.
267
+ status.location = answer === 'granted' ? answer : (await queryLocationPermission()) || answer;
268
+ return status;
269
+ }
270
+ async log(_options) {
271
+ throw this.unimplemented('Not implemented on web.');
272
+ }
273
+ async getLog(_options) {
274
+ throw this.unimplemented('Not implemented on web.');
275
+ }
276
+ async destroyLog() {
277
+ throw this.unimplemented('Not implemented on web.');
278
+ }
279
+ async uploadLog(_options) {
280
+ throw this.unimplemented('Not implemented on web.');
281
+ }
282
+ async emailLog(_options) {
283
+ throw this.unimplemented('Not implemented on web.');
284
+ }
285
+ requireReady() {
286
+ if (!this.isReady) {
287
+ throw webError('NOT_READY', 'Call ready() before using this method.');
288
+ }
289
+ }
290
+ requireGeolocation() {
291
+ const geolocation = browserGeolocation();
292
+ if (!geolocation) {
293
+ throw webError('UNAVAILABLE', 'navigator.geolocation is not available.');
294
+ }
295
+ return geolocation;
296
+ }
297
+ /** `persistence.extras` merged with the call's extras (the call wins), like records created on Android. */
298
+ recordExtras(extras) {
299
+ const persisted = this.config.persistence ? this.config.persistence.extras : undefined;
300
+ const merged = {};
301
+ if (isPlainObject(persisted)) {
302
+ Object.assign(merged, cloneJson(persisted));
303
+ }
304
+ if (isPlainObject(extras)) {
305
+ Object.assign(merged, cloneJson(extras));
306
+ }
307
+ return Object.keys(merged).length > 0 ? merged : undefined;
308
+ }
309
+ /**
310
+ * Like `notifyListeners`, but each listener gets its own copy of the payload (as on native, where every listener
311
+ * receives deserialized data), and a throwing listener neither skips the others nor fails the calling method.
312
+ */
313
+ emit(eventName, data) {
314
+ const listeners = this.listeners[eventName];
315
+ if (!listeners) {
316
+ return;
317
+ }
318
+ for (const listener of listeners.slice()) {
319
+ try {
320
+ listener(cloneJson(data));
321
+ }
322
+ catch (e) {
323
+ console.error(`LocationTracking: "${eventName}" listener threw`, e);
324
+ }
325
+ }
326
+ }
327
+ }
328
+ //# sourceMappingURL=web.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"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","sourcesContent":["// Owned by Unit 1 (TS wrapper + web).\nimport { WebPlugin } from '@capacitor/core';\n\nimport type {\n BatteryOptimizationStatus,\n CallbackID,\n Config,\n CurrentPositionOptions,\n DesiredAccuracy,\n DeviceInfo,\n Geofence,\n HeartbeatStatus,\n InsertLocationInput,\n Location,\n LocationTrackingEventMap,\n LocationTrackingPlugin,\n LogLevel,\n LogQuery,\n PermissionStatus,\n PermissionType,\n PowerManagerInfo,\n ProviderState,\n ReadyOptions,\n Sensors,\n State,\n WatchPositionCallback,\n WatchPositionOptions,\n} from './definitions';\nimport { cloneJson, defaultConfig, isPlainObject, mergeConfig, webState } from './web/config';\nimport { webDeviceInfo } from './web/device';\nimport { positionErrorInfo, webError } from './web/errors';\nimport {\n browserGeolocation,\n probeLocationPermission,\n queryLocationPermission,\n sampleBestPosition,\n} from './web/geolocation';\nimport { toLocation } from './web/location';\n\nconst ALL_PERMISSIONS: PermissionType[] = ['location', 'notifications', 'activityRecognition', 'backgroundLocation'];\n\ninterface WatchEntry {\n active: boolean;\n geolocation: Geolocation;\n browserId: number;\n}\n\nfunction highAccuracy(accuracy: DesiredAccuracy | undefined): boolean {\n return accuracy === undefined || accuracy === 'high';\n}\n\nfunction nonNegative(value: unknown, fallback: number): number {\n return typeof value === 'number' && value >= 0 ? value : fallback;\n}\n\n/** The defaults plus `options.config` (optional; must be an object when given). */\nfunction configFromDefaults(options: { config?: Config } | undefined): Config {\n const given = options ? options.config : undefined;\n if (given !== undefined && given !== null && !isPlainObject(given)) {\n throw webError('INVALID_ARGUMENT', 'config must be an object.');\n }\n return mergeConfig(defaultConfig(), given || undefined);\n}\n\n/**\n * Web implementation. It covers `getCurrentPosition`, `watchPosition` and `clearWatch` (via `navigator.geolocation`),\n * an in-memory config and state, permissions and device info. Nothing is persisted or uploaded, and tracking cannot\n * be started. Every other method rejects with `UNIMPLEMENTED`.\n *\n * Like the Android bridge, methods other than `ready`, `getState`, `checkPermissions`, `requestPermissions` and\n * `getDeviceInfo` reject with `NOT_READY` until `ready()` has resolved.\n */\nexport class LocationTrackingWeb extends WebPlugin implements LocationTrackingPlugin {\n private config: Config = defaultConfig();\n private isReady = false;\n private lastPosition: GeolocationPosition | null = null;\n private watchSeq = 0;\n private readonly watches = new Map<string, WatchEntry>();\n\n async ready(options?: ReadyOptions): Promise<State> {\n const config = configFromDefaults(options);\n // reset:false applies the given config only on the first ready(); afterwards the current config wins.\n if (!options || options.reset !== false || !this.isReady) {\n this.config = config;\n }\n this.isReady = true;\n return webState(this.config);\n }\n\n async setConfig(options: { config: Config }): Promise<State> {\n this.requireReady();\n if (!options || !isPlainObject(options.config)) {\n throw webError('INVALID_ARGUMENT', 'config must be an object.');\n }\n this.config = mergeConfig(this.config, options.config);\n return webState(this.config);\n }\n\n async reset(options?: { config?: Config }): Promise<State> {\n this.requireReady();\n this.config = configFromDefaults(options);\n return webState(this.config);\n }\n\n async getState(): Promise<State> {\n return webState(this.config);\n }\n\n async start(): Promise<State> {\n throw this.unimplemented('Not implemented on web.');\n }\n async startGeofences(): Promise<State> {\n throw this.unimplemented('Not implemented on web.');\n }\n async stop(): Promise<State> {\n throw this.unimplemented('Not implemented on web.');\n }\n async changePace(_options: { isMoving: boolean }): Promise<void> {\n throw this.unimplemented('Not implemented on web.');\n }\n\n /**\n * Takes `samples` fixes within `timeout` and resolves the most accurate one. With `maximumAge > 0`, a fix this\n * plugin received at most that long ago is returned right away. Like a persisted record on Android, the result is\n * also emitted as a `location` event unless `persist` is false.\n */\n async getCurrentPosition(options?: CurrentPositionOptions): Promise<Location> {\n this.requireReady();\n const geolocation = this.requireGeolocation();\n const o = options || {};\n const maximumAge = nonNegative(o.maximumAge, 0);\n const cached = this.lastPosition;\n let position: GeolocationPosition;\n if (maximumAge > 0 && cached && Date.now() - cached.timestamp <= maximumAge) {\n position = cached;\n } else {\n const samples = typeof o.samples === 'number' && o.samples >= 1 ? Math.floor(o.samples) : 3;\n position = await sampleBestPosition(geolocation, {\n samples,\n timeout: nonNegative(o.timeout, nonNegative(this.config.geolocation?.locationTimeout, 30000)),\n maximumAge,\n enableHighAccuracy: highAccuracy(o.desiredAccuracy),\n });\n }\n this.lastPosition = position;\n const location = toLocation(position, 'current_position', this.recordExtras(o.extras));\n if (o.persist !== false) {\n this.emit('location', location);\n }\n return location;\n }\n\n /**\n * Starts `navigator.geolocation.watchPosition` and resolves its id. The callback gets each fix as a\n * `watch_position` Location, or `(null, { code, message })` on error. `interval` is ignored: the browser decides\n * how often fixes arrive. With `persist: true` each fix is also emitted as a `location` event.\n */\n async watchPosition(options: WatchPositionOptions, callback: WatchPositionCallback): Promise<CallbackID> {\n this.requireReady();\n if (typeof callback !== 'function') {\n throw webError('INVALID_ARGUMENT', 'watchPosition requires a callback.');\n }\n const geolocation = this.requireGeolocation();\n const o = options || {};\n const callExtras = cloneJson(o.extras);\n const persist = o.persist === true;\n const entry: WatchEntry = { active: true, geolocation, browserId: 0 };\n try {\n entry.browserId = geolocation.watchPosition(\n (position) => {\n // Browsers may still deliver a queued fix after clearWatch.\n if (!entry.active) {\n return;\n }\n this.lastPosition = position;\n const location = toLocation(position, 'watch_position', this.recordExtras(callExtras));\n if (persist) {\n this.emit('location', location);\n }\n callback(location);\n },\n (error) => {\n if (entry.active) {\n callback(null, positionErrorInfo(error));\n }\n },\n { enableHighAccuracy: highAccuracy(o.desiredAccuracy), maximumAge: 0 },\n );\n } catch (e) {\n throw webError('UNAVAILABLE', e instanceof Error ? e.message : String(e));\n }\n const id = `web-watch-${++this.watchSeq}`;\n this.watches.set(id, entry);\n return id;\n }\n\n /** Stops a watch. Unknown ids are ignored. */\n async clearWatch(options: { id: CallbackID }): Promise<void> {\n this.requireReady();\n if (!options || typeof options.id !== 'string') {\n throw webError('INVALID_ARGUMENT', 'id must be a string.');\n }\n const entry = this.watches.get(options.id);\n if (!entry) {\n return;\n }\n this.watches.delete(options.id);\n entry.active = false;\n entry.geolocation.clearWatch(entry.browserId);\n }\n\n async getOdometer(): Promise<{ odometer: number }> {\n throw this.unimplemented('Not implemented on web.');\n }\n async setOdometer(_options: { odometer: number }): Promise<{ odometer: number }> {\n throw this.unimplemented('Not implemented on web.');\n }\n async resetOdometer(): Promise<{ odometer: number }> {\n throw this.unimplemented('Not implemented on web.');\n }\n\n async getLocations(_options?: { limit?: number }): Promise<{ locations: Location[] }> {\n throw this.unimplemented('Not implemented on web.');\n }\n async getCount(): Promise<{ count: number }> {\n throw this.unimplemented('Not implemented on web.');\n }\n async insertLocation(_options: { location: InsertLocationInput }): Promise<{ uuid: string }> {\n throw this.unimplemented('Not implemented on web.');\n }\n async destroyLocations(): Promise<{ count: number }> {\n throw this.unimplemented('Not implemented on web.');\n }\n async destroyLocation(_options: { uuid: string }): Promise<{ deleted: boolean }> {\n throw this.unimplemented('Not implemented on web.');\n }\n async sync(): Promise<{ locations: Location[] }> {\n throw this.unimplemented('Not implemented on web.');\n }\n\n async addGeofence(_options: { geofence: Geofence }): Promise<void> {\n throw this.unimplemented('Not implemented on web.');\n }\n async addGeofences(_options: { geofences: Geofence[] }): Promise<void> {\n throw this.unimplemented('Not implemented on web.');\n }\n async removeGeofence(_options: { identifier: string }): Promise<void> {\n throw this.unimplemented('Not implemented on web.');\n }\n async removeGeofences(_options?: { identifiers?: string[] }): Promise<void> {\n throw this.unimplemented('Not implemented on web.');\n }\n async getGeofences(): Promise<{ geofences: Geofence[] }> {\n throw this.unimplemented('Not implemented on web.');\n }\n async getGeofence(_options: { identifier: string }): Promise<{ geofence: Geofence | null }> {\n throw this.unimplemented('Not implemented on web.');\n }\n async geofenceExists(_options: { identifier: string }): Promise<{ exists: boolean }> {\n throw this.unimplemented('Not implemented on web.');\n }\n\n async getHeartbeatStatus(): Promise<HeartbeatStatus> {\n throw this.unimplemented('Not implemented on web.');\n }\n\n async getProviderState(): Promise<ProviderState> {\n throw this.unimplemented('Not implemented on web.');\n }\n async isPowerSaveMode(): Promise<{ isPowerSaveMode: boolean }> {\n throw this.unimplemented('Not implemented on web.');\n }\n async getBatteryOptimizationStatus(): Promise<BatteryOptimizationStatus> {\n throw this.unimplemented('Not implemented on web.');\n }\n async openBatteryOptimizationSettings(): Promise<{ opened: boolean }> {\n throw this.unimplemented('Not implemented on web.');\n }\n async getPowerManagerInfo(): Promise<PowerManagerInfo> {\n throw this.unimplemented('Not implemented on web.');\n }\n async openPowerManagerSettings(): Promise<{ opened: boolean }> {\n throw this.unimplemented('Not implemented on web.');\n }\n async openLocationSettings(): Promise<{ opened: boolean }> {\n throw this.unimplemented('Not implemented on web.');\n }\n async openAppSettings(): Promise<{ opened: boolean }> {\n throw this.unimplemented('Not implemented on web.');\n }\n\n /** Best-effort values parsed from `navigator.userAgent`; `platform` is `'web'`. */\n async getDeviceInfo(): Promise<DeviceInfo> {\n const nav = typeof navigator !== 'undefined' && navigator ? navigator : undefined;\n return webDeviceInfo(nav && typeof nav.userAgent === 'string' ? nav.userAgent : '', nav ? nav.platform : undefined);\n }\n async getSensors(): Promise<Sensors> {\n throw this.unimplemented('Not implemented on web.');\n }\n\n /** `location` comes from the Permissions API (`'prompt'` when it cannot tell); the other three are `'granted'`. */\n async checkPermissions(): Promise<PermissionStatus> {\n const location = await queryLocationPermission();\n return {\n location: location || 'prompt',\n backgroundLocation: 'granted',\n activityRecognition: 'granted',\n notifications: 'granted',\n };\n }\n\n /** When `location` is requested and still undecided, asks for a fix so the browser prompts, then reports. */\n async requestPermissions(options?: { permissions?: PermissionType[] }): Promise<PermissionStatus> {\n const requested = options && Array.isArray(options.permissions) ? options.permissions : ALL_PERMISSIONS;\n const status = await this.checkPermissions();\n const geolocation = browserGeolocation();\n if (requested.indexOf('location') < 0 || status.location !== 'prompt' || !geolocation) {\n return status;\n }\n const answer = await probeLocationPermission(geolocation);\n // A granted probe is proof, even for a one-time grant the Permissions API still reports as 'prompt'. Otherwise\n // prefer the Permissions API: a dismissed prompt fails the probe as denied but leaves the permission at 'prompt'.\n status.location = answer === 'granted' ? answer : (await queryLocationPermission()) || answer;\n return status;\n }\n\n async log(_options: { level: Exclude<LogLevel, 'off'>; message: string }): Promise<void> {\n throw this.unimplemented('Not implemented on web.');\n }\n async getLog(_options?: LogQuery): Promise<{ log: string }> {\n throw this.unimplemented('Not implemented on web.');\n }\n async destroyLog(): Promise<void> {\n throw this.unimplemented('Not implemented on web.');\n }\n async uploadLog(_options: {\n url: string;\n headers?: Record<string, string>;\n params?: Record<string, unknown>;\n }): Promise<{ success: boolean; status: number }> {\n throw this.unimplemented('Not implemented on web.');\n }\n async emailLog(_options: { email: string; subject?: string }): Promise<void> {\n throw this.unimplemented('Not implemented on web.');\n }\n\n private requireReady(): void {\n if (!this.isReady) {\n throw webError('NOT_READY', 'Call ready() before using this method.');\n }\n }\n\n private requireGeolocation(): Geolocation {\n const geolocation = browserGeolocation();\n if (!geolocation) {\n throw webError('UNAVAILABLE', 'navigator.geolocation is not available.');\n }\n return geolocation;\n }\n\n /** `persistence.extras` merged with the call's extras (the call wins), like records created on Android. */\n private recordExtras(extras: Record<string, unknown> | undefined): Record<string, unknown> | undefined {\n const persisted = this.config.persistence ? this.config.persistence.extras : undefined;\n const merged: Record<string, unknown> = {};\n if (isPlainObject(persisted)) {\n Object.assign(merged, cloneJson(persisted));\n }\n if (isPlainObject(extras)) {\n Object.assign(merged, cloneJson(extras));\n }\n return Object.keys(merged).length > 0 ? merged : undefined;\n }\n\n /**\n * Like `notifyListeners`, but each listener gets its own copy of the payload (as on native, where every listener\n * receives deserialized data), and a throwing listener neither skips the others nor fails the calling method.\n */\n private emit<K extends keyof LocationTrackingEventMap>(eventName: K, data: LocationTrackingEventMap[K]): void {\n const listeners = this.listeners[eventName];\n if (!listeners) {\n return;\n }\n for (const listener of listeners.slice()) {\n try {\n listener(cloneJson(data));\n } catch (e) {\n console.error(`LocationTracking: \"${eventName}\" listener threw`, e);\n }\n }\n }\n}\n"]}