expo-beacon 0.6.19 → 0.6.20

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/README.md CHANGED
@@ -52,6 +52,9 @@ An Expo module for scanning, pairing, and monitoring **iBeacons** and **Eddyston
52
52
  - [getPairedEddystones()](#getpairededdystones)
53
53
  - [startMonitoring()](#startmonitoringoptions)
54
54
  - [stopMonitoring()](#stopmonitoring)
55
+ - [getMonitoringConfig()](#getmonitoringconfig)
56
+ - [getMonitoredDeviceState()](#getmonitoreddevicestateidentifier)
57
+ - [getMonitoredDeviceStates()](#getmonitoreddevicestates)
55
58
  - [setNotificationConfig()](#setnotificationconfigconfig)
56
59
  - [enableEventLogging()](#enableeventlogging)
57
60
  - [disableEventLogging()](#disableeventlogging)
@@ -1001,6 +1004,76 @@ await ExpoBeacon.stopMonitoring();
1001
1004
 
1002
1005
  ---
1003
1006
 
1007
+ ### `getMonitoringConfig()`
1008
+
1009
+ ```ts
1010
+ getMonitoringConfig(): MonitoringConfig
1011
+ ```
1012
+
1013
+ Returns the current monitoring configuration snapshot, including whether background monitoring is active.
1014
+
1015
+ This reads the native monitoring settings currently persisted by the module. Option fields are omitted when they have not been explicitly set.
1016
+
1017
+ ```ts
1018
+ const config = ExpoBeacon.getMonitoringConfig();
1019
+ // {
1020
+ // isMonitoring: true,
1021
+ // maxDistance: 10,
1022
+ // exitDistance: 15,
1023
+ // minRssi: -85,
1024
+ // level: "all"
1025
+ // }
1026
+ ```
1027
+
1028
+ ---
1029
+
1030
+ ### `getMonitoredDeviceState(identifier)`
1031
+
1032
+ ```ts
1033
+ getMonitoredDeviceState(identifier: string): MonitoredDeviceState | null
1034
+ ```
1035
+
1036
+ Returns the current monitoring-state snapshot for a paired iBeacon or Eddystone with the matching identifier.
1037
+
1038
+ - `state` is `"entered"` or `"exited"`.
1039
+ - `distance` is `null` when the device is currently exited or there is no live reading yet.
1040
+ - Returns `null` when no paired device matches the identifier.
1041
+
1042
+ Identifiers should be unique across all paired monitored devices.
1043
+
1044
+ ```ts
1045
+ const lobby = ExpoBeacon.getMonitoredDeviceState("lobby-entrance");
1046
+ // {
1047
+ // kind: "ibeacon",
1048
+ // identifier: "lobby-entrance",
1049
+ // uuid: "E2C56DB5-DFFB-48D2-B060-D0F5A71096E0",
1050
+ // major: 1,
1051
+ // minor: 100,
1052
+ // state: "entered",
1053
+ // distance: 2.4
1054
+ // }
1055
+ ```
1056
+
1057
+ ---
1058
+
1059
+ ### `getMonitoredDeviceStates()`
1060
+
1061
+ ```ts
1062
+ getMonitoredDeviceStates(): MonitoredDeviceState[]
1063
+ ```
1064
+
1065
+ Returns the current monitoring-state snapshots for all paired monitored devices across iBeacon and Eddystone.
1066
+
1067
+ ```ts
1068
+ const states = ExpoBeacon.getMonitoredDeviceStates();
1069
+ // [
1070
+ // { kind: "ibeacon", identifier: "lobby-entrance", state: "entered", distance: 2.4, ... },
1071
+ // { kind: "eddystone", identifier: "meeting-room", state: "exited", distance: null, ... }
1072
+ // ]
1073
+ ```
1074
+
1075
+ ---
1076
+
1004
1077
  ### `setNotificationConfig(config)`
1005
1078
 
1006
1079
  ```ts
@@ -1390,10 +1463,51 @@ Passed to `startMonitoring()`.
1390
1463
  type MonitoringOptions = {
1391
1464
  maxDistance?: number;
1392
1465
  exitDistance?: number;
1466
+ minRssi?: number;
1467
+ level?: "all" | "events";
1468
+ };
1469
+ ```
1470
+
1471
+ ### `MonitoringConfig`
1472
+
1473
+ Returned by `getMonitoringConfig()`.
1474
+
1475
+ ```ts
1476
+ type MonitoringConfig = {
1477
+ isMonitoring: boolean;
1478
+ maxDistance?: number;
1479
+ exitDistance?: number;
1480
+ minRssi?: number;
1481
+ level?: "all" | "events";
1393
1482
  notifications?: NotificationConfig;
1394
1483
  };
1395
1484
  ```
1396
1485
 
1486
+ ### `MonitoredDeviceState`
1487
+
1488
+ Returned by `getMonitoredDeviceState()` and `getMonitoredDeviceStates()`.
1489
+
1490
+ ```ts
1491
+ type MonitoredDeviceState =
1492
+ | {
1493
+ kind: "ibeacon";
1494
+ identifier: string;
1495
+ uuid: string;
1496
+ major: number;
1497
+ minor: number;
1498
+ state: "entered" | "exited";
1499
+ distance: number | null;
1500
+ }
1501
+ | {
1502
+ kind: "eddystone";
1503
+ identifier: string;
1504
+ namespace: string;
1505
+ instance: string;
1506
+ state: "entered" | "exited";
1507
+ distance: number | null;
1508
+ };
1509
+ ```
1510
+
1397
1511
  ### `NotificationConfig`
1398
1512
 
1399
1513
  Top-level notification configuration.
@@ -1413,6 +1527,7 @@ type BeaconNotificationConfig = {
1413
1527
  enabled?: boolean; // Default: true. Set false to suppress.
1414
1528
  enterTitle?: string; // Default: "Beacon Entered"
1415
1529
  exitTitle?: string; // Default: "Beacon Exited"
1530
+ timeoutTitle?: string; // Default: "Beacon Timeout"
1416
1531
  body?: string; // Default: "{identifier} region {event}ed"
1417
1532
  // Supports {identifier} and {event} placeholders.
1418
1533
  sound?: boolean; // iOS only. Default: true
@@ -29,6 +29,11 @@ private const val ENTER_EXIT_NOTIF_BASE_ID = 2000
29
29
 
30
30
  class BeaconForegroundService : Service(), BeaconConsumer {
31
31
 
32
+ data class MonitoringRuntimeState(
33
+ val isEntered: Boolean,
34
+ val distance: Double?
35
+ )
36
+
32
37
  private lateinit var beaconManager: BeaconManager
33
38
  private val monitoredRegions = mutableListOf<Region>()
34
39
 
@@ -73,6 +78,7 @@ class BeaconForegroundService : Service(), BeaconConsumer {
73
78
 
74
79
  override fun onCreate() {
75
80
  super.onCreate()
81
+ activeService = this
76
82
  createNotificationChannel()
77
83
  apiForwarder = BeaconApiForwarder(this)
78
84
  beaconManager = BeaconManager.getInstanceForApplication(this).also { manager ->
@@ -667,6 +673,18 @@ class BeaconForegroundService : Service(), BeaconConsumer {
667
673
  return Companion.buildForegroundNotification(this)
668
674
  }
669
675
 
676
+ private fun snapshotMonitoringRuntimeState(): Map<String, MonitoringRuntimeState> {
677
+ synchronized(distanceLock) {
678
+ val regionIds = monitoredRegionIds.toList()
679
+ return regionIds.associateWith { regionId ->
680
+ MonitoringRuntimeState(
681
+ isEntered = enteredRegions.contains(regionId),
682
+ distance = smoothedDistances[regionId]
683
+ )
684
+ }
685
+ }
686
+ }
687
+
670
688
  companion object {
671
689
  /** EMA weight for new readings. 0.4 balances responsiveness vs noise rejection. */
672
690
  const val DISTANCE_EMA_ALPHA = 0.4
@@ -674,6 +692,7 @@ class BeaconForegroundService : Service(), BeaconConsumer {
674
692
  const val DISTANCE_JUMP_FACTOR = 5.0
675
693
 
676
694
  private const val PREF_IS_MONITORING = "expo.beacon.is_monitoring"
695
+ @Volatile private var activeService: BeaconForegroundService? = null
677
696
 
678
697
  fun start(context: Context) {
679
698
  context.getSharedPreferences(PREF_IS_MONITORING, Context.MODE_PRIVATE)
@@ -698,6 +717,10 @@ class BeaconForegroundService : Service(), BeaconConsumer {
698
717
  .getBoolean("active", false)
699
718
  }
700
719
 
720
+ fun getMonitoringRuntimeSnapshot(): Map<String, MonitoringRuntimeState> {
721
+ return activeService?.snapshotMonitoringRuntimeState() ?: emptyMap()
722
+ }
723
+
701
724
  /**
702
725
  * Ensure the notification channel exists. Must be called before building
703
726
  * a notification from a non-service context (e.g. ExpoBeaconModule).
@@ -767,6 +790,9 @@ class BeaconForegroundService : Service(), BeaconConsumer {
767
790
  }
768
791
 
769
792
  override fun onDestroy() {
793
+ if (activeService === this) {
794
+ activeService = null
795
+ }
770
796
  serviceConnected = false
771
797
  timeoutHandler.removeCallbacksAndMessages(null)
772
798
  timeoutRunnables.clear()
@@ -490,6 +490,14 @@ class ExpoBeaconModule : Module(), BeaconConsumer {
490
490
  }
491
491
  }
492
492
 
493
+ Function("getMonitoredDeviceState") { identifier: String ->
494
+ buildMonitoredDeviceState(identifier)
495
+ }
496
+
497
+ Function("getMonitoredDeviceStates") {
498
+ buildMonitoredDeviceStates()
499
+ }
500
+
493
501
  // MARK: - Battery Optimization
494
502
 
495
503
  Function("isBatteryOptimizationExempt") {
@@ -787,6 +795,88 @@ class ExpoBeaconModule : Module(), BeaconConsumer {
787
795
  return map
788
796
  }
789
797
 
798
+ private fun buildMonitoredDeviceState(identifier: String): Map<String, Any?>? {
799
+ val runtimeStates = BeaconForegroundService.getMonitoringRuntimeSnapshot()
800
+
801
+ val beacons = loadPairedBeaconsJson()
802
+ for (i in 0 until beacons.length()) {
803
+ val beacon = beacons.getJSONObject(i)
804
+ if (beacon.getString("identifier") == identifier) {
805
+ return buildIBeaconMonitoringState(beacon, runtimeStates[identifier])
806
+ }
807
+ }
808
+
809
+ val eddystones = loadPairedEddystonesJson()
810
+ for (i in 0 until eddystones.length()) {
811
+ val eddystone = eddystones.getJSONObject(i)
812
+ if (eddystone.getString("identifier") == identifier) {
813
+ return buildEddystoneMonitoringState(eddystone, runtimeStates[identifier])
814
+ }
815
+ }
816
+
817
+ return null
818
+ }
819
+
820
+ private fun buildMonitoredDeviceStates(): List<Map<String, Any?>> {
821
+ val runtimeStates = BeaconForegroundService.getMonitoringRuntimeSnapshot()
822
+ val states = mutableListOf<Map<String, Any?>>()
823
+
824
+ val beacons = loadPairedBeaconsJson()
825
+ for (i in 0 until beacons.length()) {
826
+ val beacon = beacons.getJSONObject(i)
827
+ val identifier = beacon.getString("identifier")
828
+ states.add(buildIBeaconMonitoringState(beacon, runtimeStates[identifier]))
829
+ }
830
+
831
+ val eddystones = loadPairedEddystonesJson()
832
+ for (i in 0 until eddystones.length()) {
833
+ val eddystone = eddystones.getJSONObject(i)
834
+ val identifier = eddystone.getString("identifier")
835
+ states.add(buildEddystoneMonitoringState(eddystone, runtimeStates[identifier]))
836
+ }
837
+
838
+ return states
839
+ }
840
+
841
+ private fun buildIBeaconMonitoringState(
842
+ beacon: JSONObject,
843
+ runtimeState: BeaconForegroundService.MonitoringRuntimeState?
844
+ ): Map<String, Any?> {
845
+ val identifier = beacon.getString("identifier")
846
+ return buildMap<String, Any?> {
847
+ put("kind", "ibeacon")
848
+ put("identifier", identifier)
849
+ put("uuid", beacon.getString("uuid"))
850
+ put("major", beacon.getInt("major"))
851
+ put("minor", beacon.getInt("minor"))
852
+ put("state", if (runtimeState?.isEntered == true) "entered" else "exited")
853
+ put("distance", normalizedMonitoringDistance(runtimeState))
854
+ }
855
+ }
856
+
857
+ private fun buildEddystoneMonitoringState(
858
+ eddystone: JSONObject,
859
+ runtimeState: BeaconForegroundService.MonitoringRuntimeState?
860
+ ): Map<String, Any?> {
861
+ val identifier = eddystone.getString("identifier")
862
+ return buildMap<String, Any?> {
863
+ put("kind", "eddystone")
864
+ put("identifier", identifier)
865
+ put("namespace", eddystone.getString("namespace"))
866
+ put("instance", eddystone.getString("instance"))
867
+ put("state", if (runtimeState?.isEntered == true) "entered" else "exited")
868
+ put("distance", normalizedMonitoringDistance(runtimeState))
869
+ }
870
+ }
871
+
872
+ private fun normalizedMonitoringDistance(
873
+ runtimeState: BeaconForegroundService.MonitoringRuntimeState?
874
+ ): Double? {
875
+ if (runtimeState?.isEntered != true) return null
876
+ val distance = runtimeState.distance ?: return null
877
+ return distance.takeIf { !it.isNaN() && !it.isInfinite() && it >= 0 }
878
+ }
879
+
790
880
  // --- Shared Preferences helpers ---
791
881
 
792
882
  /** Removes entries matching [identifier] from a paired JSON array, saves, and invalidates cache. */
@@ -123,6 +123,25 @@ export type MonitoringConfig = {
123
123
  level?: 'all' | 'events';
124
124
  notifications?: NotificationConfig;
125
125
  };
126
+ /** Current state snapshot for a paired monitored device. */
127
+ export type MonitoredDeviceState = {
128
+ kind: "ibeacon";
129
+ identifier: string;
130
+ uuid: string;
131
+ major: number;
132
+ minor: number;
133
+ state: "entered" | "exited";
134
+ /** Current distance in metres, or null when exited or no live reading is available. */
135
+ distance: number | null;
136
+ } | {
137
+ kind: "eddystone";
138
+ identifier: string;
139
+ namespace: string;
140
+ instance: string;
141
+ state: "entered" | "exited";
142
+ /** Current distance in metres, or null when exited or no live reading is available. */
143
+ distance: number | null;
144
+ };
126
145
  /** Options accepted by startMonitoring(). */
127
146
  export type MonitoringOptions = {
128
147
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"ExpoBeacon.types.d.ts","sourceRoot":"","sources":["../src/ExpoBeacon.types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ExpoBeacon.types.d.ts","sourceRoot":"","sources":["../src/ExpoBeacon.types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ExpoBeacon.types.js","sourceRoot":"","sources":["../src/ExpoBeacon.types.ts"],"names":[],"mappings":"","sourcesContent":["/** Raw beacon discovered during a scan. */\r\nexport type BeaconScanResult = {\r\n uuid: string; // iBeacon proximity UUID (uppercase, formatted)\r\n major: number; // iBeacon major value (0–65535)\r\n minor: number; // iBeacon minor value (0–65535)\r\n rssi: number; // Signal strength in dBm (negative number)\r\n distance: number; // Estimated distance in meters\r\n txPower: number; // Calibrated TX power\r\n /** BLE advertising device name. May be undefined on iOS (CoreLocation does not expose it for iBeacon). */\r\n name?: string;\r\n};\r\n\r\n/**\r\n * A beacon that has been paired/registered for monitoring.\r\n *\r\n * Note: Paired beacon data is stored unencrypted in UserDefaults (iOS) /\r\n * SharedPreferences (Android) and may be included in device backups.\r\n */\r\nexport type PairedBeacon = {\r\n identifier: string; // User-defined label (e.g. \"lobby-door\")\r\n uuid: string;\r\n major: number;\r\n minor: number;\r\n /** BLE advertising device name, if provided at pairing time. */\r\n name?: string;\r\n /**\r\n * Timeout in seconds. When set, the module fires `onBeaconTimeout` once\r\n * after the beacon has been continuously in range for this duration.\r\n * The timer resets if the beacon exits and re-enters range.\r\n *\r\n * The timeout countdown also starts if no BLE readings are received\r\n * for 60 seconds (e.g. due to Doze mode or background throttling).\r\n */\r\n timeoutSeconds?: number;\r\n};\r\n\r\n/** Payload for enter/exit region events. */\r\nexport type BeaconRegionEvent = {\r\n identifier: string; // Matches PairedBeacon.identifier\r\n uuid: string;\r\n major: number;\r\n minor: number;\r\n event: \"enter\" | \"exit\";\r\n /** Measured distance in metres at the time of the event (–1 if unavailable). */\r\n distance: number;\r\n /** Signal strength in dBm at the time of the event (0 if unavailable). */\r\n rssi?: number;\r\n};\r\n\r\n/** Payload for periodic distance update events during monitoring. */\r\nexport type BeaconDistanceEvent = {\r\n identifier: string;\r\n uuid: string;\r\n major: number;\r\n minor: number;\r\n distance: number;\r\n /** Signal strength in dBm (0 if unavailable). */\r\n rssi?: number;\r\n};\r\n\r\n/** Payload for beacon timeout events (beacon in range for configured duration). */\r\nexport type BeaconTimeoutEvent = {\r\n identifier: string;\r\n uuid: string;\r\n major: number;\r\n minor: number;\r\n /** Current distance in metres at the time the timeout fired. */\r\n distance: number;\r\n};\r\n\r\n/** Configuration for beacon enter/exit event notifications. */\r\nexport type BeaconNotificationConfig = {\r\n /** Whether to show enter/exit notifications. Default: true. */\r\n enabled?: boolean;\r\n /** Notification title on beacon enter. Default: \"Beacon Entered\". */\r\n enterTitle?: string;\r\n /** Notification title on beacon exit. Default: \"Beacon Exited\". */\r\n exitTitle?: string;\r\n /** Notification title on beacon timeout. Default: \"Beacon Timeout\". */\r\n timeoutTitle?: string;\r\n /**\r\n * Notification body template. Supports {identifier} and {event} placeholders.\r\n * Default: \"{identifier} region {event}ed\".\r\n */\r\n body?: string;\r\n /** Play a sound with the notification (iOS only). Default: true. */\r\n sound?: boolean;\r\n /** Android drawable resource name for the notification icon (e.g. \"ic_notification\"). */\r\n icon?: string;\r\n};\r\n\r\n/** Configuration for the Android foreground service notification (persistent status bar entry). */\r\nexport type ForegroundServiceConfig = {\r\n /** Title of the persistent notification. Default: \"Beacon Monitoring Active\". */\r\n title?: string;\r\n /** Body text of the persistent notification. Default: \"Monitoring for iBeacons in the background\". */\r\n text?: string;\r\n /** Android drawable resource name for the notification icon. */\r\n icon?: string;\r\n};\r\n\r\n/** Configuration for the Android notification channel. */\r\nexport type NotificationChannelConfig = {\r\n /** Channel display name shown in system settings. Default: \"Beacon Monitoring\". */\r\n name?: string;\r\n /** Channel description shown in system settings. Default: \"Used for background iBeacon region monitoring\". */\r\n description?: string;\r\n /**\r\n * Channel importance level. Default: 'low'.\r\n * Note: Android may ignore decreases in importance after first channel creation until the app is reinstalled.\r\n */\r\n importance?: \"low\" | \"default\" | \"high\";\r\n};\r\n\r\n/** Combined notification configuration for all notification types. */\r\nexport type NotificationConfig = {\r\n /** Settings for beacon enter/exit event notifications. */\r\n beaconEvents?: BeaconNotificationConfig;\r\n /** Settings for the persistent foreground service notification (Android only). */\r\n foregroundService?: ForegroundServiceConfig;\r\n /** Settings for the Android notification channel (Android only). */\r\n channel?: NotificationChannelConfig;\r\n};\r\n\r\n/** Snapshot of the current monitoring configuration and active state. */\r\nexport type MonitoringConfig = {\r\n /** Whether background monitoring is currently active. */\r\n isMonitoring: boolean;\r\n maxDistance?: number;\r\n exitDistance?: number;\r\n minRssi?: number;\r\n level?: 'all' | 'events';\r\n notifications?: NotificationConfig;\r\n};\r\n\r\n/** Options accepted by startMonitoring(). */\r\nexport type MonitoringOptions = {\r\n /**\r\n * Maximum distance in metres for distance-based enter events.\r\n * Exit events are always emitted when the region is lost.\r\n */\r\n maxDistance?: number;\r\n /**\r\n * Distance in metres at which exit events fire (must be ≥ maxDistance).\r\n * Creates a hysteresis band between enter and exit thresholds to prevent\r\n * rapid toggling near the boundary.\r\n *\r\n * Default when omitted: `maxDistance + min(maxDistance × 0.5, 2.5)`.\r\n * Only used when `maxDistance` is set.\r\n */\r\n exitDistance?: number;\r\n /**\r\n * Minimum RSSI (dBm) for a beacon reading to be considered valid.\r\n * Readings below this threshold are discarded as unreliable, preventing\r\n * false detections from reflected or distant signals.\r\n *\r\n * Default: -85. Typical range: -100 (very permissive) to -70 (strict).\r\n */\r\n minRssi?: number;\r\n /**\r\n * Controls which event types are emitted, logged, and forwarded to the API.\r\n *\r\n * - `'all'` (default): distance + enter + exit + timeout events.\r\n * - `'events'`: enter + exit + timeout only (no distance events).\r\n */\r\n level?: 'all' | 'events';\r\n /** Notification configuration overrides to apply for this monitoring session. */\r\n notifications?: NotificationConfig;\r\n};\r\n\r\n/** Eddystone frame type. */\r\nexport type EddystoneFrameType = \"uid\" | \"url\";\r\n\r\n/** Raw Eddystone beacon discovered during a scan. */\r\nexport type EddystoneScanResult = {\r\n frameType: EddystoneFrameType;\r\n /** 10-byte namespace ID as hex string (20 chars). Present for UID frames. */\r\n namespace?: string;\r\n /** 6-byte instance ID as hex string (12 chars). Present for UID frames. */\r\n instance?: string;\r\n /** Decoded URL. Present for URL frames. */\r\n url?: string;\r\n rssi: number;\r\n distance: number;\r\n txPower: number;\r\n /** BLE advertising device name. */\r\n name?: string;\r\n};\r\n\r\n/**\r\n * An Eddystone-UID beacon that has been paired/registered for monitoring.\r\n *\r\n * Note: Paired beacon data is stored unencrypted in UserDefaults (iOS) /\r\n * SharedPreferences (Android) and may be included in device backups.\r\n */\r\nexport type PairedEddystone = {\r\n identifier: string;\r\n /** 10-byte namespace ID as hex string (20 chars). */\r\n namespace: string;\r\n /** 6-byte instance ID as hex string (12 chars). */\r\n instance: string;\r\n /** BLE advertising device name, if provided at pairing time. */\r\n name?: string;\r\n /**\r\n * Timeout in seconds. When set, the module fires `onEddystoneTimeout` once\r\n * after the beacon has been continuously in range for this duration.\r\n * The timer resets if the beacon exits and re-enters range.\r\n *\r\n * The timeout countdown also starts if no BLE readings are received\r\n * for 60 seconds (e.g. due to Doze mode or background throttling).\r\n */\r\n timeoutSeconds?: number;\r\n};\r\n\r\n/** Payload for Eddystone enter/exit region events. */\r\nexport type EddystoneRegionEvent = {\r\n identifier: string;\r\n namespace: string;\r\n instance: string;\r\n event: \"enter\" | \"exit\";\r\n /** Measured distance in metres at the time of the event (–1 if unavailable). */\r\n distance: number;\r\n /** Signal strength in dBm at the time of the event (0 if unavailable). */\r\n rssi?: number;\r\n};\r\n\r\n/** Payload for periodic Eddystone distance update events during monitoring. */\r\nexport type EddystoneDistanceEvent = {\r\n identifier: string;\r\n namespace: string;\r\n instance: string;\r\n distance: number;\r\n /** Signal strength in dBm (0 if unavailable). */\r\n rssi?: number;\r\n};\r\n\r\n/** Payload for Eddystone timeout events (beacon in range for configured duration). */\r\nexport type EddystoneTimeoutEvent = {\r\n identifier: string;\r\n namespace: string;\r\n instance: string;\r\n /** Current distance in metres at the time the timeout fired. */\r\n distance: number;\r\n};\r\n\r\n/** Module event map. */\r\nexport type ExpoBeaconModuleEvents = {\r\n onBeaconEnter: (params: BeaconRegionEvent) => void;\r\n onBeaconExit: (params: BeaconRegionEvent) => void;\r\n onBeaconDistance: (params: BeaconDistanceEvent) => void;\r\n /** Fired once after a paired beacon has been continuously in range for its configured `timeoutSeconds`. */\r\n onBeaconTimeout: (params: BeaconTimeoutEvent) => void;\r\n /** Fired continuously during a live scan as each iBeacon is detected. */\r\n onBeaconFound: (params: BeaconScanResult) => void;\r\n /** Fired continuously during a live scan as each Eddystone beacon is detected. */\r\n onEddystoneFound: (params: EddystoneScanResult) => void;\r\n onEddystoneEnter: (params: EddystoneRegionEvent) => void;\r\n onEddystoneExit: (params: EddystoneRegionEvent) => void;\r\n onEddystoneDistance: (params: EddystoneDistanceEvent) => void;\r\n /** Fired once after a paired Eddystone has been continuously in range for its configured `timeoutSeconds`. */\r\n onEddystoneTimeout: (params: EddystoneTimeoutEvent) => void;\r\n};\r\n\r\n/** Options for filtering event logs. */\r\nexport type EventLogQueryOptions = {\r\n /** Maximum number of log entries to return (default: 1000, max: 10000). */\r\n limit?: number;\r\n /** Filter by event type (e.g. \"onBeaconEnter\", \"onBeaconExit\"). */\r\n eventType?: string;\r\n /** Only return events with timestamp >= this value (ms since epoch). */\r\n sinceTimestamp?: number;\r\n};\r\n\r\n/** A single logged beacon event entry. */\r\nexport type EventLogEntry = {\r\n id: number;\r\n /** Timestamp in milliseconds since epoch. */\r\n timestamp: number;\r\n /** The event type that was logged (e.g. \"onBeaconEnter\"). */\r\n eventType: string;\r\n /** Beacon identifier, if available. */\r\n identifier?: string;\r\n /** The full event payload that was sent to JS. */\r\n data: Record<string, unknown>;\r\n};\r\n"]}
1
+ {"version":3,"file":"ExpoBeacon.types.js","sourceRoot":"","sources":["../src/ExpoBeacon.types.ts"],"names":[],"mappings":"","sourcesContent":["/** Raw beacon discovered during a scan. */\r\nexport type BeaconScanResult = {\r\n uuid: string; // iBeacon proximity UUID (uppercase, formatted)\r\n major: number; // iBeacon major value (0–65535)\r\n minor: number; // iBeacon minor value (0–65535)\r\n rssi: number; // Signal strength in dBm (negative number)\r\n distance: number; // Estimated distance in meters\r\n txPower: number; // Calibrated TX power\r\n /** BLE advertising device name. May be undefined on iOS (CoreLocation does not expose it for iBeacon). */\r\n name?: string;\r\n};\r\n\r\n/**\r\n * A beacon that has been paired/registered for monitoring.\r\n *\r\n * Note: Paired beacon data is stored unencrypted in UserDefaults (iOS) /\r\n * SharedPreferences (Android) and may be included in device backups.\r\n */\r\nexport type PairedBeacon = {\r\n identifier: string; // User-defined label (e.g. \"lobby-door\")\r\n uuid: string;\r\n major: number;\r\n minor: number;\r\n /** BLE advertising device name, if provided at pairing time. */\r\n name?: string;\r\n /**\r\n * Timeout in seconds. When set, the module fires `onBeaconTimeout` once\r\n * after the beacon has been continuously in range for this duration.\r\n * The timer resets if the beacon exits and re-enters range.\r\n *\r\n * The timeout countdown also starts if no BLE readings are received\r\n * for 60 seconds (e.g. due to Doze mode or background throttling).\r\n */\r\n timeoutSeconds?: number;\r\n};\r\n\r\n/** Payload for enter/exit region events. */\r\nexport type BeaconRegionEvent = {\r\n identifier: string; // Matches PairedBeacon.identifier\r\n uuid: string;\r\n major: number;\r\n minor: number;\r\n event: \"enter\" | \"exit\";\r\n /** Measured distance in metres at the time of the event (–1 if unavailable). */\r\n distance: number;\r\n /** Signal strength in dBm at the time of the event (0 if unavailable). */\r\n rssi?: number;\r\n};\r\n\r\n/** Payload for periodic distance update events during monitoring. */\r\nexport type BeaconDistanceEvent = {\r\n identifier: string;\r\n uuid: string;\r\n major: number;\r\n minor: number;\r\n distance: number;\r\n /** Signal strength in dBm (0 if unavailable). */\r\n rssi?: number;\r\n};\r\n\r\n/** Payload for beacon timeout events (beacon in range for configured duration). */\r\nexport type BeaconTimeoutEvent = {\r\n identifier: string;\r\n uuid: string;\r\n major: number;\r\n minor: number;\r\n /** Current distance in metres at the time the timeout fired. */\r\n distance: number;\r\n};\r\n\r\n/** Configuration for beacon enter/exit event notifications. */\r\nexport type BeaconNotificationConfig = {\r\n /** Whether to show enter/exit notifications. Default: true. */\r\n enabled?: boolean;\r\n /** Notification title on beacon enter. Default: \"Beacon Entered\". */\r\n enterTitle?: string;\r\n /** Notification title on beacon exit. Default: \"Beacon Exited\". */\r\n exitTitle?: string;\r\n /** Notification title on beacon timeout. Default: \"Beacon Timeout\". */\r\n timeoutTitle?: string;\r\n /**\r\n * Notification body template. Supports {identifier} and {event} placeholders.\r\n * Default: \"{identifier} region {event}ed\".\r\n */\r\n body?: string;\r\n /** Play a sound with the notification (iOS only). Default: true. */\r\n sound?: boolean;\r\n /** Android drawable resource name for the notification icon (e.g. \"ic_notification\"). */\r\n icon?: string;\r\n};\r\n\r\n/** Configuration for the Android foreground service notification (persistent status bar entry). */\r\nexport type ForegroundServiceConfig = {\r\n /** Title of the persistent notification. Default: \"Beacon Monitoring Active\". */\r\n title?: string;\r\n /** Body text of the persistent notification. Default: \"Monitoring for iBeacons in the background\". */\r\n text?: string;\r\n /** Android drawable resource name for the notification icon. */\r\n icon?: string;\r\n};\r\n\r\n/** Configuration for the Android notification channel. */\r\nexport type NotificationChannelConfig = {\r\n /** Channel display name shown in system settings. Default: \"Beacon Monitoring\". */\r\n name?: string;\r\n /** Channel description shown in system settings. Default: \"Used for background iBeacon region monitoring\". */\r\n description?: string;\r\n /**\r\n * Channel importance level. Default: 'low'.\r\n * Note: Android may ignore decreases in importance after first channel creation until the app is reinstalled.\r\n */\r\n importance?: \"low\" | \"default\" | \"high\";\r\n};\r\n\r\n/** Combined notification configuration for all notification types. */\r\nexport type NotificationConfig = {\r\n /** Settings for beacon enter/exit event notifications. */\r\n beaconEvents?: BeaconNotificationConfig;\r\n /** Settings for the persistent foreground service notification (Android only). */\r\n foregroundService?: ForegroundServiceConfig;\r\n /** Settings for the Android notification channel (Android only). */\r\n channel?: NotificationChannelConfig;\r\n};\r\n\r\n/** Snapshot of the current monitoring configuration and active state. */\r\nexport type MonitoringConfig = {\r\n /** Whether background monitoring is currently active. */\r\n isMonitoring: boolean;\r\n maxDistance?: number;\r\n exitDistance?: number;\r\n minRssi?: number;\r\n level?: 'all' | 'events';\r\n notifications?: NotificationConfig;\r\n};\r\n\r\n/** Current state snapshot for a paired monitored device. */\r\nexport type MonitoredDeviceState =\r\n | {\r\n kind: \"ibeacon\";\r\n identifier: string;\r\n uuid: string;\r\n major: number;\r\n minor: number;\r\n state: \"entered\" | \"exited\";\r\n /** Current distance in metres, or null when exited or no live reading is available. */\r\n distance: number | null;\r\n }\r\n | {\r\n kind: \"eddystone\";\r\n identifier: string;\r\n namespace: string;\r\n instance: string;\r\n state: \"entered\" | \"exited\";\r\n /** Current distance in metres, or null when exited or no live reading is available. */\r\n distance: number | null;\r\n };\r\n\r\n/** Options accepted by startMonitoring(). */\r\nexport type MonitoringOptions = {\r\n /**\r\n * Maximum distance in metres for distance-based enter events.\r\n * Exit events are always emitted when the region is lost.\r\n */\r\n maxDistance?: number;\r\n /**\r\n * Distance in metres at which exit events fire (must be ≥ maxDistance).\r\n * Creates a hysteresis band between enter and exit thresholds to prevent\r\n * rapid toggling near the boundary.\r\n *\r\n * Default when omitted: `maxDistance + min(maxDistance × 0.5, 2.5)`.\r\n * Only used when `maxDistance` is set.\r\n */\r\n exitDistance?: number;\r\n /**\r\n * Minimum RSSI (dBm) for a beacon reading to be considered valid.\r\n * Readings below this threshold are discarded as unreliable, preventing\r\n * false detections from reflected or distant signals.\r\n *\r\n * Default: -85. Typical range: -100 (very permissive) to -70 (strict).\r\n */\r\n minRssi?: number;\r\n /**\r\n * Controls which event types are emitted, logged, and forwarded to the API.\r\n *\r\n * - `'all'` (default): distance + enter + exit + timeout events.\r\n * - `'events'`: enter + exit + timeout only (no distance events).\r\n */\r\n level?: 'all' | 'events';\r\n /** Notification configuration overrides to apply for this monitoring session. */\r\n notifications?: NotificationConfig;\r\n};\r\n\r\n/** Eddystone frame type. */\r\nexport type EddystoneFrameType = \"uid\" | \"url\";\r\n\r\n/** Raw Eddystone beacon discovered during a scan. */\r\nexport type EddystoneScanResult = {\r\n frameType: EddystoneFrameType;\r\n /** 10-byte namespace ID as hex string (20 chars). Present for UID frames. */\r\n namespace?: string;\r\n /** 6-byte instance ID as hex string (12 chars). Present for UID frames. */\r\n instance?: string;\r\n /** Decoded URL. Present for URL frames. */\r\n url?: string;\r\n rssi: number;\r\n distance: number;\r\n txPower: number;\r\n /** BLE advertising device name. */\r\n name?: string;\r\n};\r\n\r\n/**\r\n * An Eddystone-UID beacon that has been paired/registered for monitoring.\r\n *\r\n * Note: Paired beacon data is stored unencrypted in UserDefaults (iOS) /\r\n * SharedPreferences (Android) and may be included in device backups.\r\n */\r\nexport type PairedEddystone = {\r\n identifier: string;\r\n /** 10-byte namespace ID as hex string (20 chars). */\r\n namespace: string;\r\n /** 6-byte instance ID as hex string (12 chars). */\r\n instance: string;\r\n /** BLE advertising device name, if provided at pairing time. */\r\n name?: string;\r\n /**\r\n * Timeout in seconds. When set, the module fires `onEddystoneTimeout` once\r\n * after the beacon has been continuously in range for this duration.\r\n * The timer resets if the beacon exits and re-enters range.\r\n *\r\n * The timeout countdown also starts if no BLE readings are received\r\n * for 60 seconds (e.g. due to Doze mode or background throttling).\r\n */\r\n timeoutSeconds?: number;\r\n};\r\n\r\n/** Payload for Eddystone enter/exit region events. */\r\nexport type EddystoneRegionEvent = {\r\n identifier: string;\r\n namespace: string;\r\n instance: string;\r\n event: \"enter\" | \"exit\";\r\n /** Measured distance in metres at the time of the event (–1 if unavailable). */\r\n distance: number;\r\n /** Signal strength in dBm at the time of the event (0 if unavailable). */\r\n rssi?: number;\r\n};\r\n\r\n/** Payload for periodic Eddystone distance update events during monitoring. */\r\nexport type EddystoneDistanceEvent = {\r\n identifier: string;\r\n namespace: string;\r\n instance: string;\r\n distance: number;\r\n /** Signal strength in dBm (0 if unavailable). */\r\n rssi?: number;\r\n};\r\n\r\n/** Payload for Eddystone timeout events (beacon in range for configured duration). */\r\nexport type EddystoneTimeoutEvent = {\r\n identifier: string;\r\n namespace: string;\r\n instance: string;\r\n /** Current distance in metres at the time the timeout fired. */\r\n distance: number;\r\n};\r\n\r\n/** Module event map. */\r\nexport type ExpoBeaconModuleEvents = {\r\n onBeaconEnter: (params: BeaconRegionEvent) => void;\r\n onBeaconExit: (params: BeaconRegionEvent) => void;\r\n onBeaconDistance: (params: BeaconDistanceEvent) => void;\r\n /** Fired once after a paired beacon has been continuously in range for its configured `timeoutSeconds`. */\r\n onBeaconTimeout: (params: BeaconTimeoutEvent) => void;\r\n /** Fired continuously during a live scan as each iBeacon is detected. */\r\n onBeaconFound: (params: BeaconScanResult) => void;\r\n /** Fired continuously during a live scan as each Eddystone beacon is detected. */\r\n onEddystoneFound: (params: EddystoneScanResult) => void;\r\n onEddystoneEnter: (params: EddystoneRegionEvent) => void;\r\n onEddystoneExit: (params: EddystoneRegionEvent) => void;\r\n onEddystoneDistance: (params: EddystoneDistanceEvent) => void;\r\n /** Fired once after a paired Eddystone has been continuously in range for its configured `timeoutSeconds`. */\r\n onEddystoneTimeout: (params: EddystoneTimeoutEvent) => void;\r\n};\r\n\r\n/** Options for filtering event logs. */\r\nexport type EventLogQueryOptions = {\r\n /** Maximum number of log entries to return (default: 1000, max: 10000). */\r\n limit?: number;\r\n /** Filter by event type (e.g. \"onBeaconEnter\", \"onBeaconExit\"). */\r\n eventType?: string;\r\n /** Only return events with timestamp >= this value (ms since epoch). */\r\n sinceTimestamp?: number;\r\n};\r\n\r\n/** A single logged beacon event entry. */\r\nexport type EventLogEntry = {\r\n id: number;\r\n /** Timestamp in milliseconds since epoch. */\r\n timestamp: number;\r\n /** The event type that was logged (e.g. \"onBeaconEnter\"). */\r\n eventType: string;\r\n /** Beacon identifier, if available. */\r\n identifier?: string;\r\n /** The full event payload that was sent to JS. */\r\n data: Record<string, unknown>;\r\n};\r\n"]}
@@ -1,5 +1,5 @@
1
1
  import { NativeModule } from "expo";
2
- import { ExpoBeaconModuleEvents, BeaconScanResult, EddystoneScanResult, PairedBeacon, PairedEddystone, NotificationConfig, MonitoringOptions, MonitoringConfig, EventLogQueryOptions, EventLogEntry } from "./ExpoBeacon.types";
2
+ import { ExpoBeaconModuleEvents, BeaconScanResult, EddystoneScanResult, PairedBeacon, PairedEddystone, NotificationConfig, MonitoringOptions, MonitoringConfig, MonitoredDeviceState, EventLogQueryOptions, EventLogEntry } from "./ExpoBeacon.types";
3
3
  declare class ExpoBeaconModule extends NativeModule<ExpoBeaconModuleEvents> {
4
4
  /**
5
5
  * Start a one-shot iBeacon scan. Resolves with discovered beacons after scanDuration ms.
@@ -117,6 +117,15 @@ declare class ExpoBeaconModule extends NativeModule<ExpoBeaconModuleEvents> {
117
117
  * Option fields are undefined if not explicitly set.
118
118
  */
119
119
  getMonitoringConfig(): MonitoringConfig;
120
+ /**
121
+ * Return the current state snapshot for a paired monitored device.
122
+ * Returns null when no paired device matches the identifier.
123
+ */
124
+ getMonitoredDeviceState(identifier: string): MonitoredDeviceState | null;
125
+ /**
126
+ * Return the current state snapshot for all paired monitored devices.
127
+ */
128
+ getMonitoredDeviceStates(): MonitoredDeviceState[];
120
129
  /**
121
130
  * Return the current API forwarding configuration.
122
131
  * Each field is `null` if not set.
@@ -1 +1 @@
1
- {"version":3,"file":"ExpoBeaconModule.d.ts","sourceRoot":"","sources":["../src/ExpoBeaconModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAuB,MAAM,MAAM,CAAC;AAEzD,OAAO,EACL,sBAAsB,EACtB,gBAAgB,EAChB,mBAAmB,EACnB,YAAY,EACZ,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,oBAAoB,EACpB,aAAa,EACd,MAAM,oBAAoB,CAAC;AAE5B,OAAO,OAAO,gBAAiB,SAAQ,YAAY,CAAC,sBAAsB,CAAC;IACzE;;;;;;;;;;;OAWG;IACH,mBAAmB,CACjB,KAAK,CAAC,EAAE,MAAM,EAAE,EAChB,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAE9B;;;;;OAKG;IACH,sBAAsB,CACpB,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAEjC;;OAEG;IACH,UAAU,CACR,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE,MAAM,EACb,cAAc,CAAC,EAAE,MAAM,GACtB,IAAI;IAEP;;OAEG;IACH,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAEtC;;OAEG;IACH,gBAAgB,IAAI,YAAY,EAAE;IAElC;;OAEG;IACH,aAAa,CACX,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,IAAI,CAAC,EAAE,MAAM,EACb,cAAc,CAAC,EAAE,MAAM,GACtB,IAAI;IAEP;;OAEG;IACH,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAEzC;;OAEG;IACH,mBAAmB,IAAI,eAAe,EAAE;IAExC;;;OAGG;IACH,qBAAqB,CAAC,MAAM,EAAE,kBAAkB,GAAG,IAAI;IAEvD;;;;;;;OAOG;IACH,eAAe,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAEpE;;OAEG;IACH,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAE/B;;;OAGG;IACH,mBAAmB,IAAI,IAAI;IAE3B,iEAAiE;IACjE,kBAAkB,IAAI,IAAI;IAE1B;;;OAGG;IACH,UAAU,IAAI,IAAI;IAElB,yEAAyE;IACzE,uBAAuB,IAAI,OAAO,CAAC,OAAO,CAAC;IAE3C;;;OAGG;IACH,2BAA2B,IAAI,OAAO;IAEtC;;;;;OAKG;IACH,mCAAmC,IAAI,OAAO,CAAC,OAAO,CAAC;IAEvD,4FAA4F;IAC5F,kBAAkB,IAAI,IAAI;IAE1B,oEAAoE;IACpE,mBAAmB,IAAI,IAAI;IAE3B;;;OAGG;IACH,YAAY,CAAC,OAAO,CAAC,EAAE,oBAAoB,GAAG,aAAa,EAAE;IAE7D,kDAAkD;IAClD,cAAc,IAAI,IAAI;IAEtB,mEAAmE;IACnE,gBAAgB,IAAI,IAAI;IAExB;;;;;;;;OAQG;IACH,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI;IAE/D;;;OAGG;IACH,mBAAmB,IAAI,gBAAgB;IAEvC;;;OAGG;IACH,cAAc,IAAI;QAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE;CACnF;;AAED,wBAAmE"}
1
+ {"version":3,"file":"ExpoBeaconModule.d.ts","sourceRoot":"","sources":["../src/ExpoBeaconModule.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ExpoBeaconModule.js","sourceRoot":"","sources":["../src/ExpoBeaconModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,mBAAmB,EAAE,MAAM,MAAM,CAAC;AAqLzD,eAAe,mBAAmB,CAAmB,YAAY,CAAC,CAAC","sourcesContent":["import { NativeModule, requireNativeModule } from \"expo\";\r\n\r\nimport {\r\n ExpoBeaconModuleEvents,\r\n BeaconScanResult,\r\n EddystoneScanResult,\r\n PairedBeacon,\r\n PairedEddystone,\r\n NotificationConfig,\r\n MonitoringOptions,\r\n MonitoringConfig,\r\n EventLogQueryOptions,\r\n EventLogEntry,\r\n} from \"./ExpoBeacon.types\";\r\n\r\ndeclare class ExpoBeaconModule extends NativeModule<ExpoBeaconModuleEvents> {\r\n /**\r\n * Start a one-shot iBeacon scan. Resolves with discovered beacons after scanDuration ms.\r\n *\r\n * Pass one or more UUIDs to scan for specific beacons (uses CoreLocation on iOS).\r\n * On iOS, at least one UUID is required — Apple strips iBeacon data from BLE\r\n * advertisements, making wildcard discovery impossible. When you pass an empty\r\n * array, the module automatically uses UUIDs from paired beacons.\r\n * On Android, pass an empty array to discover all nearby iBeacons.\r\n *\r\n * @param uuids Proximity UUIDs to filter by. Empty/omitted = use paired UUIDs (iOS) or wildcard (Android).\r\n * @param scanDuration Duration in ms (default 5000)\r\n */\r\n scanForBeaconsAsync(\r\n uuids?: string[],\r\n scanDuration?: number,\r\n ): Promise<BeaconScanResult[]>;\r\n\r\n /**\r\n * Start a one-shot Eddystone beacon scan using BLE.\r\n * Discovers Eddystone-UID and Eddystone-URL frames.\r\n *\r\n * @param scanDuration Duration in ms (default 5000)\r\n */\r\n scanForEddystonesAsync(\r\n scanDuration?: number,\r\n ): Promise<EddystoneScanResult[]>;\r\n\r\n /**\r\n * Register a beacon for persistent region monitoring.\r\n */\r\n pairBeacon(\r\n identifier: string,\r\n uuid: string,\r\n major: number,\r\n minor: number,\r\n name?: string,\r\n timeoutSeconds?: number,\r\n ): void;\r\n\r\n /**\r\n * Remove a previously paired beacon.\r\n */\r\n unpairBeacon(identifier: string): void;\r\n\r\n /**\r\n * Return all currently paired beacons.\r\n */\r\n getPairedBeacons(): PairedBeacon[];\r\n\r\n /**\r\n * Register an Eddystone-UID beacon for persistent monitoring.\r\n */\r\n pairEddystone(\r\n identifier: string,\r\n namespace: string,\r\n instance: string,\r\n name?: string,\r\n timeoutSeconds?: number,\r\n ): void;\r\n\r\n /**\r\n * Remove a previously paired Eddystone beacon.\r\n */\r\n unpairEddystone(identifier: string): void;\r\n\r\n /**\r\n * Return all currently paired Eddystone beacons.\r\n */\r\n getPairedEddystones(): PairedEddystone[];\r\n\r\n /**\r\n * Set persistent notification configuration. Settings are saved and applied to all\r\n * subsequent monitoring sessions until explicitly changed.\r\n */\r\n setNotificationConfig(config: NotificationConfig): void;\r\n\r\n /**\r\n * Start background region monitoring for all paired beacons.\r\n * On Android starts a foreground service.\r\n * On iOS starts CLLocationManager region monitoring.\r\n *\r\n * Accepts a plain number (backward-compatible maxDistance shorthand) or a\r\n * MonitoringOptions object with maxDistance and/or notification overrides.\r\n */\r\n startMonitoring(options?: MonitoringOptions | number): Promise<void>;\r\n\r\n /**\r\n * Stop background region monitoring.\r\n */\r\n stopMonitoring(): Promise<void>;\r\n\r\n /**\r\n * Start a continuous BLE scan. Fires `onBeaconFound` events as beacons are detected.\r\n * Call stopContinuousScan() to end the scan.\r\n */\r\n startContinuousScan(): void;\r\n\r\n /** Stop the continuous scan started by startContinuousScan(). */\r\n stopContinuousScan(): void;\r\n\r\n /**\r\n * Cancel any in-progress one-shot scan (iBeacon or Eddystone).\r\n * The pending promise will be rejected with code \"SCAN_CANCELLED\".\r\n */\r\n cancelScan(): void;\r\n\r\n /** Request Bluetooth + Location permissions. Returns true if granted. */\r\n requestPermissionsAsync(): Promise<boolean>;\r\n\r\n /**\r\n * Check whether the app is exempt from Android battery optimizations.\r\n * Always returns true on iOS and web (no equivalent concept).\r\n */\r\n isBatteryOptimizationExempt(): boolean;\r\n\r\n /**\r\n * Request exemption from Android battery optimizations.\r\n * Opens the system dialog asking the user to whitelist this app.\r\n * Returns true if the dialog was shown (or already exempt), false on failure.\r\n * Always resolves true on iOS and web.\r\n */\r\n requestBatteryOptimizationExemption(): Promise<boolean>;\r\n\r\n /** Enable SQLite event logging. All beacon events will be persisted to a local database. */\r\n enableEventLogging(): void;\r\n\r\n /** Disable event logging. Previously logged events are retained. */\r\n disableEventLogging(): void;\r\n\r\n /**\r\n * Retrieve logged beacon events from the SQLite database.\r\n * @param options Optional filters (limit, eventType, sinceTimestamp).\r\n */\r\n getEventLogs(options?: EventLogQueryOptions): EventLogEntry[];\r\n\r\n /** Delete all logged events from the database. */\r\n clearEventLogs(): void;\r\n\r\n /** Delete the entire event log database. Also disables logging. */\r\n destroyEventLogs(): void;\r\n\r\n /**\r\n * Configure a remote API endpoint for native event forwarding.\r\n * Once set, beacon events are POSTed directly from native code,\r\n * ensuring delivery even when the JS bridge is not active (app backgrounded).\r\n *\r\n * @param url The API endpoint URL to POST events to.\r\n * @param apiKey Optional API key sent as X-CSFR-Token header.\r\n * @param id Optional identifier appended to every forwarded event payload.\r\n */\r\n setApiEndpoint(url: string, apiKey?: string, id?: string): void;\r\n\r\n /**\r\n * Return the current monitoring configuration and active state.\r\n * Option fields are undefined if not explicitly set.\r\n */\r\n getMonitoringConfig(): MonitoringConfig;\r\n\r\n /**\r\n * Return the current API forwarding configuration.\r\n * Each field is `null` if not set.\r\n */\r\n getApiEndpoint(): { url: string | null; apiKey: string | null; id: string | null };\r\n}\r\n\r\nexport default requireNativeModule<ExpoBeaconModule>(\"ExpoBeacon\");\r\n"]}
1
+ {"version":3,"file":"ExpoBeaconModule.js","sourceRoot":"","sources":["../src/ExpoBeaconModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,mBAAmB,EAAE,MAAM,MAAM,CAAC;AAiMzD,eAAe,mBAAmB,CAAmB,YAAY,CAAC,CAAC","sourcesContent":["import { NativeModule, requireNativeModule } from \"expo\";\r\n\r\nimport {\r\n ExpoBeaconModuleEvents,\r\n BeaconScanResult,\r\n EddystoneScanResult,\r\n PairedBeacon,\r\n PairedEddystone,\r\n NotificationConfig,\r\n MonitoringOptions,\r\n MonitoringConfig,\r\n MonitoredDeviceState,\r\n EventLogQueryOptions,\r\n EventLogEntry,\r\n} from \"./ExpoBeacon.types\";\r\n\r\ndeclare class ExpoBeaconModule extends NativeModule<ExpoBeaconModuleEvents> {\r\n /**\r\n * Start a one-shot iBeacon scan. Resolves with discovered beacons after scanDuration ms.\r\n *\r\n * Pass one or more UUIDs to scan for specific beacons (uses CoreLocation on iOS).\r\n * On iOS, at least one UUID is required — Apple strips iBeacon data from BLE\r\n * advertisements, making wildcard discovery impossible. When you pass an empty\r\n * array, the module automatically uses UUIDs from paired beacons.\r\n * On Android, pass an empty array to discover all nearby iBeacons.\r\n *\r\n * @param uuids Proximity UUIDs to filter by. Empty/omitted = use paired UUIDs (iOS) or wildcard (Android).\r\n * @param scanDuration Duration in ms (default 5000)\r\n */\r\n scanForBeaconsAsync(\r\n uuids?: string[],\r\n scanDuration?: number,\r\n ): Promise<BeaconScanResult[]>;\r\n\r\n /**\r\n * Start a one-shot Eddystone beacon scan using BLE.\r\n * Discovers Eddystone-UID and Eddystone-URL frames.\r\n *\r\n * @param scanDuration Duration in ms (default 5000)\r\n */\r\n scanForEddystonesAsync(\r\n scanDuration?: number,\r\n ): Promise<EddystoneScanResult[]>;\r\n\r\n /**\r\n * Register a beacon for persistent region monitoring.\r\n */\r\n pairBeacon(\r\n identifier: string,\r\n uuid: string,\r\n major: number,\r\n minor: number,\r\n name?: string,\r\n timeoutSeconds?: number,\r\n ): void;\r\n\r\n /**\r\n * Remove a previously paired beacon.\r\n */\r\n unpairBeacon(identifier: string): void;\r\n\r\n /**\r\n * Return all currently paired beacons.\r\n */\r\n getPairedBeacons(): PairedBeacon[];\r\n\r\n /**\r\n * Register an Eddystone-UID beacon for persistent monitoring.\r\n */\r\n pairEddystone(\r\n identifier: string,\r\n namespace: string,\r\n instance: string,\r\n name?: string,\r\n timeoutSeconds?: number,\r\n ): void;\r\n\r\n /**\r\n * Remove a previously paired Eddystone beacon.\r\n */\r\n unpairEddystone(identifier: string): void;\r\n\r\n /**\r\n * Return all currently paired Eddystone beacons.\r\n */\r\n getPairedEddystones(): PairedEddystone[];\r\n\r\n /**\r\n * Set persistent notification configuration. Settings are saved and applied to all\r\n * subsequent monitoring sessions until explicitly changed.\r\n */\r\n setNotificationConfig(config: NotificationConfig): void;\r\n\r\n /**\r\n * Start background region monitoring for all paired beacons.\r\n * On Android starts a foreground service.\r\n * On iOS starts CLLocationManager region monitoring.\r\n *\r\n * Accepts a plain number (backward-compatible maxDistance shorthand) or a\r\n * MonitoringOptions object with maxDistance and/or notification overrides.\r\n */\r\n startMonitoring(options?: MonitoringOptions | number): Promise<void>;\r\n\r\n /**\r\n * Stop background region monitoring.\r\n */\r\n stopMonitoring(): Promise<void>;\r\n\r\n /**\r\n * Start a continuous BLE scan. Fires `onBeaconFound` events as beacons are detected.\r\n * Call stopContinuousScan() to end the scan.\r\n */\r\n startContinuousScan(): void;\r\n\r\n /** Stop the continuous scan started by startContinuousScan(). */\r\n stopContinuousScan(): void;\r\n\r\n /**\r\n * Cancel any in-progress one-shot scan (iBeacon or Eddystone).\r\n * The pending promise will be rejected with code \"SCAN_CANCELLED\".\r\n */\r\n cancelScan(): void;\r\n\r\n /** Request Bluetooth + Location permissions. Returns true if granted. */\r\n requestPermissionsAsync(): Promise<boolean>;\r\n\r\n /**\r\n * Check whether the app is exempt from Android battery optimizations.\r\n * Always returns true on iOS and web (no equivalent concept).\r\n */\r\n isBatteryOptimizationExempt(): boolean;\r\n\r\n /**\r\n * Request exemption from Android battery optimizations.\r\n * Opens the system dialog asking the user to whitelist this app.\r\n * Returns true if the dialog was shown (or already exempt), false on failure.\r\n * Always resolves true on iOS and web.\r\n */\r\n requestBatteryOptimizationExemption(): Promise<boolean>;\r\n\r\n /** Enable SQLite event logging. All beacon events will be persisted to a local database. */\r\n enableEventLogging(): void;\r\n\r\n /** Disable event logging. Previously logged events are retained. */\r\n disableEventLogging(): void;\r\n\r\n /**\r\n * Retrieve logged beacon events from the SQLite database.\r\n * @param options Optional filters (limit, eventType, sinceTimestamp).\r\n */\r\n getEventLogs(options?: EventLogQueryOptions): EventLogEntry[];\r\n\r\n /** Delete all logged events from the database. */\r\n clearEventLogs(): void;\r\n\r\n /** Delete the entire event log database. Also disables logging. */\r\n destroyEventLogs(): void;\r\n\r\n /**\r\n * Configure a remote API endpoint for native event forwarding.\r\n * Once set, beacon events are POSTed directly from native code,\r\n * ensuring delivery even when the JS bridge is not active (app backgrounded).\r\n *\r\n * @param url The API endpoint URL to POST events to.\r\n * @param apiKey Optional API key sent as X-CSFR-Token header.\r\n * @param id Optional identifier appended to every forwarded event payload.\r\n */\r\n setApiEndpoint(url: string, apiKey?: string, id?: string): void;\r\n\r\n /**\r\n * Return the current monitoring configuration and active state.\r\n * Option fields are undefined if not explicitly set.\r\n */\r\n getMonitoringConfig(): MonitoringConfig;\r\n\r\n /**\r\n * Return the current state snapshot for a paired monitored device.\r\n * Returns null when no paired device matches the identifier.\r\n */\r\n getMonitoredDeviceState(identifier: string): MonitoredDeviceState | null;\r\n\r\n /**\r\n * Return the current state snapshot for all paired monitored devices.\r\n */\r\n getMonitoredDeviceStates(): MonitoredDeviceState[];\r\n\r\n /**\r\n * Return the current API forwarding configuration.\r\n * Each field is `null` if not set.\r\n */\r\n getApiEndpoint(): { url: string | null; apiKey: string | null; id: string | null };\r\n}\r\n\r\nexport default requireNativeModule<ExpoBeaconModule>(\"ExpoBeacon\");\r\n"]}
@@ -1,4 +1,4 @@
1
- import type { ExpoBeaconModuleEvents, BeaconScanResult, EddystoneScanResult, PairedBeacon, PairedEddystone, EventLogQueryOptions, EventLogEntry } from "./ExpoBeacon.types";
1
+ import type { ExpoBeaconModuleEvents, BeaconScanResult, EddystoneScanResult, PairedBeacon, PairedEddystone, MonitoredDeviceState, EventLogQueryOptions, EventLogEntry } from "./ExpoBeacon.types";
2
2
  declare const stub: {
3
3
  scanForBeaconsAsync: (_uuids: string[], _scanDuration?: number) => Promise<BeaconScanResult[]>;
4
4
  scanForEddystonesAsync: (_scanDuration?: number) => Promise<EddystoneScanResult[]>;
@@ -21,6 +21,8 @@ declare const stub: {
21
21
  clearEventLogs: () => void;
22
22
  destroyEventLogs: () => void;
23
23
  getMonitoringConfig: () => never;
24
+ getMonitoredDeviceState: (_identifier: string) => MonitoredDeviceState | null;
25
+ getMonitoredDeviceStates: () => MonitoredDeviceState[];
24
26
  getApiEndpoint: () => {
25
27
  url: string | null;
26
28
  apiKey: string | null;
@@ -1 +1 @@
1
- {"version":3,"file":"ExpoBeaconModule.web.d.ts","sourceRoot":"","sources":["../src/ExpoBeaconModule.web.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,sBAAsB,EACtB,gBAAgB,EAChB,mBAAmB,EACnB,YAAY,EACZ,eAAe,EACf,oBAAoB,EACpB,aAAa,EACd,MAAM,oBAAoB,CAAC;AAM5B,QAAA,MAAM,IAAI;kCAEE,MAAM,EAAE,kBACA,MAAM,KACrB,OAAO,CAAC,gBAAgB,EAAE,CAAC;6CAEZ,MAAM,KACrB,OAAO,CAAC,mBAAmB,EAAE,CAAC;8BAElB,MAAM,SACZ,MAAM,UACL,MAAM,UACN,MAAM,KACb,IAAI;gCACqB,MAAM,KAAG,IAAI;4BACnB,YAAY,EAAE;iCAErB,MAAM,cACP,MAAM,aACP,MAAM,KAChB,IAAI;mCACwB,MAAM,KAAG,IAAI;+BACnB,eAAe,EAAE;2BACrB,OAAO,CAAC,IAAI,CAAC;0BACd,OAAO,CAAC,IAAI,CAAC;+BACR,IAAI;8BACL,IAAI;sBACZ,IAAI;qCACa,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAG,IAAI;mCAClC,OAAO,CAAC,OAAO,CAAC;8BACrB,IAAI;+BACH,IAAI;8BACH,oBAAoB,KAAG,aAAa,EAAE;0BAC5C,IAAI;4BACF,IAAI;;0BAEN;QAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE;uCACnD,OAAO;+CACC,OAAO,CAAC,OAAO,CAAC;8BAC/B,MAAM,sBAAsB,aAAa,GAAG;;;qCAGrC,MAAM,sBAAsB;CAC9D,CAAC;AAEF,eAAe,IAAI,CAAC"}
1
+ {"version":3,"file":"ExpoBeaconModule.web.d.ts","sourceRoot":"","sources":["../src/ExpoBeaconModule.web.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,sBAAsB,EACtB,gBAAgB,EAChB,mBAAmB,EACnB,YAAY,EACZ,eAAe,EACf,oBAAoB,EACpB,oBAAoB,EACpB,aAAa,EACd,MAAM,oBAAoB,CAAC;AAM5B,QAAA,MAAM,IAAI;kCAEE,MAAM,EAAE,kBACA,MAAM,KACrB,OAAO,CAAC,gBAAgB,EAAE,CAAC;6CAEZ,MAAM,KACrB,OAAO,CAAC,mBAAmB,EAAE,CAAC;8BAElB,MAAM,SACZ,MAAM,UACL,MAAM,UACN,MAAM,KACb,IAAI;gCACqB,MAAM,KAAG,IAAI;4BACnB,YAAY,EAAE;iCAErB,MAAM,cACP,MAAM,aACP,MAAM,KAChB,IAAI;mCACwB,MAAM,KAAG,IAAI;+BACnB,eAAe,EAAE;2BACrB,OAAO,CAAC,IAAI,CAAC;0BACd,OAAO,CAAC,IAAI,CAAC;+BACR,IAAI;8BACL,IAAI;sBACZ,IAAI;qCACa,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAG,IAAI;mCAClC,OAAO,CAAC,OAAO,CAAC;8BACrB,IAAI;+BACH,IAAI;8BACH,oBAAoB,KAAG,aAAa,EAAE;0BAC5C,IAAI;4BACF,IAAI;;2CAEa,MAAM,KAAG,oBAAoB,GAAG,IAAI;oCAC7C,oBAAoB,EAAE;0BAChC;QAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE;uCACnD,OAAO;+CACC,OAAO,CAAC,OAAO,CAAC;8BAC/B,MAAM,sBAAsB,aAAa,GAAG;;;qCAGrC,MAAM,sBAAsB;CAC9D,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -23,6 +23,8 @@ const stub = {
23
23
  clearEventLogs: () => notSupported(),
24
24
  destroyEventLogs: () => notSupported(),
25
25
  getMonitoringConfig: () => notSupported(),
26
+ getMonitoredDeviceState: (_identifier) => notSupported(),
27
+ getMonitoredDeviceStates: () => notSupported(),
26
28
  getApiEndpoint: () => notSupported(),
27
29
  isBatteryOptimizationExempt: () => true,
28
30
  requestBatteryOptimizationExemption: () => Promise.resolve(true),
@@ -1 +1 @@
1
- {"version":3,"file":"ExpoBeaconModule.web.js","sourceRoot":"","sources":["../src/ExpoBeaconModule.web.ts"],"names":[],"mappings":"AAUA,MAAM,YAAY,GAAG,GAAU,EAAE;IAC/B,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;AAC1D,CAAC,CAAC;AAEF,MAAM,IAAI,GAAG;IACX,mBAAmB,EAAE,CACnB,MAAgB,EAChB,aAAsB,EACO,EAAE,CAAC,YAAY,EAAE;IAChD,sBAAsB,EAAE,CACtB,aAAsB,EACU,EAAE,CAAC,YAAY,EAAE;IACnD,UAAU,EAAE,CACV,WAAmB,EACnB,KAAa,EACb,MAAc,EACd,MAAc,EACR,EAAE,CAAC,YAAY,EAAE;IACzB,YAAY,EAAE,CAAC,WAAmB,EAAQ,EAAE,CAAC,YAAY,EAAE;IAC3D,gBAAgB,EAAE,GAAmB,EAAE,CAAC,YAAY,EAAE;IACtD,aAAa,EAAE,CACb,WAAmB,EACnB,UAAkB,EAClB,SAAiB,EACX,EAAE,CAAC,YAAY,EAAE;IACzB,eAAe,EAAE,CAAC,WAAmB,EAAQ,EAAE,CAAC,YAAY,EAAE;IAC9D,mBAAmB,EAAE,GAAsB,EAAE,CAAC,YAAY,EAAE;IAC5D,eAAe,EAAE,GAAkB,EAAE,CAAC,YAAY,EAAE;IACpD,cAAc,EAAE,GAAkB,EAAE,CAAC,YAAY,EAAE;IACnD,mBAAmB,EAAE,GAAS,EAAE,CAAC,YAAY,EAAE;IAC/C,kBAAkB,EAAE,GAAS,EAAE,CAAC,YAAY,EAAE;IAC9C,UAAU,EAAE,GAAS,EAAE,CAAC,YAAY,EAAE;IACtC,qBAAqB,EAAE,CAAC,OAAgC,EAAQ,EAAE,CAAC,YAAY,EAAE;IACjF,uBAAuB,EAAE,GAAqB,EAAE,CAAC,YAAY,EAAE;IAC/D,kBAAkB,EAAE,GAAS,EAAE,CAAC,YAAY,EAAE;IAC9C,mBAAmB,EAAE,GAAS,EAAE,CAAC,YAAY,EAAE;IAC/C,YAAY,EAAE,CAAC,QAA+B,EAAmB,EAAE,CAAC,YAAY,EAAE;IAClF,cAAc,EAAE,GAAS,EAAE,CAAC,YAAY,EAAE;IAC1C,gBAAgB,EAAE,GAAS,EAAE,CAAC,YAAY,EAAE;IAC5C,mBAAmB,EAAE,GAAG,EAAE,CAAC,YAAY,EAAE;IACzC,cAAc,EAAE,GAAqE,EAAE,CAAC,YAAY,EAAE;IACtG,2BAA2B,EAAE,GAAY,EAAE,CAAC,IAAI;IAChD,mCAAmC,EAAE,GAAqB,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC;IAClF,WAAW,EAAE,CAAC,UAAwC,EAAE,SAAc,EAAE,EAAE,CAAC,CAAC;QAC1E,MAAM,EAAE,GAAG,EAAE,GAAE,CAAC;KACjB,CAAC;IACF,kBAAkB,EAAE,CAAC,UAAwC,EAAE,EAAE,GAAE,CAAC;CACrE,CAAC;AAEF,eAAe,IAAI,CAAC","sourcesContent":["import type {\r\n ExpoBeaconModuleEvents,\r\n BeaconScanResult,\r\n EddystoneScanResult,\r\n PairedBeacon,\r\n PairedEddystone,\r\n EventLogQueryOptions,\r\n EventLogEntry,\r\n} from \"./ExpoBeacon.types\";\r\n\r\nconst notSupported = (): never => {\r\n throw new Error(\"expo-beacon is not supported on web.\");\r\n};\r\n\r\nconst stub = {\r\n scanForBeaconsAsync: (\r\n _uuids: string[],\r\n _scanDuration?: number,\r\n ): Promise<BeaconScanResult[]> => notSupported(),\r\n scanForEddystonesAsync: (\r\n _scanDuration?: number,\r\n ): Promise<EddystoneScanResult[]> => notSupported(),\r\n pairBeacon: (\r\n _identifier: string,\r\n _uuid: string,\r\n _major: number,\r\n _minor: number,\r\n ): void => notSupported(),\r\n unpairBeacon: (_identifier: string): void => notSupported(),\r\n getPairedBeacons: (): PairedBeacon[] => notSupported(),\r\n pairEddystone: (\r\n _identifier: string,\r\n _namespace: string,\r\n _instance: string,\r\n ): void => notSupported(),\r\n unpairEddystone: (_identifier: string): void => notSupported(),\r\n getPairedEddystones: (): PairedEddystone[] => notSupported(),\r\n startMonitoring: (): Promise<void> => notSupported(),\r\n stopMonitoring: (): Promise<void> => notSupported(),\r\n startContinuousScan: (): void => notSupported(),\r\n stopContinuousScan: (): void => notSupported(),\r\n cancelScan: (): void => notSupported(),\r\n setNotificationConfig: (_config: Record<string, unknown>): void => notSupported(),\r\n requestPermissionsAsync: (): Promise<boolean> => notSupported(),\r\n enableEventLogging: (): void => notSupported(),\r\n disableEventLogging: (): void => notSupported(),\r\n getEventLogs: (_options?: EventLogQueryOptions): EventLogEntry[] => notSupported(),\r\n clearEventLogs: (): void => notSupported(),\r\n destroyEventLogs: (): void => notSupported(),\r\n getMonitoringConfig: () => notSupported(),\r\n getApiEndpoint: (): { url: string | null; apiKey: string | null; id: string | null } => notSupported(),\r\n isBatteryOptimizationExempt: (): boolean => true,\r\n requestBatteryOptimizationExemption: (): Promise<boolean> => Promise.resolve(true),\r\n addListener: (_eventName: keyof ExpoBeaconModuleEvents, _listener: any) => ({\r\n remove: () => {},\r\n }),\r\n removeAllListeners: (_eventName: keyof ExpoBeaconModuleEvents) => {},\r\n};\r\n\r\nexport default stub;\r\n"]}
1
+ {"version":3,"file":"ExpoBeaconModule.web.js","sourceRoot":"","sources":["../src/ExpoBeaconModule.web.ts"],"names":[],"mappings":"AAWA,MAAM,YAAY,GAAG,GAAU,EAAE;IAC/B,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;AAC1D,CAAC,CAAC;AAEF,MAAM,IAAI,GAAG;IACX,mBAAmB,EAAE,CACnB,MAAgB,EAChB,aAAsB,EACO,EAAE,CAAC,YAAY,EAAE;IAChD,sBAAsB,EAAE,CACtB,aAAsB,EACU,EAAE,CAAC,YAAY,EAAE;IACnD,UAAU,EAAE,CACV,WAAmB,EACnB,KAAa,EACb,MAAc,EACd,MAAc,EACR,EAAE,CAAC,YAAY,EAAE;IACzB,YAAY,EAAE,CAAC,WAAmB,EAAQ,EAAE,CAAC,YAAY,EAAE;IAC3D,gBAAgB,EAAE,GAAmB,EAAE,CAAC,YAAY,EAAE;IACtD,aAAa,EAAE,CACb,WAAmB,EACnB,UAAkB,EAClB,SAAiB,EACX,EAAE,CAAC,YAAY,EAAE;IACzB,eAAe,EAAE,CAAC,WAAmB,EAAQ,EAAE,CAAC,YAAY,EAAE;IAC9D,mBAAmB,EAAE,GAAsB,EAAE,CAAC,YAAY,EAAE;IAC5D,eAAe,EAAE,GAAkB,EAAE,CAAC,YAAY,EAAE;IACpD,cAAc,EAAE,GAAkB,EAAE,CAAC,YAAY,EAAE;IACnD,mBAAmB,EAAE,GAAS,EAAE,CAAC,YAAY,EAAE;IAC/C,kBAAkB,EAAE,GAAS,EAAE,CAAC,YAAY,EAAE;IAC9C,UAAU,EAAE,GAAS,EAAE,CAAC,YAAY,EAAE;IACtC,qBAAqB,EAAE,CAAC,OAAgC,EAAQ,EAAE,CAAC,YAAY,EAAE;IACjF,uBAAuB,EAAE,GAAqB,EAAE,CAAC,YAAY,EAAE;IAC/D,kBAAkB,EAAE,GAAS,EAAE,CAAC,YAAY,EAAE;IAC9C,mBAAmB,EAAE,GAAS,EAAE,CAAC,YAAY,EAAE;IAC/C,YAAY,EAAE,CAAC,QAA+B,EAAmB,EAAE,CAAC,YAAY,EAAE;IAClF,cAAc,EAAE,GAAS,EAAE,CAAC,YAAY,EAAE;IAC1C,gBAAgB,EAAE,GAAS,EAAE,CAAC,YAAY,EAAE;IAC5C,mBAAmB,EAAE,GAAG,EAAE,CAAC,YAAY,EAAE;IACzC,uBAAuB,EAAE,CAAC,WAAmB,EAA+B,EAAE,CAAC,YAAY,EAAE;IAC7F,wBAAwB,EAAE,GAA2B,EAAE,CAAC,YAAY,EAAE;IACtE,cAAc,EAAE,GAAqE,EAAE,CAAC,YAAY,EAAE;IACtG,2BAA2B,EAAE,GAAY,EAAE,CAAC,IAAI;IAChD,mCAAmC,EAAE,GAAqB,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC;IAClF,WAAW,EAAE,CAAC,UAAwC,EAAE,SAAc,EAAE,EAAE,CAAC,CAAC;QAC1E,MAAM,EAAE,GAAG,EAAE,GAAE,CAAC;KACjB,CAAC;IACF,kBAAkB,EAAE,CAAC,UAAwC,EAAE,EAAE,GAAE,CAAC;CACrE,CAAC;AAEF,eAAe,IAAI,CAAC","sourcesContent":["import type {\r\n ExpoBeaconModuleEvents,\r\n BeaconScanResult,\r\n EddystoneScanResult,\r\n PairedBeacon,\r\n PairedEddystone,\r\n MonitoredDeviceState,\r\n EventLogQueryOptions,\r\n EventLogEntry,\r\n} from \"./ExpoBeacon.types\";\r\n\r\nconst notSupported = (): never => {\r\n throw new Error(\"expo-beacon is not supported on web.\");\r\n};\r\n\r\nconst stub = {\r\n scanForBeaconsAsync: (\r\n _uuids: string[],\r\n _scanDuration?: number,\r\n ): Promise<BeaconScanResult[]> => notSupported(),\r\n scanForEddystonesAsync: (\r\n _scanDuration?: number,\r\n ): Promise<EddystoneScanResult[]> => notSupported(),\r\n pairBeacon: (\r\n _identifier: string,\r\n _uuid: string,\r\n _major: number,\r\n _minor: number,\r\n ): void => notSupported(),\r\n unpairBeacon: (_identifier: string): void => notSupported(),\r\n getPairedBeacons: (): PairedBeacon[] => notSupported(),\r\n pairEddystone: (\r\n _identifier: string,\r\n _namespace: string,\r\n _instance: string,\r\n ): void => notSupported(),\r\n unpairEddystone: (_identifier: string): void => notSupported(),\r\n getPairedEddystones: (): PairedEddystone[] => notSupported(),\r\n startMonitoring: (): Promise<void> => notSupported(),\r\n stopMonitoring: (): Promise<void> => notSupported(),\r\n startContinuousScan: (): void => notSupported(),\r\n stopContinuousScan: (): void => notSupported(),\r\n cancelScan: (): void => notSupported(),\r\n setNotificationConfig: (_config: Record<string, unknown>): void => notSupported(),\r\n requestPermissionsAsync: (): Promise<boolean> => notSupported(),\r\n enableEventLogging: (): void => notSupported(),\r\n disableEventLogging: (): void => notSupported(),\r\n getEventLogs: (_options?: EventLogQueryOptions): EventLogEntry[] => notSupported(),\r\n clearEventLogs: (): void => notSupported(),\r\n destroyEventLogs: (): void => notSupported(),\r\n getMonitoringConfig: () => notSupported(),\r\n getMonitoredDeviceState: (_identifier: string): MonitoredDeviceState | null => notSupported(),\r\n getMonitoredDeviceStates: (): MonitoredDeviceState[] => notSupported(),\r\n getApiEndpoint: (): { url: string | null; apiKey: string | null; id: string | null } => notSupported(),\r\n isBatteryOptimizationExempt: (): boolean => true,\r\n requestBatteryOptimizationExemption: (): Promise<boolean> => Promise.resolve(true),\r\n addListener: (_eventName: keyof ExpoBeaconModuleEvents, _listener: any) => ({\r\n remove: () => {},\r\n }),\r\n removeAllListeners: (_eventName: keyof ExpoBeaconModuleEvents) => {},\r\n};\r\n\r\nexport default stub;\r\n"]}
package/build/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  export { default } from "./ExpoBeaconModule";
2
- export type { BeaconScanResult, PairedBeacon, BeaconRegionEvent, BeaconDistanceEvent, BeaconTimeoutEvent, ExpoBeaconModuleEvents, NotificationConfig, MonitoringOptions, MonitoringConfig, BeaconNotificationConfig, ForegroundServiceConfig, NotificationChannelConfig, EddystoneFrameType, EddystoneScanResult, PairedEddystone, EddystoneRegionEvent, EddystoneDistanceEvent, EddystoneTimeoutEvent, EventLogQueryOptions, EventLogEntry, } from "./ExpoBeacon.types";
2
+ export type { BeaconScanResult, PairedBeacon, BeaconRegionEvent, BeaconDistanceEvent, BeaconTimeoutEvent, ExpoBeaconModuleEvents, NotificationConfig, MonitoringOptions, MonitoringConfig, MonitoredDeviceState, BeaconNotificationConfig, ForegroundServiceConfig, NotificationChannelConfig, EddystoneFrameType, EddystoneScanResult, PairedEddystone, EddystoneRegionEvent, EddystoneDistanceEvent, EddystoneTimeoutEvent, EventLogQueryOptions, EventLogEntry, } from "./ExpoBeacon.types";
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAG7C,YAAY,EACV,gBAAgB,EAChB,YAAY,EACZ,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,sBAAsB,EACtB,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,wBAAwB,EACxB,uBAAuB,EACvB,yBAAyB,EACzB,kBAAkB,EAClB,mBAAmB,EACnB,eAAe,EACf,oBAAoB,EACpB,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,EACpB,aAAa,GACd,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAG7C,YAAY,EACV,gBAAgB,EAChB,YAAY,EACZ,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,sBAAsB,EACtB,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,oBAAoB,EACpB,wBAAwB,EACxB,uBAAuB,EACvB,yBAAyB,EACzB,kBAAkB,EAClB,mBAAmB,EACnB,eAAe,EACf,oBAAoB,EACpB,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,EACpB,aAAa,GACd,MAAM,oBAAoB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iCAAiC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC","sourcesContent":["// Native module (default export)\r\nexport { default } from \"./ExpoBeaconModule\";\r\n\r\n// All public types\r\nexport type {\r\n BeaconScanResult,\r\n PairedBeacon,\r\n BeaconRegionEvent,\r\n BeaconDistanceEvent,\r\n BeaconTimeoutEvent,\r\n ExpoBeaconModuleEvents,\r\n NotificationConfig,\r\n MonitoringOptions,\r\n MonitoringConfig,\r\n BeaconNotificationConfig,\r\n ForegroundServiceConfig,\r\n NotificationChannelConfig,\r\n EddystoneFrameType,\r\n EddystoneScanResult,\r\n PairedEddystone,\r\n EddystoneRegionEvent,\r\n EddystoneDistanceEvent,\r\n EddystoneTimeoutEvent,\r\n EventLogQueryOptions,\r\n EventLogEntry,\r\n} from \"./ExpoBeacon.types\";\r\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iCAAiC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC","sourcesContent":["// Native module (default export)\r\nexport { default } from \"./ExpoBeaconModule\";\r\n\r\n// All public types\r\nexport type {\r\n BeaconScanResult,\r\n PairedBeacon,\r\n BeaconRegionEvent,\r\n BeaconDistanceEvent,\r\n BeaconTimeoutEvent,\r\n ExpoBeaconModuleEvents,\r\n NotificationConfig,\r\n MonitoringOptions,\r\n MonitoringConfig,\r\n MonitoredDeviceState,\r\n BeaconNotificationConfig,\r\n ForegroundServiceConfig,\r\n NotificationChannelConfig,\r\n EddystoneFrameType,\r\n EddystoneScanResult,\r\n PairedEddystone,\r\n EddystoneRegionEvent,\r\n EddystoneDistanceEvent,\r\n EddystoneTimeoutEvent,\r\n EventLogQueryOptions,\r\n EventLogEntry,\r\n} from \"./ExpoBeacon.types\";\r\n"]}
@@ -535,6 +535,14 @@ public class ExpoBeaconModule: Module {
535
535
  return result
536
536
  }
537
537
 
538
+ Function("getMonitoredDeviceState") { (identifier: String) -> [String: Any?]? in
539
+ return self.buildMonitoredDeviceState(identifier: identifier)
540
+ }
541
+
542
+ Function("getMonitoredDeviceStates") { () -> [[String: Any?]] in
543
+ return self.buildMonitoredDeviceStates()
544
+ }
545
+
538
546
  // MARK: - Battery Optimization (Android-only; no-op on iOS)
539
547
 
540
548
  Function("isBatteryOptimizationExempt") { () -> Bool in
@@ -1057,6 +1065,63 @@ public class ExpoBeaconModule: Module {
1057
1065
  return value
1058
1066
  }
1059
1067
 
1068
+ private func buildMonitoredDeviceState(identifier: String) -> [String: Any?]? {
1069
+ if let pairedBeacon = loadPairedBeaconsRaw().first(where: { ($0["identifier"] as? String) == identifier }) {
1070
+ return makeMonitoredIBeaconState(from: pairedBeacon)
1071
+ }
1072
+ if let pairedEddystone = loadPairedEddystonesRaw().first(where: { ($0["identifier"] as? String) == identifier }) {
1073
+ return makeMonitoredEddystoneState(from: pairedEddystone)
1074
+ }
1075
+ return nil
1076
+ }
1077
+
1078
+ private func buildMonitoredDeviceStates() -> [[String: Any?]] {
1079
+ let beaconStates = loadPairedBeaconsRaw().map { makeMonitoredIBeaconState(from: $0) }
1080
+ let eddystoneStates = loadPairedEddystonesRaw().map { makeMonitoredEddystoneState(from: $0) }
1081
+ return beaconStates + eddystoneStates
1082
+ }
1083
+
1084
+ private func makeMonitoredIBeaconState(from paired: [String: Any]) -> [String: Any?] {
1085
+ let identifier = paired["identifier"] as? String ?? ""
1086
+ let isEntered = enteredRegions.contains(identifier)
1087
+ let major = (paired["major"] as? Int) ?? (paired["major"] as? NSNumber)?.intValue ?? 0
1088
+ let minor = (paired["minor"] as? Int) ?? (paired["minor"] as? NSNumber)?.intValue ?? 0
1089
+
1090
+ return [
1091
+ "kind": "ibeacon",
1092
+ "identifier": identifier,
1093
+ "uuid": paired["uuid"] as? String ?? "",
1094
+ "major": major,
1095
+ "minor": minor,
1096
+ "state": isEntered ? "entered" : "exited",
1097
+ "distance": normalizedMonitoringDistance(identifier: identifier, isEntered: isEntered)
1098
+ ]
1099
+ }
1100
+
1101
+ private func makeMonitoredEddystoneState(from paired: [String: Any]) -> [String: Any?] {
1102
+ let identifier = paired["identifier"] as? String ?? ""
1103
+ let isEntered = eddystoneEnteredRegions.contains(identifier)
1104
+
1105
+ return [
1106
+ "kind": "eddystone",
1107
+ "identifier": identifier,
1108
+ "namespace": paired["namespace"] as? String ?? "",
1109
+ "instance": paired["instance"] as? String ?? "",
1110
+ "state": isEntered ? "entered" : "exited",
1111
+ "distance": normalizedMonitoringDistance(identifier: identifier, isEntered: isEntered)
1112
+ ]
1113
+ }
1114
+
1115
+ private func normalizedMonitoringDistance(identifier: String, isEntered: Bool) -> Double? {
1116
+ guard isEntered,
1117
+ let distance = smoothedDistances[identifier],
1118
+ distance.isFinite,
1119
+ distance >= 0 else {
1120
+ return nil
1121
+ }
1122
+ return distance
1123
+ }
1124
+
1060
1125
  private func migrateUserDefaultsIfNeeded() {
1061
1126
  let migrationKey = "expo.beacon.migrated_to_suite_v1"
1062
1127
  guard !defaults.bool(forKey: migrationKey) else { return }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-beacon",
3
- "version": "0.6.19",
3
+ "version": "0.6.20",
4
4
  "description": "Expo module for scanning, pairing, and monitoring iBeacons on Android and iOS",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -133,6 +133,28 @@ export type MonitoringConfig = {
133
133
  notifications?: NotificationConfig;
134
134
  };
135
135
 
136
+ /** Current state snapshot for a paired monitored device. */
137
+ export type MonitoredDeviceState =
138
+ | {
139
+ kind: "ibeacon";
140
+ identifier: string;
141
+ uuid: string;
142
+ major: number;
143
+ minor: number;
144
+ state: "entered" | "exited";
145
+ /** Current distance in metres, or null when exited or no live reading is available. */
146
+ distance: number | null;
147
+ }
148
+ | {
149
+ kind: "eddystone";
150
+ identifier: string;
151
+ namespace: string;
152
+ instance: string;
153
+ state: "entered" | "exited";
154
+ /** Current distance in metres, or null when exited or no live reading is available. */
155
+ distance: number | null;
156
+ };
157
+
136
158
  /** Options accepted by startMonitoring(). */
137
159
  export type MonitoringOptions = {
138
160
  /**
@@ -9,6 +9,7 @@ import {
9
9
  NotificationConfig,
10
10
  MonitoringOptions,
11
11
  MonitoringConfig,
12
+ MonitoredDeviceState,
12
13
  EventLogQueryOptions,
13
14
  EventLogEntry,
14
15
  } from "./ExpoBeacon.types";
@@ -172,6 +173,17 @@ declare class ExpoBeaconModule extends NativeModule<ExpoBeaconModuleEvents> {
172
173
  */
173
174
  getMonitoringConfig(): MonitoringConfig;
174
175
 
176
+ /**
177
+ * Return the current state snapshot for a paired monitored device.
178
+ * Returns null when no paired device matches the identifier.
179
+ */
180
+ getMonitoredDeviceState(identifier: string): MonitoredDeviceState | null;
181
+
182
+ /**
183
+ * Return the current state snapshot for all paired monitored devices.
184
+ */
185
+ getMonitoredDeviceStates(): MonitoredDeviceState[];
186
+
175
187
  /**
176
188
  * Return the current API forwarding configuration.
177
189
  * Each field is `null` if not set.
@@ -4,6 +4,7 @@ import type {
4
4
  EddystoneScanResult,
5
5
  PairedBeacon,
6
6
  PairedEddystone,
7
+ MonitoredDeviceState,
7
8
  EventLogQueryOptions,
8
9
  EventLogEntry,
9
10
  } from "./ExpoBeacon.types";
@@ -48,6 +49,8 @@ const stub = {
48
49
  clearEventLogs: (): void => notSupported(),
49
50
  destroyEventLogs: (): void => notSupported(),
50
51
  getMonitoringConfig: () => notSupported(),
52
+ getMonitoredDeviceState: (_identifier: string): MonitoredDeviceState | null => notSupported(),
53
+ getMonitoredDeviceStates: (): MonitoredDeviceState[] => notSupported(),
51
54
  getApiEndpoint: (): { url: string | null; apiKey: string | null; id: string | null } => notSupported(),
52
55
  isBatteryOptimizationExempt: (): boolean => true,
53
56
  requestBatteryOptimizationExemption: (): Promise<boolean> => Promise.resolve(true),
package/src/index.ts CHANGED
@@ -12,6 +12,7 @@ export type {
12
12
  NotificationConfig,
13
13
  MonitoringOptions,
14
14
  MonitoringConfig,
15
+ MonitoredDeviceState,
15
16
  BeaconNotificationConfig,
16
17
  ForegroundServiceConfig,
17
18
  NotificationChannelConfig,