@wayq/beekon-rn 0.0.8 → 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 (69) hide show
  1. package/BeekonRn.podspec +3 -3
  2. package/CHANGELOG.md +58 -6
  3. package/LICENSE.txt +3 -3
  4. package/README.md +85 -264
  5. package/android/build.gradle +2 -2
  6. package/android/src/main/java/in/wayq/beekonrn/BeekonRnModule.kt +133 -8
  7. package/ios/BeekonRn.mm +40 -0
  8. package/ios/BeekonRn.swift +176 -8
  9. package/ios/Frameworks/BeekonKit.xcframework/Info.plist +5 -5
  10. package/ios/Frameworks/BeekonKit.xcframework/LICENSE.txt +3 -3
  11. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64/BeekonKit.framework/BeekonKit +0 -0
  12. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64/BeekonKit.framework/Modules/BeekonKit.swiftmodule/arm64-apple-ios.abi.json +5839 -3482
  13. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64/BeekonKit.framework/Modules/BeekonKit.swiftmodule/arm64-apple-ios.swiftdoc +0 -0
  14. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64/BeekonKit.framework/Modules/BeekonKit.swiftmodule/arm64-apple-ios.swiftinterface +93 -16
  15. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64_x86_64-simulator/BeekonKit.framework/BeekonKit +0 -0
  16. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64_x86_64-simulator/BeekonKit.framework/Modules/BeekonKit.swiftmodule/arm64-apple-ios-simulator.abi.json +5839 -3482
  17. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64_x86_64-simulator/BeekonKit.framework/Modules/BeekonKit.swiftmodule/arm64-apple-ios-simulator.swiftdoc +0 -0
  18. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64_x86_64-simulator/BeekonKit.framework/Modules/BeekonKit.swiftmodule/arm64-apple-ios-simulator.swiftinterface +93 -16
  19. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64_x86_64-simulator/BeekonKit.framework/Modules/BeekonKit.swiftmodule/x86_64-apple-ios-simulator.abi.json +5839 -3482
  20. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64_x86_64-simulator/BeekonKit.framework/Modules/BeekonKit.swiftmodule/x86_64-apple-ios-simulator.swiftdoc +0 -0
  21. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64_x86_64-simulator/BeekonKit.framework/Modules/BeekonKit.swiftmodule/x86_64-apple-ios-simulator.swiftinterface +93 -16
  22. package/lib/module/NativeBeekonRn.js +6 -0
  23. package/lib/module/NativeBeekonRn.js.map +1 -1
  24. package/lib/module/beekon.js +109 -1
  25. package/lib/module/beekon.js.map +1 -1
  26. package/lib/module/index.js +4 -0
  27. package/lib/module/index.js.map +1 -1
  28. package/lib/module/internal/licenseNudge.js +64 -0
  29. package/lib/module/internal/licenseNudge.js.map +1 -0
  30. package/lib/module/internal/mappers.js +68 -8
  31. package/lib/module/internal/mappers.js.map +1 -1
  32. package/lib/module/types/config.js +73 -1
  33. package/lib/module/types/config.js.map +1 -1
  34. package/lib/module/types/log.js +4 -0
  35. package/lib/module/types/log.js.map +1 -0
  36. package/lib/module/types/permission.js +2 -0
  37. package/lib/module/types/permission.js.map +1 -0
  38. package/lib/typescript/src/NativeBeekonRn.d.ts +66 -2
  39. package/lib/typescript/src/NativeBeekonRn.d.ts.map +1 -1
  40. package/lib/typescript/src/beekon.d.ts +56 -1
  41. package/lib/typescript/src/beekon.d.ts.map +1 -1
  42. package/lib/typescript/src/index.d.ts +5 -2
  43. package/lib/typescript/src/index.d.ts.map +1 -1
  44. package/lib/typescript/src/internal/licenseNudge.d.ts +38 -0
  45. package/lib/typescript/src/internal/licenseNudge.d.ts.map +1 -0
  46. package/lib/typescript/src/internal/mappers.d.ts +5 -1
  47. package/lib/typescript/src/internal/mappers.d.ts.map +1 -1
  48. package/lib/typescript/src/types/config.d.ts +90 -7
  49. package/lib/typescript/src/types/config.d.ts.map +1 -1
  50. package/lib/typescript/src/types/enums.d.ts +8 -0
  51. package/lib/typescript/src/types/enums.d.ts.map +1 -1
  52. package/lib/typescript/src/types/log.d.ts +22 -0
  53. package/lib/typescript/src/types/log.d.ts.map +1 -0
  54. package/lib/typescript/src/types/permission.d.ts +42 -0
  55. package/lib/typescript/src/types/permission.d.ts.map +1 -0
  56. package/lib/typescript/src/types/state.d.ts +4 -1
  57. package/lib/typescript/src/types/state.d.ts.map +1 -1
  58. package/package.json +5 -5
  59. package/scripts/fetch-beekonkit.sh +6 -6
  60. package/src/NativeBeekonRn.ts +70 -2
  61. package/src/beekon.ts +114 -1
  62. package/src/index.tsx +12 -1
  63. package/src/internal/licenseNudge.ts +80 -0
  64. package/src/internal/mappers.ts +93 -7
  65. package/src/types/config.ts +99 -7
  66. package/src/types/enums.ts +9 -0
  67. package/src/types/log.ts +22 -0
  68. package/src/types/permission.ts +48 -0
  69. package/src/types/state.ts +4 -0
