@wayq/beekon-rn 0.0.1 → 0.0.5

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 (92) hide show
  1. package/BeekonRn.podspec +4 -4
  2. package/README.md +94 -48
  3. package/android/build.gradle +11 -6
  4. package/android/src/main/java/in/wayq/beekonrn/BeekonRnModule.kt +428 -0
  5. package/android/src/main/java/{com → in}/wayq/beekonrn/BeekonRnPackage.kt +1 -1
  6. package/ios/BeekonRn.h +5 -1
  7. package/ios/BeekonRn.mm +90 -34
  8. package/ios/BeekonRn.swift +396 -116
  9. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64/BeekonKit.framework/BeekonKit +0 -0
  10. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64/BeekonKit.framework/Info.plist +0 -0
  11. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64/BeekonKit.framework/Modules/BeekonKit.swiftmodule/arm64-apple-ios.abi.json +8636 -0
  12. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64/BeekonKit.framework/Modules/BeekonKit.swiftmodule/arm64-apple-ios.swiftdoc +0 -0
  13. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64/BeekonKit.framework/Modules/BeekonKit.swiftmodule/arm64-apple-ios.swiftinterface +236 -0
  14. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64/BeekonKit.framework/PrivacyInfo.xcprivacy +1 -1
  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/Info.plist +0 -0
  17. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64_x86_64-simulator/BeekonKit.framework/Modules/BeekonKit.swiftmodule/arm64-apple-ios-simulator.abi.json +8636 -0
  18. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64_x86_64-simulator/BeekonKit.framework/Modules/BeekonKit.swiftmodule/arm64-apple-ios-simulator.swiftdoc +0 -0
  19. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64_x86_64-simulator/BeekonKit.framework/Modules/BeekonKit.swiftmodule/arm64-apple-ios-simulator.swiftinterface +236 -0
  20. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64_x86_64-simulator/BeekonKit.framework/Modules/BeekonKit.swiftmodule/x86_64-apple-ios-simulator.abi.json +8636 -0
  21. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64_x86_64-simulator/BeekonKit.framework/Modules/BeekonKit.swiftmodule/x86_64-apple-ios-simulator.swiftdoc +0 -0
  22. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64_x86_64-simulator/BeekonKit.framework/Modules/BeekonKit.swiftmodule/x86_64-apple-ios-simulator.swiftinterface +236 -0
  23. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64_x86_64-simulator/BeekonKit.framework/PrivacyInfo.xcprivacy +1 -1
  24. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64_x86_64-simulator/BeekonKit.framework/_CodeSignature/CodeResources +2 -14
  25. package/lib/module/NativeBeekonRn.js +22 -7
  26. package/lib/module/NativeBeekonRn.js.map +1 -1
  27. package/lib/module/beekon.js +209 -60
  28. package/lib/module/beekon.js.map +1 -1
  29. package/lib/module/index.js +1 -0
  30. package/lib/module/index.js.map +1 -1
  31. package/lib/module/internal/mappers.js +145 -23
  32. package/lib/module/internal/mappers.js.map +1 -1
  33. package/lib/module/types/enums.js +2 -0
  34. package/lib/module/types/{preset.js.map → enums.js.map} +1 -1
  35. package/lib/module/types/error.js +25 -0
  36. package/lib/module/types/error.js.map +1 -0
  37. package/lib/module/types/geofence.js +2 -0
  38. package/lib/module/types/{position.js.map → geofence.js.map} +1 -1
  39. package/lib/module/types/location.js +4 -0
  40. package/lib/module/types/location.js.map +1 -0
  41. package/lib/module/types/sync.js +2 -0
  42. package/lib/module/types/sync.js.map +1 -0
  43. package/lib/typescript/src/NativeBeekonRn.d.ts +113 -35
  44. package/lib/typescript/src/NativeBeekonRn.d.ts.map +1 -1
  45. package/lib/typescript/src/beekon.d.ts +84 -49
  46. package/lib/typescript/src/beekon.d.ts.map +1 -1
  47. package/lib/typescript/src/index.d.ts +7 -4
  48. package/lib/typescript/src/index.d.ts.map +1 -1
  49. package/lib/typescript/src/internal/mappers.d.ts +16 -3
  50. package/lib/typescript/src/internal/mappers.d.ts.map +1 -1
  51. package/lib/typescript/src/types/config.d.ts +53 -31
  52. package/lib/typescript/src/types/config.d.ts.map +1 -1
  53. package/lib/typescript/src/types/enums.d.ts +48 -0
  54. package/lib/typescript/src/types/enums.d.ts.map +1 -0
  55. package/lib/typescript/src/types/error.d.ts +20 -0
  56. package/lib/typescript/src/types/error.d.ts.map +1 -0
  57. package/lib/typescript/src/types/geofence.d.ts +36 -0
  58. package/lib/typescript/src/types/geofence.d.ts.map +1 -0
  59. package/lib/typescript/src/types/location.d.ts +40 -0
  60. package/lib/typescript/src/types/location.d.ts.map +1 -0
  61. package/lib/typescript/src/types/state.d.ts +18 -9
  62. package/lib/typescript/src/types/state.d.ts.map +1 -1
  63. package/lib/typescript/src/types/sync.d.ts +27 -0
  64. package/lib/typescript/src/types/sync.d.ts.map +1 -0
  65. package/package.json +5 -6
  66. package/scripts/fetch-beekonkit.sh +5 -2
  67. package/src/NativeBeekonRn.ts +120 -34
  68. package/src/beekon.ts +235 -63
  69. package/src/index.tsx +23 -4
  70. package/src/internal/mappers.ts +213 -22
  71. package/src/types/config.ts +54 -31
  72. package/src/types/enums.ts +64 -0
  73. package/src/types/error.ts +25 -0
  74. package/src/types/geofence.ts +37 -0
  75. package/src/types/location.ts +45 -0
  76. package/src/types/state.ts +23 -7
  77. package/src/types/sync.ts +23 -0
  78. package/android/src/main/java/com/wayq/beekonrn/BeekonRnModule.kt +0 -233
  79. package/ios/Frameworks/BeekonKit.xcframework/_CodeSignature/CodeDirectory +0 -0
  80. package/ios/Frameworks/BeekonKit.xcframework/_CodeSignature/CodeRequirements +0 -0
  81. package/ios/Frameworks/BeekonKit.xcframework/_CodeSignature/CodeRequirements-1 +0 -0
  82. package/ios/Frameworks/BeekonKit.xcframework/_CodeSignature/CodeResources +0 -233
  83. package/ios/Frameworks/BeekonKit.xcframework/_CodeSignature/CodeSignature +0 -0
  84. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64/BeekonKit.framework/_CodeSignature/CodeResources +0 -113
  85. package/lib/module/types/position.js +0 -2
  86. package/lib/module/types/preset.js +0 -2
  87. package/lib/typescript/src/types/position.d.ts +0 -24
  88. package/lib/typescript/src/types/position.d.ts.map +0 -1
  89. package/lib/typescript/src/types/preset.d.ts +0 -12
  90. package/lib/typescript/src/types/preset.d.ts.map +0 -1
  91. package/src/types/position.ts +0 -23
  92. package/src/types/preset.ts +0 -11
