@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.
- package/BeekonRn.podspec +3 -3
- package/CHANGELOG.md +58 -6
- package/LICENSE.txt +3 -3
- package/README.md +85 -264
- package/android/build.gradle +2 -2
- package/android/src/main/java/in/wayq/beekonrn/BeekonRnModule.kt +133 -8
- package/ios/BeekonRn.mm +40 -0
- package/ios/BeekonRn.swift +176 -8
- package/ios/Frameworks/BeekonKit.xcframework/Info.plist +5 -5
- package/ios/Frameworks/BeekonKit.xcframework/LICENSE.txt +3 -3
- package/ios/Frameworks/BeekonKit.xcframework/ios-arm64/BeekonKit.framework/BeekonKit +0 -0
- package/ios/Frameworks/BeekonKit.xcframework/ios-arm64/BeekonKit.framework/Modules/BeekonKit.swiftmodule/arm64-apple-ios.abi.json +5839 -3482
- package/ios/Frameworks/BeekonKit.xcframework/ios-arm64/BeekonKit.framework/Modules/BeekonKit.swiftmodule/arm64-apple-ios.swiftdoc +0 -0
- package/ios/Frameworks/BeekonKit.xcframework/ios-arm64/BeekonKit.framework/Modules/BeekonKit.swiftmodule/arm64-apple-ios.swiftinterface +93 -16
- package/ios/Frameworks/BeekonKit.xcframework/ios-arm64_x86_64-simulator/BeekonKit.framework/BeekonKit +0 -0
- package/ios/Frameworks/BeekonKit.xcframework/ios-arm64_x86_64-simulator/BeekonKit.framework/Modules/BeekonKit.swiftmodule/arm64-apple-ios-simulator.abi.json +5839 -3482
- package/ios/Frameworks/BeekonKit.xcframework/ios-arm64_x86_64-simulator/BeekonKit.framework/Modules/BeekonKit.swiftmodule/arm64-apple-ios-simulator.swiftdoc +0 -0
- package/ios/Frameworks/BeekonKit.xcframework/ios-arm64_x86_64-simulator/BeekonKit.framework/Modules/BeekonKit.swiftmodule/arm64-apple-ios-simulator.swiftinterface +93 -16
- package/ios/Frameworks/BeekonKit.xcframework/ios-arm64_x86_64-simulator/BeekonKit.framework/Modules/BeekonKit.swiftmodule/x86_64-apple-ios-simulator.abi.json +5839 -3482
- package/ios/Frameworks/BeekonKit.xcframework/ios-arm64_x86_64-simulator/BeekonKit.framework/Modules/BeekonKit.swiftmodule/x86_64-apple-ios-simulator.swiftdoc +0 -0
- package/ios/Frameworks/BeekonKit.xcframework/ios-arm64_x86_64-simulator/BeekonKit.framework/Modules/BeekonKit.swiftmodule/x86_64-apple-ios-simulator.swiftinterface +93 -16
- package/lib/module/NativeBeekonRn.js +6 -0
- package/lib/module/NativeBeekonRn.js.map +1 -1
- package/lib/module/beekon.js +109 -1
- package/lib/module/beekon.js.map +1 -1
- package/lib/module/index.js +4 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/internal/licenseNudge.js +64 -0
- package/lib/module/internal/licenseNudge.js.map +1 -0
- package/lib/module/internal/mappers.js +68 -8
- package/lib/module/internal/mappers.js.map +1 -1
- package/lib/module/types/config.js +73 -1
- package/lib/module/types/config.js.map +1 -1
- package/lib/module/types/log.js +4 -0
- package/lib/module/types/log.js.map +1 -0
- package/lib/module/types/permission.js +2 -0
- package/lib/module/types/permission.js.map +1 -0
- package/lib/typescript/src/NativeBeekonRn.d.ts +66 -2
- package/lib/typescript/src/NativeBeekonRn.d.ts.map +1 -1
- package/lib/typescript/src/beekon.d.ts +56 -1
- package/lib/typescript/src/beekon.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +5 -2
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/internal/licenseNudge.d.ts +38 -0
- package/lib/typescript/src/internal/licenseNudge.d.ts.map +1 -0
- package/lib/typescript/src/internal/mappers.d.ts +5 -1
- package/lib/typescript/src/internal/mappers.d.ts.map +1 -1
- package/lib/typescript/src/types/config.d.ts +90 -7
- package/lib/typescript/src/types/config.d.ts.map +1 -1
- package/lib/typescript/src/types/enums.d.ts +8 -0
- package/lib/typescript/src/types/enums.d.ts.map +1 -1
- package/lib/typescript/src/types/log.d.ts +22 -0
- package/lib/typescript/src/types/log.d.ts.map +1 -0
- package/lib/typescript/src/types/permission.d.ts +42 -0
- package/lib/typescript/src/types/permission.d.ts.map +1 -0
- package/lib/typescript/src/types/state.d.ts +4 -1
- package/lib/typescript/src/types/state.d.ts.map +1 -1
- package/package.json +5 -5
- package/scripts/fetch-beekonkit.sh +6 -6
- package/src/NativeBeekonRn.ts +70 -2
- package/src/beekon.ts +114 -1
- package/src/index.tsx +12 -1
- package/src/internal/licenseNudge.ts +80 -0
- package/src/internal/mappers.ts +93 -7
- package/src/types/config.ts +99 -7
- package/src/types/enums.ts +9 -0
- package/src/types/log.ts +22 -0
- package/src/types/permission.ts +48 -0
- 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.
|
|
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/
|
|
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
|
-
# `
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
`
|
|
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.
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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/
|
|
21
|
+
<a href="https://github.com/beekonlabs/beekon"><strong>GitHub</strong></a>
|
|
23
22
|
</p>
|
|
24
23
|
|
|
25
24
|
---
|
|
26
25
|
|
|
27
|
-
Capture
|
|
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
|
|
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
|
-
##
|
|
47
|
+
## Install
|
|
48
48
|
|
|
49
49
|
```sh
|
|
50
50
|
npm install @wayq/beekon-rn
|
|
51
51
|
```
|
|
52
52
|
|
|
53
|
-
**iOS** — install
|
|
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
|
-
|
|
56
|
-
|
|
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
|
-
**
|
|
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
|
|
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
|
-
##
|
|
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
|
-
|
|
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
|
-
|
|
185
|
+
Subscriptions (each returns an unsubscribe function): `onState` · `onLocation` · `onGeofenceEvent` · `onSyncStatus` · `onAuthTokens` · `onLicenseStatus` · `onLog`.
|
|
239
186
|
|
|
240
|
-
|
|
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
|
|
375
|
-
- **Background relaunch.** Call `resumeIfNeeded()` early in
|
|
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
|
|
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
|
|
package/android/build.gradle
CHANGED
|
@@ -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.
|
|
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.
|
|
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.
|