package/BeekonRn.podspec CHANGED
@@ -11,11 +11,11 @@ Pod::Spec.new do |s|
11
11
  s.authors = package["author"]
12
12
 
13
13
  # iOS 17.0 floor reflects this wrapper's React Native baseline (RN 0.85), not
14
- # a BeekonKit constraint — BeekonKit 0.0.8 itself supports iOS 13+ (with
14
+ # a BeekonKit constraint — BeekonKit 0.0.9 itself supports iOS 13+ (with
15
15
  # 13–16 fallback paths). Kept at 17.0 to avoid any consumer regression; do not
16
16
  # lower below React Native's own minimum.
17
17
  s.platforms = { :ios => "17.0" }
18
- s.source = { :git => "https://github.com/wayqteam/beekon-rn.git", :tag => "v#{s.version}" }
18
+ s.source = { :git => "https://github.com/beekonlabs/beekon-rn.git", :tag => "v#{s.version}" }
19
19
 
20
20
  s.source_files = "ios/**/*.{h,m,mm,swift,cpp}"
21
21
  # Headers are only for the auto-generated `BeekonRn-Swift.h` interop — keep
@@ -23,7 +23,7 @@ Pod::Spec.new do |s|
23
23
  s.private_header_files = "ios/**/*.h"
24
24
 
25
25
  # Native Beekon SDK as a vendored xcframework. The zip is fetched from
26
- # `wayqteam/beekon-ios-binary`'s GitHub Release at this version into
26
+ # `beekonlabs/beekon-ios-binary`'s GitHub Release at this version into
27
27
  # `ios/Frameworks/` by `scripts/fetch-beekonkit.sh`, run via `yarn prepare`,
28
28
  # and bundled in the npm tarball at publish time. SHA256 verified before
29
29
  # extraction.
package/CHANGELOG.md CHANGED
@@ -6,6 +6,58 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
  Beekon is pre-1.0 — releases may contain breaking changes.
8
8
 