package/BeekonRn.podspec CHANGED
@@ -10,10 +10,10 @@ Pod::Spec.new do |s|
10
10
  s.license = package["license"]
11
11
  s.authors = package["author"]
12
12
 
13
- # Match RN 0.85 default Podfile floor (15.1). Native BeekonKit's floor is
14
- # 15.0 so this is satisfied. Bump only if RN raises its default.
15
- s.platforms = { :ios => "15.1" }
16
- s.source = { :git => "https://github.com/wayqteam/beekon.git", :tag => "v#{s.version}" }
13
+ # BeekonKit targets iOS 17.0 (uses CLLocationUpdate.liveUpdates). The
14
+ # consuming app must also target iOS 17.0 or higher.
15
+ s.platforms = { :ios => "17.0" }
16
+ s.source = { :git => "https://github.com/wayqteam/beekon-rn.git", :tag => "v#{s.version}" }
17
17
 
18
18
  s.source_files = "ios/**/*.{h,m,mm,swift,cpp}"
19
19
  # Headers are only for the auto-generated `BeekonRn-Swift.h` interop — keep
package/README.md CHANGED
@@ -2,19 +2,19 @@
2
2
 
3
3
  React Native binding for the [Beekon](https://github.com/wayqteam/beekon) location SDK.
4
4
 
5
- A thin pass-through over the native Android (`io.github.wayqteam:beekon`) and iOS (`BeekonKit`) libraries. The public TypeScript surface mirrors the Kotlin / Swift / Dart APIs in shape: `init / configure / start / stop`, callback-backed `state` and `positions` streams, and a `history(from, to)` query.
5
+ A thin pass-through over the native Android (`io.github.wayqteam:beekon`) and iOS (`BeekonKit`) libraries at version **0.0.5**. The public TypeScript surface mirrors the Kotlin / Swift APIs in shape: a 12-method `Beekon` singleton, four callback streams (`state`, `locations`, `geofenceEvents`, `syncStatus`), geofencing, and optional server sync.
6
6
 
7
- Built on the React Native New Architecture (TurboModules + Codegen). The binding is a thin delegation layer — all logic, persistence, and OS integration lives natively. **Writes never cross into JavaScript**: in background the JS engine isn't guaranteed to be alive, so the native libraries own the persistence path end-to-end (same rule as the Flutter binding).
7
+ Built on the React Native New Architecture (TurboModules + Codegen). The binding contains no location logic — all tracking, persistence, geofencing, and OS integration live natively. **Writes never cross into JavaScript**: in the background the JS engine isn't guaranteed to be alive, so the native libraries own the persistence path end-to-end.
8
8
 
9
- See [`../docs/REQUIREMENTS.md`](../docs/REQUIREMENTS.md) for the full cross-platform spec.
9
+ There is **no `initialize()`** the native SDKs auto-initialize. `start()` / `stop()` **never throw**: subscribe to `onState` to learn whether tracking is active and why it stopped.
10
10
 
11
11
  ## Requirements
12
12
 
13
13
  | Area | Floor |
14
14
  |---|---|
15
15
  | React Native | 0.76+ (target 0.85) |
16
- | iOS | 15.1 |
17
- | Android | API 24 |
16
+ | iOS | 17.0 |
17
+ | Android | **API 26** (required by the native AAR) |
18
18
  | New Architecture | required (Old Arch is unsupported) |
19
19
 
20
20
  ## Install
@@ -25,19 +25,17 @@ npm install @wayq/beekon-rn
25
25
  yarn add @wayq/beekon-rn
26
26
  ```
27
27
 
28
- iOS:
28
+ iOS — the package fetches and bundles `BeekonKit.xcframework` (SHA256-verified) during `prepare`, so just install pods:
29
29
 
30
30
  ```sh
31
31
  cd ios && pod install
32
32
  ```
33
33
 
34
- The package bundles `BeekonKit.xcframework` directly no manual SwiftPM setup needed.
35
-
36
- Android: Maven Central is auto-included by the autolinker. The native AAR (`io.github.wayqteam:beekon`) is pulled transitively.
34
+ Android Maven Central is auto-included by the autolinker; the native AAR (`io.github.wayqteam:beekon`) is pulled transitively.
37
35
 
38
36
  ## Permissions
39
37
 
40
- The library does NOT request permissions itself — your app must. Use a library like [`react-native-permissions`](https://github.com/zoontek/react-native-permissions) or platform APIs.
38
+ The library does NOT request permissions — your app must (e.g. via [`react-native-permissions`](https://github.com/zoontek/react-native-permissions) or `PermissionsAndroid`). Foreground location works without background location.
41
39
 
42
40
  **Android** (`AndroidManifest.xml`):
43
41
 
@@ -47,75 +45,123 @@ The library does NOT request permissions itself — your app must. Use a library
47
45
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
48
46
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />
49
47
  <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
48
+ <!-- Only when BeekonConfig.detectActivity is enabled -->
49
+ <uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
50
50
  ```
51
51
 
52
52
  **iOS** (`Info.plist`):
53
53
 
54
54
  ```xml
55
55
  <key>NSLocationWhenInUseUsageDescription</key>
56
- <string>...</string>
56
+ <string>…</string>
57
57
  <key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
58
- <string>...</string>
58
+ <string>…</string>
59
+ <!-- Only when BeekonConfig.detectActivity is enabled -->
60
+ <key>NSMotionUsageDescription</key>
61
+ <string>…</string>
59
62
  <key>UIBackgroundModes</key>
60
- <array><string>location</string></array>
63
+ <array>
64
+ <string>location</string>
65
+ <string>fetch</string>
66
+ </array>
67
+ <key>BGTaskSchedulerPermittedIdentifiers</key>
68
+ <array>
69
+ <string>in.wayq.beekon.sync</string>
70
+ </array>
61
71
  ```
62
72
 
73
+ ## Background-task registration (iOS)
74
+
75
+ For background sync scheduling and cold-launch resume, register Beekon's background task **synchronously during app launch** (it must run before `didFinishLaunchingWithOptions` returns). In your `AppDelegate.swift`:
76
+
77
+ ```swift
78
+ import BeekonRn
79
+
80
+ func application(_ application: UIApplication,
81
+ didFinishLaunchingWithOptions launchOptions: …) -> Bool {
82
+ BeekonRnImpl.registerBackgroundTasks()
83
+ // … React Native setup …
84
+ return true
85
+ }
86
+ ```
87
+
88
+ Foreground tracking and the JS streams work without this; only background sync / relaunch need it.
89
+
90
+ ## Cold-launch resume (Android)
91
+
92
+ To resume tracking after the OS killed the process, call `in.wayq.beekon.Beekon.start()` from your `Application.onCreate` (native — the JS engine may not be running on a background relaunch). From JS, `Beekon.resumeIfNeeded()` covers the foreground case.
93
+
63
94
  ## Usage
64
95
 
65
96
  ```ts
66
- import { Beekon, type BeekonState, type Position } from '@wayq/beekon-rn';
97
+ import { Beekon, type BeekonState, type Location } from '@wayq/beekon-rn';
67
98
 
68
- // Subscribe — returns an unsubscribe function.
99
+ // Subscribe — each returns an unsubscribe function. `onState` / `onSyncStatus`
100
+ // replay the latest value to new subscribers; `onLocation` / `onGeofenceEvent`
101
+ // are broadcast (no replay).
69
102
  const offState = Beekon.onState((s: BeekonState) => console.log('state', s));
70
- const offPos = Beekon.onPosition((p: Position) => console.log('pos', p));
71
-
72
- // Initialize once at startup.
73
- await Beekon.init();
103
+ const offLoc = Beekon.onLocation((l: Location) => console.log('location', l));
74
104
 
75
- // Configure (Android requires `androidNotification`; iOS ignores it).
105
+ // Configure (optional; defaults below). Pass 0 to disable a gate.
76
106
  await Beekon.configure({
77
- preset: 'balanced', // or 'saver' / 'precision'
78
- androidNotification: {
79
- channelId: 'beekon_tracking',
80
- channelName: 'Beekon location tracking',
81
- notificationId: 1001,
82
- title: 'Tracking',
83
- text: 'Recording your route',
84
- smallIconResName: 'ic_notification', // drawable in your app
107
+ minTimeBetweenLocationsSeconds: 30, // default 30
108
+ minDistanceBetweenLocationsMeters: 100, // default 100
109
+ accuracyMode: 'balanced', // 'high' | 'balanced' | 'low'
110
+ whenStationary: 'pause', // 'keepTracking' | 'pause' | 'pauseWithCheckIns'
111
+ detectActivity: false,
112
+ // Optional server upload:
113
+ sync: {
114
+ url: 'https://example.com/ingest',
115
+ headers: { Authorization: 'Bearer …' },
85
116
  },
117
+ // Android-only foreground-service notification:
118
+ notification: { title: 'Tracking', text: 'Recording your route' },
86
119
  });
87
120
 
88
- await Beekon.start();
89
- // ... later
121
+ await Beekon.start(); // never throws — observe onState
122
+ // later
90
123
  await Beekon.stop();
91
124
 
92
- // Read past positions.
93
- const pts = await Beekon.history(new Date(Date.now() - 3600_000), new Date());
125
+ // History (local store; source of truth even when JS was asleep).
126
+ const fixes = await Beekon.getLocations(new Date(Date.now() - 3600_000), new Date());
94
127
 
95
128
  // Cleanup.
96
129
  offState();
97
- offPos();
130
+ offLoc();
98
131
  ```
99
132
 
100
133
  ## API
101
134
 
102
135
  | Method | Description |
103
136
  |---|---|
104
- | `Beekon.init()` | One-time initialization. Idempotent. |
105
- | `Beekon.configure(config)` | Set sampling / Android notification config. |
106
- | `Beekon.start()` | Begin tracking. State `starting` → `tracking`. |
107
- | `Beekon.stop()` | Stop tracking. Idempotent. State `stopped`. |
108
- | `Beekon.shutdown()` | Final teardown. Most apps don't need this. |
109
- | `Beekon.history(from, to)` | Read persisted positions in range. |
110
- | `Beekon.onState(cb)` | Subscribe to state. Returns unsubscribe fn. |
111
- | `Beekon.onPosition(cb)` | Subscribe to gated positions. Returns unsubscribe fn. |
112
-
113
- Errors are thrown as `Error` instances with stable platform-agnostic codes:
114
- `NOT_INITIALISED`, `NOT_CONFIGURED`, `PERMISSION_DENIED`, `LOCATION_SERVICES_DISABLED` (iOS), `NO_GMS_AVAILABLE` (Android), `SERVICE_FAILED`, `INTERNAL_ERROR`.
115
-
116
- ## Storage and retention
117
-
118
- The native SDKs persist every gated position locally (Room on Android, GRDB on iOS) JS is a passive reader. Retention: **TTL 7 days OR most recent 100 K rows**, whichever is smaller; auto-pruned on each write batch.
137
+ | `configure(config)` | Set config. Optional, idempotent. Does not throw. |
138
+ | `start()` | Begin tracking. Never throws observe `onState`. |
139
+ | `stop()` | Stop tracking. Idempotent. Never throws. |
140
+ | `resumeIfNeeded()` | Resume a session active before the app was terminated. |
141
+ | `getLocations(from, to)` | Read persisted fixes in `[from, to]`. Throws `'storage'`. |
142
+ | `deleteLocations(before?)` | Delete fixes at/before `before` (all when omitted). Throws `'storage'`. |
143
+ | `pendingUploadCount()` | Count of fixes not yet uploaded. Throws `'storage'`. |
144
+ | `sync()` | Request an immediate upload (no-op if sync unconfigured). |
145
+ | `setExtras(extras)` | Custom key/value fields sent with every upload. |
146
+ | `addGeofences(geofences)` | Register geofences. Throws `'invalidGeofence'`. |
147
+ | `removeGeofences(ids)` | Unregister geofences by id. |
148
+ | `listGeofences()` | The currently registered geofences. |
149
+ | `onState(cb)` | Subscribe to state. Replay-1. Returns unsubscribe fn. |
150
+ | `onLocation(cb)` | Subscribe to gated fixes. No replay. |
151
+ | `onGeofenceEvent(cb)` | Subscribe to geofence enter/exit. No replay. |
152
+ | `onSyncStatus(cb)` | Subscribe to upload health. Replay-1. |
153
+
154
+ `BeekonState` is a discriminated union on `kind`: `'idle' | 'tracking' | 'stopped'`. The `'stopped'` variant carries `reason: 'user' | 'permissionDenied' | 'locationServicesDisabled' | 'locationUnavailable' | 'system'`.
155
+
156
+ `SyncStatus` is a union on `kind`: `'idle' | 'pending' | 'failed'`; `'failed'` carries `reason: 'auth' | 'rejected'`.
157
+
158
+ `Location` carries `id`, `latitude`, `longitude`, `timestamp`, the nullable `accuracy` / `speed` / `bearing` / `altitude`, plus `quality`, `trigger`, `motion`, `activity` (`null` unless `detectActivity`), and `isMock`. Optional numeric fields are `null` when the OS did not report a value — never `0`.
159
+
160
+ The **only** thrown errors are `BeekonError` instances with `kind: 'storage' | 'invalidGeofence'`. Permission / services / lifecycle problems are not thrown — they surface on `onState` as `stopped(reason)`.
161
+
162
+ ## Storage, retention, and sync
163
+
164
+ The native SDKs persist every gated fix locally (Room on Android, GRDB on iOS) — JS is a passive reader. Retention: **TTL 7 days OR the most recent 100 K rows**, whichever is smaller; auto-pruned on each write batch. With `sync` configured, accepted rows are deleted locally after upload, so `getLocations` / `pendingUploadCount` return only un-uploaded fixes.
119
165
 
120
166
  ## License
121
167
 
@@ -1,7 +1,8 @@
1
1
  buildscript {
2
2
  ext.BeekonRn = [
3
- kotlinVersion: "2.0.21",
4
- minSdkVersion: 24,
3
+ kotlinVersion: "2.1.20",
4
+ // minSdk 26 is required by the native Beekon AAR (io.github.wayqteam:beekon).
5
+ minSdkVersion: 26,
5
6
  compileSdkVersion: 36,
6
7
  targetSdkVersion: 36
7
8
  ]
@@ -33,7 +34,7 @@ apply plugin: "kotlin-android"
33
34
  apply plugin: "com.facebook.react"
34
35
 
35
36
  android {
36
- namespace "com.wayq.beekonrn"
37
+ namespace "in.wayq.beekonrn"
37
38
 
38
39
  compileSdkVersion getExtOrDefault("compileSdkVersion")
39
40
 
@@ -57,8 +58,12 @@ android {
57
58
  }
58
59
 
59
60
  compileOptions {
60
- sourceCompatibility JavaVersion.VERSION_1_8
61
- targetCompatibility JavaVersion.VERSION_1_8
61
+ sourceCompatibility JavaVersion.VERSION_17
62
+ targetCompatibility JavaVersion.VERSION_17
63
+ }
64
+
65
+ kotlinOptions {
66
+ jvmTarget = "17"
62
67
  }
63
68
  }
64
69
 
@@ -72,7 +77,7 @@ dependencies {
72
77
  // Native Beekon SDK — published from beekon-android/ via Maven Central.
73
78
  // Pinned exact in v0.x to avoid surprise breakage; loosen to a range when
74
79
  // the SDK reaches v1 stability.
75
- implementation "io.github.wayqteam:beekon:0.0.1"
80
+ implementation "io.github.wayqteam:beekon:0.0.5"
76
81
  // Kotlin coroutines — required for collecting Beekon's StateFlow/SharedFlow.
77
82
  // Beekon already depends on coroutines transitively, but declaring it here
78
83
  // makes the dependency intent explicit.