@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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../../src/types/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../../src/types/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAEtE;;;;;GAKG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,2DAA2D;IAC3D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mDAAmD;IACnD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB,kDAAkD;IAClD,GAAG,EAAE,MAAM,CAAC;IACZ,wEAAwE;IACxE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,4EAA4E;IAC5E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,8CAA8C;IAC9C,IAAI,EAAE,OAAO,CAAC;IACd;;;;;OAKG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2DAA2D;IAC3D,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAClC;;;OAGG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,qDAAqD;IACrD,IAAI,EAAE,aAAa,CAAC;IACpB,yEAAyE;IACzE,8BAA8B,CAAC,EAAE,MAAM,CAAC;IACxC,8EAA8E;IAC9E,iCAAiC,CAAC,EAAE,MAAM,CAAC;IAC3C,wDAAwD;IACxD,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,sDAAsD;IACtD,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,6EAA6E;IAC7E,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,qEAAqE;IACrE,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,2DAA2D;IAC3D,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAClC;;;;;;;;;;;OAWG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,YAAY,GAAG,WAAW,GAAG,iBAAiB,CAAC;AAE3D;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY;IACvB,6DAA6D;8BAC9C,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,KAAG,WAAW;IAGtD,kEAAkE;qCAEvD,IAAI,CAAC,iBAAiB,EAAE,MAAM,CAAC,KACvC,iBAAiB;CAGZ,CAAC"}
|
|
@@ -59,4 +59,12 @@ export type AuthStrategy = 'bearer' | 'raw';
|
|
|
59
59
|
* - `'json'` — `application/json`.
|
|
60
60
|
*/
|
|
61
61
|
export type AuthBodyFormat = 'form' | 'json';
|
|
62
|
+
/**
|
|
63
|
+
* Diagnostic log verbosity threshold. Ordered by increasing verbosity; an entry
|
|
64
|
+
* is recorded only when its level is at or below the active threshold
|
|
65
|
+
* ({@link BeekonConfig.logLevel} or {@link Beekon.setLogLevel}). The default is
|
|
66
|
+
* `'info'`, so coordinates (logged only at `'debug'`/`'verbose'`) stay out of the
|
|
67
|
+
* buffer. Mirrors the native `LogLevel`; see `spec/diagnostics/log-format-v1`.
|
|
68
|
+
*/
|
|
69
|
+
export type LogLevel = 'off' | 'error' | 'warn' | 'info' | 'debug' | 'verbose';
|
|
62
70
|
//# sourceMappingURL=enums.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enums.d.ts","sourceRoot":"","sources":["../../../../src/types/enums.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;GAMG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,UAAU,GAAG,KAAK,CAAC;AAEvD;;;;;;;GAOG;AACH,MAAM,MAAM,cAAc,GAAG,cAAc,GAAG,OAAO,GAAG,mBAAmB,CAAC;AAE5E;;;;;;;;GAQG;AACH,MAAM,MAAM,eAAe,GACvB,UAAU,GACV,QAAQ,GACR,SAAS,GACT,UAAU,GACV,QAAQ,CAAC;AAEb;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG,IAAI,GAAG,aAAa,GAAG,kBAAkB,CAAC;AAExE,0DAA0D;AAC1D,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,YAAY,GAAG,SAAS,CAAC;AAE9D;;;GAGG;AACH,MAAM,MAAM,YAAY,GACpB,YAAY,GACZ,SAAS,GACT,SAAS,GACT,SAAS,GACT,YAAY,GACZ,SAAS,CAAC;AAEd;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,KAAK,CAAC;AAE5C;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,MAAM,CAAC"}
|
|
1
|
+
{"version":3,"file":"enums.d.ts","sourceRoot":"","sources":["../../../../src/types/enums.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;GAMG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,UAAU,GAAG,KAAK,CAAC;AAEvD;;;;;;;GAOG;AACH,MAAM,MAAM,cAAc,GAAG,cAAc,GAAG,OAAO,GAAG,mBAAmB,CAAC;AAE5E;;;;;;;;GAQG;AACH,MAAM,MAAM,eAAe,GACvB,UAAU,GACV,QAAQ,GACR,SAAS,GACT,UAAU,GACV,QAAQ,CAAC;AAEb;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG,IAAI,GAAG,aAAa,GAAG,kBAAkB,CAAC;AAExE,0DAA0D;AAC1D,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,YAAY,GAAG,SAAS,CAAC;AAE9D;;;GAGG;AACH,MAAM,MAAM,YAAY,GACpB,YAAY,GACZ,SAAS,GACT,SAAS,GACT,SAAS,GACT,YAAY,GACZ,SAAS,CAAC;AAEd;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,KAAK,CAAC;AAE5C;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,MAAM,CAAC;AAE7C;;;;;;GAMG;AACH,MAAM,MAAM,QAAQ,GAAG,KAAK,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { LogLevel } from './enums';
|
|
2
|
+
/**
|
|
3
|
+
* A single diagnostic log record from the Beekon SDK.
|
|
4
|
+
*
|
|
5
|
+
* Delivered live on {@link Beekon.onLog} and read back from the persisted ring
|
|
6
|
+
* buffer via {@link Beekon.getLog}. Entries survive process death — the point of
|
|
7
|
+
* the buffer is post-hoc field diagnosis. Mirrors the native `LogEntry`; see
|
|
8
|
+
* `spec/diagnostics/log-format-v1`.
|
|
9
|
+
*/
|
|
10
|
+
export type LogEntry = {
|
|
11
|
+
/** UUIDv7 — orders and dedups entries. */
|
|
12
|
+
id: string;
|
|
13
|
+
/** When the entry was recorded. */
|
|
14
|
+
timestamp: Date;
|
|
15
|
+
/** Severity. Always one of `'error'`…`'verbose'`. */
|
|
16
|
+
level: LogLevel;
|
|
17
|
+
/** Originating subsystem (e.g. `'location'`, `'sync'`); host breadcrumbs use `'app'`. */
|
|
18
|
+
category: string;
|
|
19
|
+
/** Human-readable, already-redacted text. */
|
|
20
|
+
message: string;
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=log.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../../../../src/types/log.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC;;;;;;;GAOG;AACH,MAAM,MAAM,QAAQ,GAAG;IACrB,0CAA0C;IAC1C,EAAE,EAAE,MAAM,CAAC;IACX,mCAAmC;IACnC,SAAS,EAAE,IAAI,CAAC;IAChB,qDAAqD;IACrD,KAAK,EAAE,QAAQ,CAAC;IAChB,yFAAyF;IACzF,QAAQ,EAAE,MAAM,CAAC;IACjB,6CAA6C;IAC7C,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How far the host app's location grant reaches. Mirrors the native
|
|
3
|
+
* `PermissionStatus` level on both platforms.
|
|
4
|
+
*
|
|
5
|
+
* Normalized — not platform permission constants. `'restricted'` is **iOS-only**
|
|
6
|
+
* (MDM / Screen Time); on Android "not yet asked" and "denied" cannot be told
|
|
7
|
+
* apart without an `Activity`, so both report `'notDetermined'`.
|
|
8
|
+
*
|
|
9
|
+
* - `'notDetermined'` — not yet decided; request to proceed.
|
|
10
|
+
* - `'denied'` — the user denied access (iOS). User-fixable in Settings.
|
|
11
|
+
* - `'restricted'` — blocked by an unchangeable policy (iOS-only).
|
|
12
|
+
* - `'foreground'` — granted while in use; foreground tracking only.
|
|
13
|
+
* - `'background'` — granted at all times; background tracking works.
|
|
14
|
+
*/
|
|
15
|
+
export type PermissionLevel = 'notDetermined' | 'denied' | 'restricted' | 'foreground' | 'background';
|
|
16
|
+
/**
|
|
17
|
+
* Precision of a granted location authorization. `null` unless granted.
|
|
18
|
+
*
|
|
19
|
+
* - `'full'` — precise location.
|
|
20
|
+
* - `'reduced'` — approximate only (iOS 14 / Android 12 "approximate").
|
|
21
|
+
*/
|
|
22
|
+
export type PermissionAccuracy = 'full' | 'reduced';
|
|
23
|
+
/**
|
|
24
|
+
* A point-in-time snapshot of the location-permission grant, returned by
|
|
25
|
+
* `Beekon.getPermissionStatus()`. Mirrors the native `PermissionStatus`.
|
|
26
|
+
*
|
|
27
|
+
* Beekon never *requests* permission — the app owns that. This is a read-only
|
|
28
|
+
* query for pre-start checks; it never prompts. It is a snapshot, not an
|
|
29
|
+
* observer: once tracking is running, permission loss surfaces on the `onState`
|
|
30
|
+
* stream as `{ kind: 'stopped', reason: 'permissionDenied' }`.
|
|
31
|
+
*/
|
|
32
|
+
export type PermissionStatus = {
|
|
33
|
+
/** How far the grant reaches. */
|
|
34
|
+
level: PermissionLevel;
|
|
35
|
+
/** Precision of the grant, or `null` when not authorized. */
|
|
36
|
+
accuracy: PermissionAccuracy | null;
|
|
37
|
+
/** `true` when authorized at all — foreground or background. */
|
|
38
|
+
isAuthorized: boolean;
|
|
39
|
+
/** `true` when background tracking is authorized. */
|
|
40
|
+
canTrackInBackground: boolean;
|
|
41
|
+
};
|
|
42
|
+
//# sourceMappingURL=permission.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permission.d.ts","sourceRoot":"","sources":["../../../../src/types/permission.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,eAAe,GACvB,eAAe,GACf,QAAQ,GACR,YAAY,GACZ,YAAY,GACZ,YAAY,CAAC;AAEjB;;;;;GAKG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,SAAS,CAAC;AAEpD;;;;;;;;GAQG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,iCAAiC;IACjC,KAAK,EAAE,eAAe,CAAC;IACvB,6DAA6D;IAC7D,QAAQ,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACpC,gEAAgE;IAChE,YAAY,EAAE,OAAO,CAAC;IACtB,qDAAqD;IACrD,oBAAoB,EAAE,OAAO,CAAC;CAC/B,CAAC"}
|
|
@@ -8,10 +8,13 @@
|
|
|
8
8
|
* (user-fixable in Settings).
|
|
9
9
|
* - `'locationUnavailable'` — no usable location backend on this device (e.g.
|
|
10
10
|
* Google Play Services absent/outdated on Android). Not user-fixable.
|
|
11
|
+
* - `'cloudModeUnavailable'` — the SDK was configured for cloud mode but the
|
|
12
|
+
* running build cannot operate it (cloud-mode-v1). Not user-fixable; switch to
|
|
13
|
+
* a self-managed config or a cloud-capable SDK build.
|
|
11
14
|
* - `'system'` — the OS terminated tracking (e.g. foreground-service kill,
|
|
12
15
|
* or an unrecoverable internal error).
|
|
13
16
|
*/
|
|
14
|
-
export type StopReason = 'user' | 'permissionDenied' | 'locationServicesDisabled' | 'locationUnavailable' | 'system';
|
|
17
|
+
export type StopReason = 'user' | 'permissionDenied' | 'locationServicesDisabled' | 'locationUnavailable' | 'cloudModeUnavailable' | 'system';
|
|
15
18
|
/**
|
|
16
19
|
* Tracking state. Mirrors the native `BeekonState` sealed type on both
|
|
17
20
|
* platforms. Use the `kind` field as a discriminator.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../../src/types/state.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../../src/types/state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,UAAU,GAClB,MAAM,GACN,kBAAkB,GAClB,0BAA0B,GAC1B,qBAAqB,GACrB,sBAAsB,GACtB,QAAQ,CAAC;AAEb;;;;;;;GAOG;AACH,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GACpB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,UAAU,CAAA;CAAE,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wayq/beekon-rn",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "React Native binding for the Beekon location SDK (Android + iOS).",
|
|
5
5
|
"main": "./lib/module/index.js",
|
|
6
6
|
"types": "./lib/typescript/src/index.d.ts",
|
|
@@ -58,14 +58,14 @@
|
|
|
58
58
|
],
|
|
59
59
|
"repository": {
|
|
60
60
|
"type": "git",
|
|
61
|
-
"url": "git+https://github.com/
|
|
61
|
+
"url": "git+https://github.com/beekonlabs/beekon-rn.git"
|
|
62
62
|
},
|
|
63
|
-
"author": "
|
|
63
|
+
"author": "beekonlabs <beekonlabs@users.noreply.github.com> (https://github.com/beekonlabs)",
|
|
64
64
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
65
65
|
"bugs": {
|
|
66
|
-
"url": "https://github.com/
|
|
66
|
+
"url": "https://github.com/beekonlabs/beekon-rn/issues"
|
|
67
67
|
},
|
|
68
|
-
"homepage": "https://github.com/
|
|
68
|
+
"homepage": "https://github.com/beekonlabs/beekon-rn#readme",
|
|
69
69
|
"publishConfig": {
|
|
70
70
|
"registry": "https://registry.npmjs.org/",
|
|
71
71
|
"access": "public"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# Fetches BeekonKit.xcframework from
|
|
2
|
+
# Fetches BeekonKit.xcframework from beekonlabs/beekon-ios-binary's GitHub
|
|
3
3
|
# Release at the pinned version, verifies SHA256, and extracts it into
|
|
4
4
|
# ios/Frameworks/. Idempotent: skips if the framework is already present.
|
|
5
5
|
#
|
|
@@ -13,12 +13,12 @@
|
|
|
13
13
|
|
|
14
14
|
set -euo pipefail
|
|
15
15
|
|
|
16
|
-
VERSION="0.0
|
|
17
|
-
URL="https://github.com/
|
|
18
|
-
# SHA256 of the v0.0.
|
|
19
|
-
# `binaryTarget` checksum in beekon-ios-binary's Package.swift at tag v0.0.
|
|
16
|
+
VERSION="0.1.0"
|
|
17
|
+
URL="https://github.com/beekonlabs/beekon-ios-binary/releases/download/v${VERSION}/BeekonKit.xcframework.zip"
|
|
18
|
+
# SHA256 of the v0.0.9 BeekonKit.xcframework.zip. Matches the SwiftPM
|
|
19
|
+
# `binaryTarget` checksum in beekon-ios-binary's Package.swift at tag v0.0.9
|
|
20
20
|
# (SwiftPM's compute-checksum is the SHA256 of the zip).
|
|
21
|
-
EXPECTED_SHA="
|
|
21
|
+
EXPECTED_SHA="8a39d9360a05f117226381036a10d3cfeb71237f99fd8d800cfafda42d9657f2"
|
|
22
22
|
|
|
23
23
|
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
24
24
|
DEST_DIR="${ROOT}/ios/Frameworks"
|
package/src/NativeBeekonRn.ts
CHANGED
|
@@ -59,6 +59,7 @@ export type WireSyncConfig = {
|
|
|
59
59
|
headers: WireKeyValue[];
|
|
60
60
|
intervalSeconds: number;
|
|
61
61
|
batchSize: number;
|
|
62
|
+
syncThreshold: number;
|
|
62
63
|
/** Token-refresh recipe; omitted keeps static-header auth. */
|
|
63
64
|
auth?: WireAuthConfig;
|
|
64
65
|
};
|
|
@@ -71,7 +72,27 @@ export type WireNotificationConfig = {
|
|
|
71
72
|
};
|
|
72
73
|
|
|
73
74
|
export type WireConfig = {
|
|
74
|
-
/**
|
|
75
|
+
/**
|
|
76
|
+
* Configuration-ownership discriminator (cloud-mode-v1 §2). One of: 'cloud' |
|
|
77
|
+
* 'selfManaged'. The native side switches on this to build the matching arm of
|
|
78
|
+
* the sealed `BeekonConfig`.
|
|
79
|
+
*/
|
|
80
|
+
mode: string;
|
|
81
|
+
/**
|
|
82
|
+
* Cloud arm only: the opaque project credential (`bkproj_…`). Omitted/empty for
|
|
83
|
+
* the self-managed arm; the native cloud arm trims it and rejects an empty key.
|
|
84
|
+
*/
|
|
85
|
+
projectKey?: string;
|
|
86
|
+
/**
|
|
87
|
+
* Cloud arm only: base-URL override. Omitted means the native baked-in default
|
|
88
|
+
* (`https://api.getbeekon.com`). Ignored by the self-managed arm.
|
|
89
|
+
*/
|
|
90
|
+
endpoint?: string;
|
|
91
|
+
/**
|
|
92
|
+
* Self-managed arm only (ignored by the cloud arm, which derives tracking
|
|
93
|
+
* config from the server). All fields required at the wire level — the TS
|
|
94
|
+
* facade applies defaults.
|
|
95
|
+
*/
|
|
75
96
|
minTimeBetweenLocationsSeconds: number;
|
|
76
97
|
minDistanceBetweenLocationsMeters: number;
|
|
77
98
|
/** One of: 'high' | 'balanced' | 'low'. */
|
|
@@ -91,6 +112,20 @@ export type WireConfig = {
|
|
|
91
112
|
* object, so this field documents the shape rather than altering codegen.
|
|
92
113
|
*/
|
|
93
114
|
licenseKey?: string;
|
|
115
|
+
/**
|
|
116
|
+
* Diagnostic log verbosity threshold (spec `diagnostics/log-format-v1` §1).
|
|
117
|
+
* One of: 'off' | 'error' | 'warn' | 'info' | 'debug' | 'verbose'.
|
|
118
|
+
*/
|
|
119
|
+
logLevel: string;
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
export type WireLogEntry = {
|
|
123
|
+
id: string;
|
|
124
|
+
timestampMs: number;
|
|
125
|
+
/** One of: 'error' | 'warn' | 'info' | 'debug' | 'verbose'. */
|
|
126
|
+
level: string;
|
|
127
|
+
category: string;
|
|
128
|
+
message: string;
|
|
94
129
|
};
|
|
95
130
|
|
|
96
131
|
export type WireLocation = {
|
|
@@ -137,7 +172,7 @@ export type WireState = {
|
|
|
137
172
|
/**
|
|
138
173
|
* Only populated when `type === 'stopped'`. One of: 'user' |
|
|
139
174
|
* 'permissionDenied' | 'locationServicesDisabled' | 'locationUnavailable' |
|
|
140
|
-
* 'system'.
|
|
175
|
+
* 'cloudModeUnavailable' | 'system'.
|
|
141
176
|
*/
|
|
142
177
|
stopReason?: string;
|
|
143
178
|
};
|
|
@@ -183,6 +218,21 @@ export type WireLicenseStatus = {
|
|
|
183
218
|
reason: string | null;
|
|
184
219
|
};
|
|
185
220
|
|
|
221
|
+
/**
|
|
222
|
+
* Flat wire form of the current location-permission grant (read-only). `level`
|
|
223
|
+
* is the wire-stable identifier; `accuracy` is `''` (not null — Codegen has no
|
|
224
|
+
* portable nullable-enum) when location is not granted, else 'full' | 'reduced'.
|
|
225
|
+
*/
|
|
226
|
+
export type WirePermissionStatus = {
|
|
227
|
+
/**
|
|
228
|
+
* One of: 'notDetermined' | 'denied' | 'restricted' | 'foreground' |
|
|
229
|
+
* 'background'.
|
|
230
|
+
*/
|
|
231
|
+
level: string;
|
|
232
|
+
/** 'full' | 'reduced', or '' when not granted. */
|
|
233
|
+
accuracy: string;
|
|
234
|
+
};
|
|
235
|
+
|
|
186
236
|
export interface Spec extends TurboModule {
|
|
187
237
|
/**
|
|
188
238
|
* The config crosses as an untyped object (`ReadableMap` on Android,
|
|
@@ -232,12 +282,30 @@ export interface Spec extends TurboModule {
|
|
|
232
282
|
*/
|
|
233
283
|
licenseStatus(): Promise<WireLicenseStatus>;
|
|
234
284
|
|
|
285
|
+
/**
|
|
286
|
+
* The current location-permission grant (read-only; never prompts). For
|
|
287
|
+
* pre-start checks — during tracking, permission loss surfaces on `onState`.
|
|
288
|
+
*/
|
|
289
|
+
getPermissionStatus(): Promise<WirePermissionStatus>;
|
|
290
|
+
|
|
291
|
+
/** Persisted diagnostic log entries in `[fromMs, toMs]`, oldest first. */
|
|
292
|
+
getLog(fromMs: number, toMs: number): Promise<WireLogEntry[]>;
|
|
293
|
+
/** Serialize the whole log buffer to an NDJSON file; resolves its path. */
|
|
294
|
+
exportLog(): Promise<string>;
|
|
295
|
+
/** Delete all persisted diagnostic log entries. */
|
|
296
|
+
clearLog(): Promise<void>;
|
|
297
|
+
/** Set the diagnostic log threshold at runtime. */
|
|
298
|
+
setLogLevel(level: string): Promise<void>;
|
|
299
|
+
/** Write a host-app breadcrumb (category `app`) into the log pipeline. */
|
|
300
|
+
log(level: string, message: string): Promise<void>;
|
|
301
|
+
|
|
235
302
|
readonly onState: CodegenTypes.EventEmitter<WireState>;
|
|
236
303
|
readonly onLocation: CodegenTypes.EventEmitter<WireLocation>;
|
|
237
304
|
readonly onGeofenceEvent: CodegenTypes.EventEmitter<WireGeofenceEvent>;
|
|
238
305
|
readonly onSyncStatus: CodegenTypes.EventEmitter<WireSyncStatus>;
|
|
239
306
|
readonly onAuthTokens: CodegenTypes.EventEmitter<WireAuthTokens>;
|
|
240
307
|
readonly onLicenseStatus: CodegenTypes.EventEmitter<WireLicenseStatus>;
|
|
308
|
+
readonly onLog: CodegenTypes.EventEmitter<WireLogEntry>;
|
|
241
309
|
}
|
|
242
310
|
|
|
243
311
|
export default TurboModuleRegistry.getEnforcing<Spec>('BeekonRn');
|
package/src/beekon.ts
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import NativeBeekon from './NativeBeekonRn';
|
|
2
|
+
import { LicenseNudge } from './internal/licenseNudge';
|
|
2
3
|
import type { AuthTokens } from './types/auth';
|
|
3
4
|
import type { BeekonConfig } from './types/config';
|
|
4
|
-
import type { AccuracyMode } from './types/enums';
|
|
5
|
+
import type { AccuracyMode, LogLevel } from './types/enums';
|
|
5
6
|
import type { BeekonGeofence, GeofenceEvent } from './types/geofence';
|
|
6
7
|
import type { LicenseStatus } from './types/license';
|
|
7
8
|
import type { Location } from './types/location';
|
|
9
|
+
import type { LogEntry } from './types/log';
|
|
10
|
+
import type { PermissionStatus } from './types/permission';
|
|
8
11
|
import type { BeekonState } from './types/state';
|
|
9
12
|
import type { SyncStatus } from './types/sync';
|
|
10
13
|
import {
|
|
@@ -17,6 +20,8 @@ import {
|
|
|
17
20
|
wireToGeofenceEvent,
|
|
18
21
|
wireToLicenseStatus,
|
|
19
22
|
wireToLocation,
|
|
23
|
+
wireToLogEntry,
|
|
24
|
+
wireToPermissionStatus,
|
|
20
25
|
wireToState,
|
|
21
26
|
wireToSyncStatus,
|
|
22
27
|
} from './internal/mappers';
|
|
@@ -42,6 +47,7 @@ class EventHub {
|
|
|
42
47
|
private readonly syncListeners = new Set<Listener<SyncStatus>>();
|
|
43
48
|
private readonly authTokenListeners = new Set<Listener<AuthTokens>>();
|
|
44
49
|
private readonly licenseListeners = new Set<Listener<LicenseStatus>>();
|
|
50
|
+
private readonly logListeners = new Set<Listener<LogEntry>>();
|
|
45
51
|
private lastState: BeekonState | undefined;
|
|
46
52
|
private lastSyncStatus: SyncStatus | undefined;
|
|
47
53
|
private lastAuthTokens: AuthTokens | undefined;
|
|
@@ -79,6 +85,10 @@ class EventHub {
|
|
|
79
85
|
this.lastLicenseStatus = s;
|
|
80
86
|
this.licenseListeners.forEach((cb) => cb(s));
|
|
81
87
|
});
|
|
88
|
+
NativeBeekon.onLog((w) => {
|
|
89
|
+
const e = wireToLogEntry(w);
|
|
90
|
+
this.logListeners.forEach((cb) => cb(e));
|
|
91
|
+
});
|
|
82
92
|
}
|
|
83
93
|
|
|
84
94
|
onState(cb: Listener<BeekonState>): () => void {
|
|
@@ -132,6 +142,14 @@ class EventHub {
|
|
|
132
142
|
this.licenseListeners.delete(cb);
|
|
133
143
|
};
|
|
134
144
|
}
|
|
145
|
+
|
|
146
|
+
onLog(cb: Listener<LogEntry>): () => void {
|
|
147
|
+
this.ensureSubscribed();
|
|
148
|
+
this.logListeners.add(cb);
|
|
149
|
+
return () => {
|
|
150
|
+
this.logListeners.delete(cb);
|
|
151
|
+
};
|
|
152
|
+
}
|
|
135
153
|
}
|
|
136
154
|
|
|
137
155
|
/**
|
|
@@ -154,6 +172,20 @@ class EventHub {
|
|
|
154
172
|
*/
|
|
155
173
|
class BeekonImpl {
|
|
156
174
|
private readonly hub = new EventHub();
|
|
175
|
+
private readonly licenseNudge = new LicenseNudge();
|
|
176
|
+
private licenseNudgeAttached = false;
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Echo the evaluation-mode nudge to the JS console once, on first lifecycle
|
|
180
|
+
* use — so it only activates for apps actually using the SDK. Metro shows JS
|
|
181
|
+
* console only, so this is how the native nudge reaches an RN dev. See
|
|
182
|
+
* {@link LicenseNudge}.
|
|
183
|
+
*/
|
|
184
|
+
private activateLicenseNudge(): void {
|
|
185
|
+
if (this.licenseNudgeAttached) return;
|
|
186
|
+
this.licenseNudgeAttached = true;
|
|
187
|
+
this.licenseNudge.attach((cb) => this.hub.onLicenseStatus(cb));
|
|
188
|
+
}
|
|
157
189
|
|
|
158
190
|
/**
|
|
159
191
|
* Set tracking parameters. Optional — `start()` falls back to the previously
|
|
@@ -163,6 +195,7 @@ class BeekonImpl {
|
|
|
163
195
|
*/
|
|
164
196
|
async configure(config: BeekonConfig): Promise<void> {
|
|
165
197
|
this.hub.ensureSubscribed();
|
|
198
|
+
this.activateLicenseNudge();
|
|
166
199
|
await NativeBeekon.configure(configToWire(config));
|
|
167
200
|
}
|
|
168
201
|
|
|
@@ -174,6 +207,7 @@ class BeekonImpl {
|
|
|
174
207
|
*/
|
|
175
208
|
async start(): Promise<void> {
|
|
176
209
|
this.hub.ensureSubscribed();
|
|
210
|
+
this.activateLicenseNudge();
|
|
177
211
|
await NativeBeekon.start();
|
|
178
212
|
}
|
|
179
213
|
|
|
@@ -194,6 +228,7 @@ class BeekonImpl {
|
|
|
194
228
|
*/
|
|
195
229
|
async resumeIfNeeded(): Promise<void> {
|
|
196
230
|
this.hub.ensureSubscribed();
|
|
231
|
+
this.activateLicenseNudge();
|
|
197
232
|
await NativeBeekon.resumeIfNeeded();
|
|
198
233
|
}
|
|
199
234
|
|
|
@@ -321,6 +356,75 @@ class BeekonImpl {
|
|
|
321
356
|
return wireToLicenseStatus(await NativeBeekon.licenseStatus());
|
|
322
357
|
}
|
|
323
358
|
|
|
359
|
+
/**
|
|
360
|
+
* The current location-permission grant — a point-in-time read for
|
|
361
|
+
* **pre-start** checks, returned without ever prompting. Beekon never requests
|
|
362
|
+
* permission; the app owns that. A snapshot, not an observer: once tracking is
|
|
363
|
+
* running, permission loss surfaces on `onState` as
|
|
364
|
+
* `{ kind: 'stopped', reason: 'permissionDenied' }`. On Android, "not yet
|
|
365
|
+
* asked" and "denied" both report `'notDetermined'`; `'restricted'` is iOS-only.
|
|
366
|
+
*/
|
|
367
|
+
async getPermissionStatus(): Promise<PermissionStatus> {
|
|
368
|
+
return wireToPermissionStatus(await NativeBeekon.getPermissionStatus());
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* Read persisted diagnostic log entries in the inclusive range `[from, to]`,
|
|
373
|
+
* oldest first. Entries survive process death, so this recovers what the SDK
|
|
374
|
+
* did during a background session — the key to diagnosing field issues. Throws
|
|
375
|
+
* `BeekonError` with kind `'storage'` on a read failure. Requires native ≥ 0.0.9.
|
|
376
|
+
*/
|
|
377
|
+
async getLog(from: Date, to: Date): Promise<LogEntry[]> {
|
|
378
|
+
try {
|
|
379
|
+
const wires = await NativeBeekon.getLog(from.getTime(), to.getTime());
|
|
380
|
+
return wires.map(wireToLogEntry);
|
|
381
|
+
} catch (e) {
|
|
382
|
+
rethrowAsBeekonError(e);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
* Serialize the whole diagnostic log buffer to an NDJSON file and resolve its
|
|
388
|
+
* path. The app owns the file — attach it to a support email, share it, or
|
|
389
|
+
* upload it. Throws `BeekonError` with kind `'storage'` on a failure. Requires
|
|
390
|
+
* native ≥ 0.0.9.
|
|
391
|
+
*/
|
|
392
|
+
async exportLog(): Promise<string> {
|
|
393
|
+
try {
|
|
394
|
+
return await NativeBeekon.exportLog();
|
|
395
|
+
} catch (e) {
|
|
396
|
+
rethrowAsBeekonError(e);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
/** Delete all persisted diagnostic log entries. Requires native ≥ 0.0.9. */
|
|
401
|
+
async clearLog(): Promise<void> {
|
|
402
|
+
try {
|
|
403
|
+
await NativeBeekon.clearLog();
|
|
404
|
+
} catch (e) {
|
|
405
|
+
rethrowAsBeekonError(e);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* Set the diagnostic log verbosity threshold at runtime — no restart needed.
|
|
411
|
+
* Raise to `'debug'`/`'verbose'` for field diagnosis, then lower again. A later
|
|
412
|
+
* `configure` re-applies `BeekonConfig.logLevel` and supersedes this. Requires
|
|
413
|
+
* native ≥ 0.0.9.
|
|
414
|
+
*/
|
|
415
|
+
async setLogLevel(level: LogLevel): Promise<void> {
|
|
416
|
+
await NativeBeekon.setLogLevel(level);
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* Write a host-app breadcrumb into the same pipeline as the SDK's own logs
|
|
421
|
+
* (category `app`), so app and SDK events interleave in one timeline. Requires
|
|
422
|
+
* native ≥ 0.0.9.
|
|
423
|
+
*/
|
|
424
|
+
async log(level: LogLevel, message: string): Promise<void> {
|
|
425
|
+
await NativeBeekon.log(level, message);
|
|
426
|
+
}
|
|
427
|
+
|
|
324
428
|
/**
|
|
325
429
|
* Subscribe to tracking-state transitions (`idle` / `tracking` /
|
|
326
430
|
* `stopped(reason)`). The current state is delivered to new subscribers
|
|
@@ -375,6 +479,15 @@ class BeekonImpl {
|
|
|
375
479
|
onLicenseStatus(cb: (s: LicenseStatus) => void): () => void {
|
|
376
480
|
return this.hub.onLicenseStatus(cb);
|
|
377
481
|
}
|
|
482
|
+
|
|
483
|
+
/**
|
|
484
|
+
* Subscribe to diagnostic log entries as they are recorded — SDK subsystems
|
|
485
|
+
* plus host breadcrumbs from {@link log}. Broadcast (no replay); read history
|
|
486
|
+
* with {@link getLog}. Returns an unsubscribe function. Requires native ≥ 0.0.9.
|
|
487
|
+
*/
|
|
488
|
+
onLog(cb: (e: LogEntry) => void): () => void {
|
|
489
|
+
return this.hub.onLog(cb);
|
|
490
|
+
}
|
|
378
491
|
}
|
|
379
492
|
|
|
380
493
|
export const Beekon = new BeekonImpl();
|
package/src/index.tsx
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
export { Beekon } from './beekon';
|
|
2
2
|
|
|
3
|
+
// `BeekonConfig` is a merged type + value (the `cloud` / `selfManaged`
|
|
4
|
+
// factories), so it is a value export — its type meaning travels with it.
|
|
5
|
+
export { BeekonConfig } from './types/config';
|
|
3
6
|
export type {
|
|
4
|
-
|
|
7
|
+
CloudConfig,
|
|
8
|
+
SelfManagedConfig,
|
|
5
9
|
SyncConfig,
|
|
6
10
|
NotificationConfig,
|
|
7
11
|
} from './types/config';
|
|
@@ -14,7 +18,9 @@ export type {
|
|
|
14
18
|
ActivityType,
|
|
15
19
|
AuthStrategy,
|
|
16
20
|
AuthBodyFormat,
|
|
21
|
+
LogLevel,
|
|
17
22
|
} from './types/enums';
|
|
23
|
+
export type { LogEntry } from './types/log';
|
|
18
24
|
export type { AuthConfig, AuthResponseMapping, AuthTokens } from './types/auth';
|
|
19
25
|
export type { Location } from './types/location';
|
|
20
26
|
export type {
|
|
@@ -23,6 +29,11 @@ export type {
|
|
|
23
29
|
Transition,
|
|
24
30
|
} from './types/geofence';
|
|
25
31
|
export type { BeekonState, StopReason } from './types/state';
|
|
32
|
+
export type {
|
|
33
|
+
PermissionStatus,
|
|
34
|
+
PermissionLevel,
|
|
35
|
+
PermissionAccuracy,
|
|
36
|
+
} from './types/permission';
|
|
26
37
|
export type { SyncStatus, SyncFailure } from './types/sync';
|
|
27
38
|
export type { LicenseStatus, LicenseInvalidReason } from './types/license';
|
|
28
39
|
export { BeekonError, type BeekonErrorKind } from './types/error';
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { LicenseStatus } from '../types/license';
|
|
2
|
+
|
|
3
|
+
// The debug nudge: a prominent multi-line banner mirroring the native debug
|
|
4
|
+
// banner. Every line carries the prefix (greppability). Neutral by design — no
|
|
5
|
+
// "release is unaffected", no advertised opt-out — so it nudges toward a key.
|
|
6
|
+
const BANNER = [
|
|
7
|
+
'[Beekon][license] ════════════════════════════════════════════════════',
|
|
8
|
+
'[Beekon][license] Beekon is running without a license key.',
|
|
9
|
+
'[Beekon][license] Get one: https://getbeekon.com/pricing',
|
|
10
|
+
'[Beekon][license] Then add it via BeekonConfig.licenseKey.',
|
|
11
|
+
'[Beekon][license] ════════════════════════════════════════════════════',
|
|
12
|
+
].join('\n');
|
|
13
|
+
|
|
14
|
+
function isDev(): boolean {
|
|
15
|
+
const g = globalThis as { __DEV__?: boolean };
|
|
16
|
+
return g.__DEV__ === true;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function acknowledged(): boolean {
|
|
20
|
+
const g = globalThis as { BEEKON_EVALUATION_MODE?: boolean };
|
|
21
|
+
return g.BEEKON_EVALUATION_MODE === true;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function defaultLog(message: string): void {
|
|
25
|
+
// The dev-console nudge: Metro surfaces JS console output, not native logs.
|
|
26
|
+
console.warn(message);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Echoes the evaluation-mode license nudge into the JS console.
|
|
31
|
+
*
|
|
32
|
+
* The native SDKs log the license notice to the platform stream (iOS unified
|
|
33
|
+
* logging, Android Logcat), but Metro shows only JS `console.*` — neither native
|
|
34
|
+
* stream reaches it, so a React Native developer never sees the "you're
|
|
35
|
+
* unlicensed" nudge in the terminal they actually watch. This mirrors the
|
|
36
|
+
* **evaluation** notice (no key supplied) onto `console.warn` so it surfaces in
|
|
37
|
+
* Metro, on **both** platforms.
|
|
38
|
+
*
|
|
39
|
+
* Debug-only (`__DEV__`): a release bundle never console-warns. Fires **at most
|
|
40
|
+
* once per JS context** on the first `evaluation` status, mirroring the native
|
|
41
|
+
* once-per-transition guarantee. Purely a log line — it never blocks, degrades,
|
|
42
|
+
* or delays the SDK (license-format-v1 policy anchor).
|
|
43
|
+
*
|
|
44
|
+
* Silence it without a key by setting `globalThis.BEEKON_EVALUATION_MODE = true`
|
|
45
|
+
* before the SDK initializes — the JS analog of the native `BeekonEvaluationMode`
|
|
46
|
+
* plist / `in.wayq.beekon.evaluationMode` manifest acknowledgment.
|
|
47
|
+
*/
|
|
48
|
+
export class LicenseNudge {
|
|
49
|
+
private emitted = false;
|
|
50
|
+
private unsubscribe: (() => void) | undefined;
|
|
51
|
+
private readonly log: (message: string) => void;
|
|
52
|
+
private readonly enabled: boolean;
|
|
53
|
+
|
|
54
|
+
constructor(options?: {
|
|
55
|
+
log?: (message: string) => void;
|
|
56
|
+
enabled?: boolean;
|
|
57
|
+
}) {
|
|
58
|
+
this.log = options?.log ?? defaultLog;
|
|
59
|
+
this.enabled = options?.enabled ?? (isDev() && !acknowledged());
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Subscribe via [subscribe] — a replay-1 license-status subscription that
|
|
64
|
+
* returns an unsubscribe function — and emit the banner the first time the
|
|
65
|
+
* status is `evaluation`. A no-op when disabled; idempotent.
|
|
66
|
+
*/
|
|
67
|
+
attach(subscribe: (cb: (status: LicenseStatus) => void) => () => void): void {
|
|
68
|
+
if (!this.enabled || this.unsubscribe !== undefined) return;
|
|
69
|
+
this.unsubscribe = subscribe((status) => this.onStatus(status));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
private onStatus(status: LicenseStatus): void {
|
|
73
|
+
if (this.emitted || status.status !== 'evaluation') return;
|
|
74
|
+
this.emitted = true;
|
|
75
|
+
this.log(BANNER);
|
|
76
|
+
// One-shot per process — drop the subscription once nudged.
|
|
77
|
+
this.unsubscribe?.();
|
|
78
|
+
this.unsubscribe = undefined;
|
|
79
|
+
}
|
|
80
|
+
}
|