9
+ ## [0.1.0] - 2026-06-15
10
+
11
+ ### Changed
12
+
13
+ - **Moved to the `beekonlabs` GitHub org.** The Android native dependency
14
+ coordinate is now `io.github.beekonlabs:beekon` (was `io.github.wayqteam:beekon`),
15
+ and the iOS xcframework is fetched from `github.com/beekonlabs/beekon-ios-binary`.
16
+ This is internal to the module — the npm package name (`@wayq/beekon-rn`) is
17
+ unchanged and no consumer code changes are required.
18
+
19
+ ### Added
20
+
21
+ - **`getPermissionStatus()` — read-only permission query.** Resolves the current
22
+ location grant as a `PermissionStatus` (`level`: `notDetermined` / `denied` /
23
+ `restricted` / `foreground` / `background`; nullable `accuracy`: `full` /
24
+ `reduced`) for pre-start checks, without ever prompting. Adds the
25
+ `PermissionLevel` / `PermissionAccuracy` types and `isAuthorized` /
26
+ `canTrackInBackground`. Beekon still never *requests* permission — the app owns
27
+ that; during tracking, loss surfaces on `onState`. On Android, "not yet asked"
28
+ and "denied" both report `notDetermined`; `restricted` is iOS-only. Requires
29
+ the native SDKs ≥ the release that adds the API.
30
+
31
+ ## [0.0.9] - 2026-06-14
32
+
33
+ ### Added
34
+
35
+ - **Cloud mode** (cloud-mode-v1): point a project key (`bkproj_…`) at Beekon
36
+ Cloud and let the server own tracking config, geofences, and the license.
37
+ Built via `BeekonConfig.cloud(...)`; cloud config takes the project key and an
38
+ optional `endpoint` (default `https://api.getbeekon.com`). Requires the native
39
+ SDKs ≥ 0.0.9.
40
+ - **Diagnostic logging** (log-format-v1): `getLog` / `exportLog` / `clearLog` /
41
+ `setLogLevel` / `log` plus the `onLog` subscription and `LogEntry` / `LogLevel`
42
+ types; `logLevel` on each config arm sets the threshold. Requires the native
43
+ SDKs ≥ 0.0.9.
44
+ - **`SyncConfig.syncThreshold`** ([beekon#20]): pending-fix count that triggers
45
+ an early upload of regular fixes ahead of the `intervalSeconds` schedule (not
46
+ subject to the Android ~15 min WorkManager floor). `0` (the default) leaves
47
+ regular fixes to the schedule. Independent of this setting, a geofence event
48
+ and a session stop with pending fixes always flush immediately while sync is
49
+ configured. Requires the native SDKs ≥ 0.0.9.
50
+
51
+ ### Changed
52
+
53
+ - **BREAKING:** `BeekonConfig` is now a sealed two-arm discriminated union
54
+ (`CloudConfig | SelfManagedConfig`) built via `BeekonConfig.cloud(...)` /
55
+ `BeekonConfig.selfManaged(...)`; the flat config object is gone and a `mode`
56
+ discriminator (`'cloud'` | `'selfManaged'`) is now required. Tracking params,
57
+ `sync`, and `licenseKey` live only on the `selfManaged` arm.
58
+
59
+ [beekon#20]: https://github.com/beekonlabs/beekon/issues/20
60
+
9
61
  ## [0.0.8]
10
62
 
11
63
  Built against the native **0.0.8** API; requires native ≥ 0.0.8 at runtime.
@@ -13,7 +65,7 @@ No binding API changes.
13
65
 
14
66
  ### Changed
15
67
 
16
- - Native pins bumped to `0.0.8` (Maven `io.github.wayqteam:beekon`, `BeekonKit`
68
+ - Native pins bumped to `0.0.8` (Maven `io.github.beekonlabs:beekon`, `BeekonKit`
17
69
  xcframework). 0.0.8 embeds the production ES256 license verification keyset,
18
70
  so genuine `license-format-v1` tokens resolve to `licensed` / `evaluation`
19
71
  on-device, and hardens wire/license conformance. The license surface remains a
@@ -40,7 +92,7 @@ Built against the native **0.0.7** API; requires native ≥ 0.0.7 at runtime.
40
92
  degrades, or delays the SDK; Android and iOS may legally diverge for the
41
93
  same app.
42
94
  - The binding identifies itself to the verifier as the `rn` product.
43
- - Native pins bumped to `0.0.7` (Maven `io.github.wayqteam:beekon`, `BeekonKit`
95
+ - Native pins bumped to `0.0.7` (Maven `io.github.beekonlabs:beekon`, `BeekonKit`
44
96
  xcframework).
45
97
 
46
98
  ## [0.0.6]
@@ -80,7 +132,7 @@ Built against the native **0.0.6** API; requires native ≥ 0.0.6 at runtime.
80
132
  - `resumeIfNeeded()` now calls the guarded native `Beekon.resumeIfNeeded()` on
81
133
  Android (previously `Beekon.start()`): it re-adopts a previously-active,
82
134
  non-user-stopped session only, mirroring iOS.
83
- - Native pins bumped to `0.0.6` (Maven `io.github.wayqteam:beekon`, iOS
135
+ - Native pins bumped to `0.0.6` (Maven `io.github.beekonlabs:beekon`, iOS
84
136
  `BeekonKit.xcframework`).
85
137
 
86
138
  ## [0.0.5]
@@ -110,7 +162,7 @@ release. The TypeScript surface is a faithful 1:1 mirror of the native `Beekon`
110
162
  `minDistanceBetweenLocationsMeters`.
111
163
  - `getLocations(from: Date, to: Date)` replaces the prior history call.
112
164
  - Notification config is now `androidNotification` (Android-only; iOS ignores it).
113
- - Native pins bumped to `0.0.5` (Maven `io.github.wayqteam:beekon`, SwiftPM
165
+ - Native pins bumped to `0.0.5` (Maven `io.github.beekonlabs:beekon`, SwiftPM
114
166
  `beekon-ios-binary`).
115
167
 
116
168
  ### Removed
@@ -121,7 +173,7 @@ release. The TypeScript surface is a faithful 1:1 mirror of the native `Beekon`
121
173
  ## [0.0.3]
122
174
 
123
175
  First synchronized release across all four registries (Maven Central,
124
- `wayqteam/beekon-ios-binary` xcframework, pub.dev, npm). `Location`
176
+ `beekonlabs/beekon-ios-binary` xcframework, pub.dev, npm). `Location`
125
177
  accuracy/speed/bearing/altitude are nullable to faithfully represent providers
126
178
  that don't deliver them.
127
179
 
@@ -132,7 +184,7 @@ Initial release.
132
184
  ### Added
133
185
 
134
186
  - React Native (New Architecture / TurboModule) binding for the native Beekon
135
- location SDKs (Android `io.github.wayqteam:beekon`, iOS `BeekonKit`
187
+ location SDKs (Android `io.github.beekonlabs:beekon`, iOS `BeekonKit`
136
188
  xcframework).
137
189
  - Public API mirroring the native surface: `Beekon.configure / start / stop /
138
190
  getLocations`, plus `onState` / `onLocation` subscriptions.
package/LICENSE.txt CHANGED
@@ -1,9 +1,9 @@
1
1
  Beekon SDK
2
- Copyright (c) 2026 wayqteam. All rights reserved.
2
+ Copyright (c) 2026 beekonlabs. All rights reserved.
3
3
 
4
4
  This software is licensed for evaluation use only. No production deployment,
5
5
  redistribution, sublicensing, or commercial use is permitted without a separate
6
- written agreement with wayqteam.
6
+ written agreement with beekonlabs.
7
7
 
8
8
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
9
9
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
@@ -11,4 +11,4 @@ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
11
11
  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY ARISING
12
12
  FROM USE OF THE SOFTWARE.
13
13
 
14
- For licensing inquiries: contact wayqteam.
14
+ For licensing inquiries: contact beekonlabs.
package/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  <p align="center">
8
8
  Background location tracking for React Native.<br/>
9
- Native location stack on each platform — tracking survives backgrounding and termination.
9
+ A native location stack on each platform — tracking survives backgrounding and termination.
10
10
  </p>
11
11
 
12
12
  <p align="center">
@@ -17,22 +17,22 @@
17
17
 
18
18
  <p align="center">
19
19
  <a href="https://docs.getbeekon.com"><strong>Docs</strong></a> ·
20
- <a href="https://console.getbeekon.com"><strong>Console</strong></a> ·
21
20
  <a href="https://getbeekon.com"><strong>getbeekon.com</strong></a> ·
22
- <a href="https://github.com/wayqteam/beekon"><strong>Umbrella</strong></a>
21
+ <a href="https://github.com/beekonlabs/beekon"><strong>GitHub</strong></a>
23
22
  </p>
24
23
 
25
24
  ---
26
25
 
27
- Capture GPS in the foreground and background, keep a queryable history on the device, define geofences, and optionally sync to your own server. The JavaScript API is fully typed.
26
+ Capture location in the foreground and background, keep a queryable history on the device, define geofences, and optionally upload to a backend **you** control. Nothing leaves the device unless you set a `sync` endpoint. The JavaScript API is fully typed.
28
27
 
29
28
  ## Features
30
29
 
31
30
  - Foreground and background tracking that survives app termination
32
- - Battery-aware capture: time and distance filtering, accuracy presets, and automatic pausing while the device is stationary
31
+ - Battery-aware capture: time/distance filtering, accuracy presets, auto-pause while stationary
33
32
  - On-device history you can query at any time
34
33
  - Geofencing with enter and exit events
35
34
  - Optional batched server sync with automatic retry
35
+ - Diagnostic logging: query/export an on-device buffer, stream live entries
36
36
  - Activity detection (walking, running, cycling, automotive)
37
37
  - Built for the React Native New Architecture
38
38
 
@@ -44,19 +44,81 @@ Capture GPS in the foreground and background, keep a queryable history on the de
44
44
  | iOS | 17.0 |
45
45
  | Android | 8.0 (API level 26) |
46
46
 
47
- ## Installation
47
+ ## Install
48
48
 
49
49
  ```sh
50
50
  npm install @wayq/beekon-rn
51
51
  ```
52
52
 
53
- **iOS** — install pods:
53
+ **iOS** — `cd ios && pod install`. **Android** — no extra steps; the module links automatically. See [Setup](#permissions-and-setup) for the OS config.
54
54
 
55
- ```sh
56
- cd ios && pod install
55
+ ## Quick start
56
+
57
+ ```ts
58
+ import { Beekon } from '@wayq/beekon-rn';
59
+
60
+ const offState = Beekon.onState((state) => console.log('state:', state.kind));
61
+ const offLocation = Beekon.onLocation((loc) =>
62
+ console.log(loc.latitude, loc.longitude, loc.timestamp),
63
+ );
64
+
65
+ // Configure is optional. Request OS permissions before starting (see Setup).
66
+ await Beekon.configure({
67
+ mode: 'selfManaged',
68
+ minTimeBetweenLocationsSeconds: 30,
69
+ minDistanceBetweenLocationsMeters: 100,
70
+ });
71
+
72
+ await Beekon.start();
73
+ ```
74
+
75
+ `start()` and `stop()` never throw. Observe `onState` to learn whether tracking began and why it stopped (`'user' | 'permissionDenied' | 'locationServicesDisabled' | 'locationUnavailable' | 'system'`).
76
+
77
+ ## Send to your backend
78
+
79
+ Add a `sync` config and Beekon uploads fixes and geofence events to your backend — batched, retried, and removed from the device once your server accepts them. Without a `sync` config, all data stays on the device.
80
+
81
+ ```ts
82
+ await Beekon.configure({
83
+ mode: 'selfManaged',
84
+ sync: {
85
+ url: 'https://api.example.com/locations',
86
+ headers: { Authorization: 'Bearer <token>' },
87
+ // intervalSeconds defaults to 300, batchSize to 100
88
+ },
89
+ });
90
+
91
+ Beekon.setExtras({ userId: 'abc123' }); // attached to every upload
92
+ Beekon.onSyncStatus((status) => console.log('sync:', status.kind));
93
+ ```
94
+
95
+ Your server receives a small JSON envelope and acknowledges it with a status code. **[Build your ingest endpoint](https://docs.getbeekon.com/backend/ingest/)** is a complete, working example. For rotating bearer tokens, set `sync.auth` and the SDK attaches and **natively refreshes** the token — proactively before expiry, reactively on a `401`/`403` — even in the background. See [Auth & token refresh](https://docs.getbeekon.com/backend/auth/).
96
+
97
+ ## More
98
+
99
+ ```ts
100
+ // History (stored on the device, survives restarts)
101
+ const since = new Date(Date.now() - 24 * 60 * 60 * 1000);
102
+ const fixes = await Beekon.getLocations(since, new Date());
103
+
104
+ // Geofences — enter/exit events that keep firing across launches
105
+ await Beekon.addGeofences([
106
+ { id: 'office', latitude: 37.331, longitude: -122.031, radiusMeters: 150 },
107
+ ]);
108
+ const offGeofence = Beekon.onGeofenceEvent((e) => console.log(e.geofenceId, e.type));
109
+
110
+ // One-shot fix, independent of tracking (null on timeout)
111
+ const fix = await Beekon.getCurrentLocation();
112
+
113
+ // Pre-start permission check (the app still owns the request)
114
+ const status = await Beekon.getPermissionStatus();
115
+
116
+ // Diagnostics — runtime level, live tail, NDJSON export for bug reports
117
+ await Beekon.setLogLevel('debug');
118
+ const logPath = await Beekon.exportLog();
57
119
  ```
58
120
 
59
- **Android** — no additional steps; the module links automatically.
121
+ A **license key** is optional and purely observational `configure({ mode: 'selfManaged', licenseKey: '<JWS>' })`, then read `licenseStatus()`; without one, Beekon runs in evaluation mode. The package ships full TypeScript types, so methods, config, and events are typed in your editor. Complete API and guides: **[docs.getbeekon.com](https://docs.getbeekon.com)**.
60
122
 
61
123
  ## Permissions and setup
62
124
 
@@ -76,7 +138,7 @@ In `android/app/src/main/AndroidManifest.xml`:
76
138
  <uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
77
139
  ```
78
140
 
79
- While tracking, Android shows a persistent notification (required by the system). Set its title and text with the `notification` option.
141
+ While tracking, Android shows a persistent notification (required by the system). Set its title and text with the `notification` config option.
80
142
 
81
143
  ### iOS
82
144
 
@@ -101,7 +163,7 @@ In `Info.plist`:
101
163
  <string>Explain why your app detects activity.</string>
102
164
  ```
103
165
 
104
- Register Beekon's background task once during launch (required for background sync and to resume tracking after the app is terminated). In `AppDelegate.swift`:
166
+ Register Beekon's background task once during launch (required for background sync and to resume tracking after termination). In `AppDelegate.swift`:
105
167
 
106
168
  ```swift
107
169
  import BeekonRn
@@ -116,272 +178,31 @@ func application(
116
178
  }
117
179
  ```
118
180
 
119
- ## Usage
120
-
121
- ### Start tracking
122
-
123
- ```ts
124
- import { Beekon } from '@wayq/beekon-rn';
125
-
126
- const offState = Beekon.onState((state) => {
127
- console.log('state:', state.kind); // 'idle' | 'tracking' | 'stopped'
128
- });
129
-
130
- const offLocation = Beekon.onLocation((location) => {
131
- console.log(location.latitude, location.longitude, location.timestamp);
132
- });
133
-
134
- // Configure is optional. Request OS permissions before starting.
135
- await Beekon.configure({
136
- minTimeBetweenLocationsSeconds: 30,
137
- minDistanceBetweenLocationsMeters: 100,
138
- });
139
-
140
- await Beekon.start();
141
-
142
- // Later:
143
- await Beekon.stop();
144
- offState();
145
- offLocation();
146
- ```
147
-
148
- `start()` and `stop()` never throw. Observe `onState` to learn whether tracking began and why it stopped:
149
-
150
- ```ts
151
- Beekon.onState((state) => {
152
- if (state.kind === 'stopped') {
153
- // 'user' | 'permissionDenied' | 'locationServicesDisabled'
154
- // | 'locationUnavailable' | 'system'
155
- console.log('stopped:', state.reason);
156
- }
157
- });
158
- ```
159
-
160
- ### Read history
161
-
162
- Recorded fixes are stored on the device and remain available even after the app is closed.
163
-
164
- ```ts
165
- const since = new Date(Date.now() - 24 * 60 * 60 * 1000);
166
- const fixes = await Beekon.getLocations(since, new Date());
167
-
168
- await Beekon.deleteLocations(); // delete everything
169
- await Beekon.deleteLocations(since); // delete up to a cutoff
170
- ```
171
-
172
- ### Geofences
173
-
174
- ```ts
175
- await Beekon.addGeofences([
176
- { id: 'office', latitude: 37.331, longitude: -122.031, radiusMeters: 150 },
177
- ]);
178
-
179
- const offGeofence = Beekon.onGeofenceEvent((event) => {
180
- console.log(event.geofenceId, event.type); // 'enter' | 'exit'
181
- });
182
-
183
- await Beekon.listGeofences();
184
- await Beekon.removeGeofences(['office']);
185
- ```
186
-
187
- ### Server sync
188
-
189
- Add a `sync` config to upload recorded fixes and geofence events to your backend. Uploads are batched, retried automatically, and removed from the device once your server accepts them. Without a `sync` config, all data stays on the device.
190
-
191
- ```ts
192
- await Beekon.configure({
193
- sync: {
194
- url: 'https://api.example.com/locations',
195
- headers: { Authorization: 'Bearer <token>' },
196
- // intervalSeconds defaults to 300, batchSize to 100
197
- },
198
- });
199
-
200
- Beekon.setExtras({ userId: 'abc123' }); // attached to every upload
201
-
202
- Beekon.onSyncStatus((status) => {
203
- console.log('sync:', status.kind); // 'idle' | 'pending' | 'failed'
204
- });
205
- ```
206
-
207
- #### Token refresh
208
-
209
- Set `sync.auth` (an `AuthConfig`) to let the SDK attach and **natively** refresh the upload access token — proactively before it expires and reactively on a `401`/`403`, then retry the upload. This runs in the background and survives a cold launch with no host involvement. Without `auth`, a `401`/`403` pauses sync and surfaces `SyncFailure 'auth'`; re-seed by calling `configure()` again to resume.
210
-
211
- The supplied tokens are a **seed**: the SDK owns and rotates the live token set in secure storage (Keychain / encrypted prefs) after first persist. Subscribe with `onAuthTokens` to mirror rotations into your own session store.
212
-
213
- ```ts
214
- await Beekon.configure({
215
- sync: {
216
- url: 'https://api.example.com/locations',
217
- auth: {
218
- accessToken: '<initial access token>',
219
- refreshToken: '<initial refresh token>',
220
- expiresAt: new Date(Date.now() + 3600_000),
221
- refreshUrl: 'https://auth.example.com/oauth/token',
222
- refreshPayload: {
223
- grant_type: 'refresh_token',
224
- refresh_token: '{refreshToken}', // substituted with the current token
225
- },
226
- // strategy defaults to 'bearer', refreshBodyFormat to 'form',
227
- // skewMarginSeconds to 60. responseMapping defaults to common-name detection.
228
- },
229
- },
230
- });
181
+ ## API at a glance
231
182
 
232
- const offAuth = Beekon.onAuthTokens((tokens) => {
233
- // Persist the rotated set into your own session store.
234
- console.log('rotated:', tokens.accessToken, tokens.expiresAt, tokens.epoch);
235
- });
236
- ```
183
+ Methods: `configure` · `start` · `stop` · `resumeIfNeeded` · `getCurrentLocation` · `getLocations` · `deleteLocations` · `pendingUploadCount` · `sync` · `setExtras` · `addGeofences` · `removeGeofences` · `listGeofences` · `getPermissionStatus` · `licenseStatus` · `getLog` · `exportLog` · `clearLog` · `setLogLevel` · `log`.
237
184
 
238
- The refresh recipe is persisted in plaintext to survive a cold launch **do not** put static client secrets in `refreshHeaders` or `refreshPayload`. Requires the native SDK ≥ 0.0.6; with an older native binary the recipe is ignored and only static `sync.headers` apply.
185
+ Subscriptions (each returns an unsubscribe function): `onState` · `onLocation` · `onGeofenceEvent` · `onSyncStatus` · `onAuthTokens` · `onLicenseStatus` · `onLog`.
239
186
 
240
- ## Configuration
241
-
242
- All options are optional; defaults are shown.
243
-
244
- | Option | Default | Description |
245
- |---|---|---|
246
- | `minTimeBetweenLocationsSeconds` | `30` | Minimum seconds between recorded fixes. `0` disables the time filter. |
247
- | `minDistanceBetweenLocationsMeters` | `100` | Minimum metres between recorded fixes. `0` disables the distance filter. |
248
- | `accuracyMode` | `'balanced'` | `'high'` \| `'balanced'` \| `'low'`. Trades accuracy against battery. |
249
- | `whenStationary` | `'pause'` | `'keepTracking'` \| `'pause'` \| `'pauseWithCheckIns'`. |
250
- | `stationaryRadiusMeters` | `5` | Distance the device must move to count as moving again. |
251
- | `detectActivity` | `false` | Detect physical activity. Requires the motion permission. |
252
- | `sync` | – | Server upload settings: `{ url, headers?, intervalSeconds?, batchSize?, auth? }`. See [Token refresh](#token-refresh). |
253
- | `notification` | – | Android-only tracking notification: `{ title?, text?, smallIcon? }`. `smallIcon` is a drawable/mipmap resource name. |
254
-
255
- A fix is recorded only when **both** the time and distance filters are satisfied.
256
-
257
- ## API
258
-
259
- | Method | Description |
260
- |---|---|
261
- | `configure(config)` | Apply settings. Optional; may be called while tracking. |
262
- | `start()` | Begin tracking. |
263
- | `stop()` | Stop tracking. |
264
- | `resumeIfNeeded()` | Resume a session that was active before the app closed. |
265
- | `getCurrentLocation(options?)` | One-shot current fix, independent of tracking. Resolves `null` on timeout. `options`: `{ timeoutMs?, accuracy? }`. |
266
- | `getLocations(from, to)` | Recorded fixes within a date range. |
267
- | `deleteLocations(before?)` | Delete fixes (all if `before` is omitted); returns the count removed. |
268
- | `pendingUploadCount()` | Number of fixes not yet uploaded. |
269
- | `sync()` | Request an immediate upload. |
270
- | `setExtras(extras)` | Custom fields included with every upload. |
271
- | `addGeofences(geofences)` | Register circular regions. |
272
- | `removeGeofences(ids)` | Unregister geofences by id. |
273
- | `listGeofences()` | Currently registered geofences. |
274
-
275
- Subscriptions — each returns an unsubscribe function:
276
-
277
- | Subscription | Delivers |
278
- |---|---|
279
- | `onState(cb)` | Tracking state changes. The current state is delivered immediately. |
280
- | `onLocation(cb)` | Each newly recorded fix. |
281
- | `onGeofenceEvent(cb)` | Geofence enter and exit events. |
282
- | `onSyncStatus(cb)` | Upload status. The current status is delivered immediately. |
283
- | `onAuthTokens(cb)` | Token rotations from native refresh (see [Token refresh](#token-refresh)). The latest rotation is delivered immediately. |
284
-
285
- `getLocations`, `deleteLocations`, `pendingUploadCount`, and `addGeofences` reject with a `BeekonError` on failure — check `error.kind` (`'storage'` or `'invalidGeofence'`). `getCurrentLocation` rejects with `error.kind` `'permissionDenied'`, `'locationServicesDisabled'`, or `'locationUnavailable'` on a precondition failure. Other methods resolve normally; tracking-lifecycle problems are reported through `onState` rather than thrown.
286
-
287
- ## Types
288
-
289
- ```ts
290
- type Location = {
291
- id: string;
292
- latitude: number;
293
- longitude: number;
294
- timestamp: Date;
295
- accuracy: number | null; // metres
296
- speed: number | null; // m/s
297
- bearing: number | null; // degrees from true north
298
- altitude: number | null; // metres
299
- quality: 'ok' | 'lowAccuracy' | 'implausibleSpeed';
300
- trigger: 'interval' | 'motion' | 'checkIn' | 'geofence' | 'manual';
301
- motion: 'moving' | 'stationary' | 'unknown';
302
- activity:
303
- | 'stationary' | 'walking' | 'running'
304
- | 'cycling' | 'automotive' | 'unknown' | null;
305
- isMock: boolean;
306
- };
307
-
308
- type BeekonState =
309
- | { kind: 'idle' }
310
- | { kind: 'tracking' }
311
- | {
312
- kind: 'stopped';
313
- reason:
314
- | 'user' | 'permissionDenied' | 'locationServicesDisabled'
315
- | 'locationUnavailable' | 'system';
316
- };
317
-
318
- type SyncStatus =
319
- | { kind: 'idle' }
320
- | { kind: 'pending' }
321
- | { kind: 'failed'; reason: 'auth' | 'rejected' };
322
-
323
- type BeekonGeofence = {
324
- id: string;
325
- latitude: number;
326
- longitude: number;
327
- radiusMeters: number;
328
- notifyOnEntry?: boolean; // default true
329
- notifyOnExit?: boolean; // default true
330
- };
331
-
332
- type GeofenceEvent = {
333
- id: string;
334
- geofenceId: string;
335
- type: 'enter' | 'exit';
336
- timestamp: Date;
337
- };
338
-
339
- // Set on `SyncConfig.auth` to enable native token refresh. The token fields are
340
- // a seed — the SDK rotates them after first persist.
341
- type AuthConfig = {
342
- accessToken?: string;
343
- refreshToken?: string;
344
- expiresAt?: Date;
345
- strategy?: 'bearer' | 'raw'; // default 'bearer'
346
- refreshUrl?: string; // omit to disable refresh
347
- refreshPayload?: Record<string, string>; // '{refreshToken}' substituted
348
- refreshHeaders?: Record<string, string>; // '{accessToken}' substituted
349
- refreshBodyFormat?: 'form' | 'json'; // default 'form'
350
- responseMapping?: {
351
- accessToken?: string;
352
- refreshToken?: string;
353
- expiresIn?: string;
354
- expiresAt?: string;
355
- };
356
- skewMarginSeconds?: number; // default 60
357
- seedEpoch?: number;
358
- };
359
-
360
- // Delivered by `onAuthTokens` after each native rotation. Sensitive — in-process
361
- // only, never logged.
362
- type AuthTokens = {
363
- accessToken: string;
364
- refreshToken: string | null;
365
- expiresAt: Date | null;
366
- epoch: number; // monotonic generation, bumped on each refresh
367
- };
368
- ```
369
-
370
- Optional numeric fields on `Location` are `null` when the device did not report them — never `0`.
187
+ Every method, type, and event is documented at **[docs.getbeekon.com](https://docs.getbeekon.com)** and typed in the package.
371
188
 
372
189
  ## Notes
373
190
 
374
- - **Retention.** Fixes are kept on the device for up to 7 days, or the most recent 100,000 fixes, whichever comes first.
375
- - **Background relaunch.** Call `resumeIfNeeded()` early in your app to restore tracking after the system terminates it. On Android, also resume from your `Application.onCreate` (see the example app).
191
+ - **Retention.** Fixes are kept for up to 7 days, or the most recent 100,000 fixes, whichever comes first.
192
+ - **Background relaunch.** Call `resumeIfNeeded()` early in startup to restore tracking after the system terminates the app. On Android, also resume from `Application.onCreate` (see the example app).
376
193
  - **Android background limits.** Some manufacturers aggressively stop background services; if tracking halts unexpectedly, see [dontkillmyapp.com](https://dontkillmyapp.com).
377
194
 
195
+ ## Beekon Cloud
196
+
197
+ Prefer managed ingest, a console, and server-owned config instead of running your own backend? **Beekon Cloud** is in private beta — see the [docs](https://docs.getbeekon.com/cloud/).
198
+
378
199
  ## Example
379
200
 
380
201
  A complete, runnable example is in the [`example/`](./example) directory.
381
202
 
382
203
  ## License
383
204
 
384
- Proprietary — evaluation use only without a separate written agreement with wayqteam. See [LICENSE.txt](./LICENSE.txt).
205
+ Proprietary — evaluation use only without a separate written agreement with WayQ Technologies Pvt Ltd. See [LICENSE.txt](./LICENSE.txt).
385
206
 
386
207
  ---
387
208
 
@@ -1,7 +1,7 @@
1
1
  buildscript {
2
2
  ext.BeekonRn = [
3
3
  kotlinVersion: "2.1.20",
4
- // minSdk 26 is required by the native Beekon AAR (io.github.wayqteam:beekon).
4
+ // minSdk 26 is required by the native Beekon AAR (io.github.beekonlabs:beekon).
5
5
  minSdkVersion: 26,
6
6
  compileSdkVersion: 36,
7
7
  targetSdkVersion: 36
@@ -79,7 +79,7 @@ dependencies {
79
79
  // the SDK reaches v1 stability. 0.0.7 is the release that ships the license
80
80
  // API (setWrapperInfo / BeekonConfig.licenseKey / Beekon.licenseStatus);
81
81
  // 0.0.8 embeds the production ES256 verification keyset.
82
- implementation "io.github.wayqteam:beekon:0.0.8"
82
+ implementation "io.github.beekonlabs:beekon:0.1.0"
83
83
  // Kotlin coroutines — required for collecting Beekon's StateFlow/SharedFlow.
84
84
  // Beekon already depends on coroutines transitively, but declaring it here
85
85
  // makes the dependency intent explicit.