expo-beacon 0.3.2 → 0.4.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/README.md +253 -14
- package/android/src/main/java/expo/modules/beacon/BeaconEventReceiver.kt +42 -18
- package/android/src/main/java/expo/modules/beacon/BeaconForegroundService.kt +63 -3
- package/android/src/main/java/expo/modules/beacon/ExpoBeaconModule.kt +172 -12
- package/build/ExpoBeacon.types.d.ts +45 -1
- package/build/ExpoBeacon.types.d.ts.map +1 -1
- package/build/ExpoBeacon.types.js.map +1 -1
- package/build/ExpoBeaconModule.d.ts +75 -1
- package/build/ExpoBeaconModule.d.ts.map +1 -1
- package/build/ExpoBeaconModule.js +1 -9
- package/build/ExpoBeaconModule.js.map +1 -1
- package/build/ExpoBeaconModule.web.d.ts +5 -1
- package/build/ExpoBeaconModule.web.d.ts.map +1 -1
- package/build/ExpoBeaconModule.web.js +4 -0
- package/build/ExpoBeaconModule.web.js.map +1 -1
- package/build/index.d.ts +1 -1
- package/build/index.d.ts.map +1 -1
- package/build/index.js.map +1 -1
- package/ios/ExpoBeaconModule.swift +408 -39
- package/package.json +1 -1
- package/src/ExpoBeacon.types.ts +50 -1
- package/src/ExpoBeaconModule.ts +32 -11
- package/src/ExpoBeaconModule.web.ts +12 -0
- package/src/index.ts +5 -0
|
@@ -21,6 +21,8 @@ import org.json.JSONObject
|
|
|
21
21
|
|
|
22
22
|
private const val PREFS_NAME = "expo.beacon.paired"
|
|
23
23
|
private const val PREFS_KEY = "paired_beacons"
|
|
24
|
+
private const val EDDYSTONE_PREFS_NAME = "expo.beacon.paired_eddystones"
|
|
25
|
+
private const val EDDYSTONE_PREFS_KEY = "paired_eddystones"
|
|
24
26
|
private const val NOTIFICATION_CONFIG_PREFS = "expo.beacon.notification_config"
|
|
25
27
|
|
|
26
28
|
class ExpoBeaconModule : Module(), BeaconConsumer {
|
|
@@ -35,6 +37,18 @@ class ExpoBeaconModule : Module(), BeaconConsumer {
|
|
|
35
37
|
BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25")
|
|
36
38
|
)
|
|
37
39
|
}
|
|
40
|
+
// Register Eddystone-UID parser
|
|
41
|
+
if (manager.beaconParsers.none { it.layout?.contains("s:0-1=feaa,m:2-2=00") == true }) {
|
|
42
|
+
manager.beaconParsers.add(
|
|
43
|
+
BeaconParser().setBeaconLayout("s:0-1=feaa,m:2-2=00,p:3-3:-41,i:4-13,i:14-19")
|
|
44
|
+
)
|
|
45
|
+
}
|
|
46
|
+
// Register Eddystone-URL parser
|
|
47
|
+
if (manager.beaconParsers.none { it.layout?.contains("s:0-1=feaa,m:2-2=10") == true }) {
|
|
48
|
+
manager.beaconParsers.add(
|
|
49
|
+
BeaconParser().setBeaconLayout("s:0-1=feaa,m:2-2=10,p:3-3:-41,i:4-20v")
|
|
50
|
+
)
|
|
51
|
+
}
|
|
38
52
|
}
|
|
39
53
|
}
|
|
40
54
|
|
|
@@ -42,6 +56,10 @@ class ExpoBeaconModule : Module(), BeaconConsumer {
|
|
|
42
56
|
appContext.reactContext!!.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
|
|
43
57
|
}
|
|
44
58
|
|
|
59
|
+
private val eddystonePrefs: SharedPreferences by lazy {
|
|
60
|
+
appContext.reactContext!!.getSharedPreferences(EDDYSTONE_PREFS_NAME, Context.MODE_PRIVATE)
|
|
61
|
+
}
|
|
62
|
+
|
|
45
63
|
// Coroutine scope tied to module lifecycle
|
|
46
64
|
private val moduleScope = CoroutineScope(Dispatchers.Main + SupervisorJob())
|
|
47
65
|
|
|
@@ -50,6 +68,7 @@ class ExpoBeaconModule : Module(), BeaconConsumer {
|
|
|
50
68
|
|
|
51
69
|
// Current one-shot scan state
|
|
52
70
|
private var scanPromise: Promise? = null
|
|
71
|
+
private var eddystoneScanPromise: Promise? = null
|
|
53
72
|
private var scanJob: Job? = null
|
|
54
73
|
private val scanResults = mutableListOf<Beacon>()
|
|
55
74
|
private var scanUuidFilter: Set<String> = emptySet()
|
|
@@ -62,10 +81,10 @@ class ExpoBeaconModule : Module(), BeaconConsumer {
|
|
|
62
81
|
override fun definition() = ModuleDefinition {
|
|
63
82
|
Name("ExpoBeacon")
|
|
64
83
|
|
|
65
|
-
Events("onBeaconEnter", "onBeaconExit", "onBeaconDistance", "onBeaconFound")
|
|
84
|
+
Events("onBeaconEnter", "onBeaconExit", "onBeaconDistance", "onBeaconFound", "onEddystoneFound", "onEddystoneEnter", "onEddystoneExit", "onEddystoneDistance")
|
|
66
85
|
|
|
67
86
|
AsyncFunction("scanForBeaconsAsync") { uuids: List<String>?, scanDurationMs: Int, promise: Promise ->
|
|
68
|
-
if (scanPromise != null) {
|
|
87
|
+
if (scanPromise != null || eddystoneScanPromise != null) {
|
|
69
88
|
promise.reject("SCAN_IN_PROGRESS", "A scan is already running", null)
|
|
70
89
|
return@AsyncFunction
|
|
71
90
|
}
|
|
@@ -114,6 +133,29 @@ class ExpoBeaconModule : Module(), BeaconConsumer {
|
|
|
114
133
|
null
|
|
115
134
|
}
|
|
116
135
|
|
|
136
|
+
AsyncFunction("scanForEddystonesAsync") { scanDurationMs: Int, promise: Promise ->
|
|
137
|
+
if (scanPromise != null || eddystoneScanPromise != null) {
|
|
138
|
+
promise.reject("SCAN_IN_PROGRESS", "A scan is already running", null)
|
|
139
|
+
return@AsyncFunction
|
|
140
|
+
}
|
|
141
|
+
scanResults.clear()
|
|
142
|
+
eddystoneScanPromise = promise
|
|
143
|
+
|
|
144
|
+
beaconManager.addRangeNotifier(scanRangeNotifier)
|
|
145
|
+
|
|
146
|
+
if (!isBoundForScan) {
|
|
147
|
+
isBoundForScan = true
|
|
148
|
+
beaconManager.bind(this@ExpoBeaconModule)
|
|
149
|
+
} else {
|
|
150
|
+
startScanRanging()
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
scanJob = moduleScope.launch {
|
|
154
|
+
delay(scanDurationMs.toLong())
|
|
155
|
+
stopEddystoneScanAndResolve()
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
117
159
|
Function("pairBeacon") { identifier: String, uuid: String, major: Int, minor: Int ->
|
|
118
160
|
// Validate UUID format
|
|
119
161
|
try {
|
|
@@ -169,6 +211,45 @@ class ExpoBeaconModule : Module(), BeaconConsumer {
|
|
|
169
211
|
}
|
|
170
212
|
}
|
|
171
213
|
|
|
214
|
+
Function("pairEddystone") { identifier: String, namespace: String, instance: String ->
|
|
215
|
+
val eddystones = loadPairedEddystonesJson()
|
|
216
|
+
val filtered = (0 until eddystones.length())
|
|
217
|
+
.map { eddystones.getJSONObject(it) }
|
|
218
|
+
.filter { it.getString("identifier") != identifier }
|
|
219
|
+
|
|
220
|
+
val arr = JSONArray()
|
|
221
|
+
filtered.forEach { arr.put(it) }
|
|
222
|
+
val newEddystone = JSONObject().apply {
|
|
223
|
+
put("identifier", identifier)
|
|
224
|
+
put("namespace", namespace)
|
|
225
|
+
put("instance", instance)
|
|
226
|
+
}
|
|
227
|
+
arr.put(newEddystone)
|
|
228
|
+
eddystonePrefs.edit().putString(EDDYSTONE_PREFS_KEY, arr.toString()).apply()
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
Function("unpairEddystone") { identifier: String ->
|
|
232
|
+
val eddystones = loadPairedEddystonesJson()
|
|
233
|
+
val filtered = (0 until eddystones.length())
|
|
234
|
+
.map { eddystones.getJSONObject(it) }
|
|
235
|
+
.filter { it.getString("identifier") != identifier }
|
|
236
|
+
val arr = JSONArray()
|
|
237
|
+
filtered.forEach { arr.put(it) }
|
|
238
|
+
eddystonePrefs.edit().putString(EDDYSTONE_PREFS_KEY, arr.toString()).apply()
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
Function("getPairedEddystones") {
|
|
242
|
+
val eddystones = loadPairedEddystonesJson()
|
|
243
|
+
(0 until eddystones.length()).map { i ->
|
|
244
|
+
val e = eddystones.getJSONObject(i)
|
|
245
|
+
mapOf(
|
|
246
|
+
"identifier" to e.getString("identifier"),
|
|
247
|
+
"namespace" to e.getString("namespace"),
|
|
248
|
+
"instance" to e.getString("instance")
|
|
249
|
+
)
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
172
253
|
AsyncFunction("startMonitoring") { options: Any?, promise: Promise ->
|
|
173
254
|
val ctx = appContext.reactContext!!
|
|
174
255
|
var maxDistance: Double? = null
|
|
@@ -268,6 +349,8 @@ class ExpoBeaconModule : Module(), BeaconConsumer {
|
|
|
268
349
|
OnDestroy {
|
|
269
350
|
this@ExpoBeaconModule.unregisterEventReceiver()
|
|
270
351
|
this@ExpoBeaconModule.scanJob?.cancel()
|
|
352
|
+
this@ExpoBeaconModule.scanPromise = null
|
|
353
|
+
this@ExpoBeaconModule.eddystoneScanPromise = null
|
|
271
354
|
this@ExpoBeaconModule.moduleScope.cancel()
|
|
272
355
|
if (this@ExpoBeaconModule.continuousScanActive) {
|
|
273
356
|
this@ExpoBeaconModule.continuousScanActive = false
|
|
@@ -284,7 +367,7 @@ class ExpoBeaconModule : Module(), BeaconConsumer {
|
|
|
284
367
|
// --- BeaconConsumer (for scan binding) ---
|
|
285
368
|
|
|
286
369
|
override fun onBeaconServiceConnect() {
|
|
287
|
-
if (scanPromise != null) startScanRanging()
|
|
370
|
+
if (scanPromise != null || eddystoneScanPromise != null) startScanRanging()
|
|
288
371
|
if (continuousScanActive) startContinuousRanging()
|
|
289
372
|
}
|
|
290
373
|
|
|
@@ -315,14 +398,18 @@ class ExpoBeaconModule : Module(), BeaconConsumer {
|
|
|
315
398
|
|
|
316
399
|
private val continuousScanRangeNotifier = RangeNotifier { beacons, _ ->
|
|
317
400
|
beacons.forEach { beacon ->
|
|
318
|
-
|
|
319
|
-
"
|
|
320
|
-
|
|
321
|
-
"
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
401
|
+
if (beacon.serviceUuid == 0xfeaa) {
|
|
402
|
+
sendEvent("onEddystoneFound", eddystoneBeaconToMap(beacon))
|
|
403
|
+
} else {
|
|
404
|
+
sendEvent("onBeaconFound", mapOf(
|
|
405
|
+
"uuid" to beacon.id1.toString().uppercase(),
|
|
406
|
+
"major" to beacon.id2.toInt(),
|
|
407
|
+
"minor" to beacon.id3.toInt(),
|
|
408
|
+
"rssi" to beacon.rssi,
|
|
409
|
+
"distance" to beacon.distance,
|
|
410
|
+
"txPower" to beacon.txPower
|
|
411
|
+
))
|
|
412
|
+
}
|
|
326
413
|
}
|
|
327
414
|
}
|
|
328
415
|
|
|
@@ -341,7 +428,7 @@ class ExpoBeaconModule : Module(), BeaconConsumer {
|
|
|
341
428
|
} catch (_: RemoteException) {}
|
|
342
429
|
beaconManager.removeRangeNotifier(scanRangeNotifier)
|
|
343
430
|
|
|
344
|
-
val results = scanResults.distinctBy { "${it.id1}:${it.id2}:${it.id3}" }.map { beacon ->
|
|
431
|
+
val results = scanResults.filter { it.serviceUuid != 0xfeaa }.distinctBy { "${it.id1}:${it.id2}:${it.id3}" }.map { beacon ->
|
|
345
432
|
mapOf(
|
|
346
433
|
"uuid" to beacon.id1.toString().uppercase(),
|
|
347
434
|
"major" to beacon.id2.toInt(),
|
|
@@ -356,6 +443,74 @@ class ExpoBeaconModule : Module(), BeaconConsumer {
|
|
|
356
443
|
scanUuidFilter = emptySet()
|
|
357
444
|
}
|
|
358
445
|
|
|
446
|
+
private fun stopEddystoneScanAndResolve() {
|
|
447
|
+
scanJob?.cancel()
|
|
448
|
+
try {
|
|
449
|
+
beaconManager.stopRangingBeaconsInRegion(Region("scanRegion", null, null, null))
|
|
450
|
+
} catch (_: RemoteException) {}
|
|
451
|
+
beaconManager.removeRangeNotifier(scanRangeNotifier)
|
|
452
|
+
|
|
453
|
+
val results = scanResults
|
|
454
|
+
.filter { it.serviceUuid == 0xfeaa }
|
|
455
|
+
.distinctBy {
|
|
456
|
+
if (it.identifiers.size >= 2) "uid:${it.id1}:${it.id2}"
|
|
457
|
+
else "url:${it.id1}"
|
|
458
|
+
}
|
|
459
|
+
.map { eddystoneBeaconToMap(it) }
|
|
460
|
+
|
|
461
|
+
eddystoneScanPromise?.resolve(results)
|
|
462
|
+
eddystoneScanPromise = null
|
|
463
|
+
scanResults.clear()
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
private fun eddystoneBeaconToMap(beacon: Beacon): Map<String, Any> {
|
|
467
|
+
val map = mutableMapOf<String, Any>(
|
|
468
|
+
"rssi" to beacon.rssi,
|
|
469
|
+
"distance" to beacon.distance,
|
|
470
|
+
"txPower" to beacon.txPower
|
|
471
|
+
)
|
|
472
|
+
if (beacon.identifiers.size >= 2) {
|
|
473
|
+
map["frameType"] = "uid"
|
|
474
|
+
map["namespace"] = beacon.id1.toString().removePrefix("0x")
|
|
475
|
+
map["instance"] = beacon.id2.toString().removePrefix("0x")
|
|
476
|
+
} else {
|
|
477
|
+
map["frameType"] = "url"
|
|
478
|
+
map["url"] = decodeEddystoneUrl(beacon.id1.toByteArray())
|
|
479
|
+
}
|
|
480
|
+
return map
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
private fun decodeEddystoneUrl(bytes: ByteArray): String {
|
|
484
|
+
if (bytes.isEmpty()) return ""
|
|
485
|
+
val schemes = arrayOf("http://www.", "https://www.", "http://", "https://")
|
|
486
|
+
val suffixes = mapOf(
|
|
487
|
+
0x00.toByte() to ".com/", 0x01.toByte() to ".org/",
|
|
488
|
+
0x02.toByte() to ".edu/", 0x03.toByte() to ".net/",
|
|
489
|
+
0x04.toByte() to ".info/", 0x05.toByte() to ".biz/",
|
|
490
|
+
0x06.toByte() to ".gov/",
|
|
491
|
+
0x07.toByte() to ".com", 0x08.toByte() to ".org",
|
|
492
|
+
0x09.toByte() to ".edu", 0x0A.toByte() to ".net",
|
|
493
|
+
0x0B.toByte() to ".info", 0x0C.toByte() to ".biz",
|
|
494
|
+
0x0D.toByte() to ".gov"
|
|
495
|
+
)
|
|
496
|
+
val schemeIndex = bytes[0].toInt() and 0xFF
|
|
497
|
+
if (schemeIndex >= schemes.size) return ""
|
|
498
|
+
val sb = StringBuilder(schemes[schemeIndex])
|
|
499
|
+
for (i in 1 until bytes.size) {
|
|
500
|
+
val b = bytes[i]
|
|
501
|
+
val suffix = suffixes[b]
|
|
502
|
+
if (suffix != null) {
|
|
503
|
+
sb.append(suffix)
|
|
504
|
+
} else {
|
|
505
|
+
val c = b.toInt() and 0xFF
|
|
506
|
+
if (c in 0x20..0x7E) {
|
|
507
|
+
sb.append(c.toChar())
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
return sb.toString()
|
|
512
|
+
}
|
|
513
|
+
|
|
359
514
|
// --- Notification config helpers ---
|
|
360
515
|
|
|
361
516
|
private fun mapToJson(map: Map<String, Any?>): JSONObject {
|
|
@@ -380,6 +535,11 @@ class ExpoBeaconModule : Module(), BeaconConsumer {
|
|
|
380
535
|
return try { JSONArray(json) } catch (_: Exception) { JSONArray() }
|
|
381
536
|
}
|
|
382
537
|
|
|
538
|
+
private fun loadPairedEddystonesJson(): JSONArray {
|
|
539
|
+
val json = eddystonePrefs.getString(EDDYSTONE_PREFS_KEY, "[]") ?: "[]"
|
|
540
|
+
return try { JSONArray(json) } catch (_: Exception) { JSONArray() }
|
|
541
|
+
}
|
|
542
|
+
|
|
383
543
|
// --- Event receiver registration ---
|
|
384
544
|
|
|
385
545
|
private fun registerEventReceiver() {
|
|
@@ -90,12 +90,56 @@ export type MonitoringOptions = {
|
|
|
90
90
|
/** Notification configuration overrides to apply for this monitoring session. */
|
|
91
91
|
notifications?: NotificationConfig;
|
|
92
92
|
};
|
|
93
|
+
/** Eddystone frame type. */
|
|
94
|
+
export type EddystoneFrameType = "uid" | "url";
|
|
95
|
+
/** Raw Eddystone beacon discovered during a scan. */
|
|
96
|
+
export type EddystoneScanResult = {
|
|
97
|
+
frameType: EddystoneFrameType;
|
|
98
|
+
/** 10-byte namespace ID as hex string (20 chars). Present for UID frames. */
|
|
99
|
+
namespace?: string;
|
|
100
|
+
/** 6-byte instance ID as hex string (12 chars). Present for UID frames. */
|
|
101
|
+
instance?: string;
|
|
102
|
+
/** Decoded URL. Present for URL frames. */
|
|
103
|
+
url?: string;
|
|
104
|
+
rssi: number;
|
|
105
|
+
distance: number;
|
|
106
|
+
txPower: number;
|
|
107
|
+
};
|
|
108
|
+
/** An Eddystone-UID beacon that has been paired/registered for monitoring. */
|
|
109
|
+
export type PairedEddystone = {
|
|
110
|
+
identifier: string;
|
|
111
|
+
/** 10-byte namespace ID as hex string (20 chars). */
|
|
112
|
+
namespace: string;
|
|
113
|
+
/** 6-byte instance ID as hex string (12 chars). */
|
|
114
|
+
instance: string;
|
|
115
|
+
};
|
|
116
|
+
/** Payload for Eddystone enter/exit region events. */
|
|
117
|
+
export type EddystoneRegionEvent = {
|
|
118
|
+
identifier: string;
|
|
119
|
+
namespace: string;
|
|
120
|
+
instance: string;
|
|
121
|
+
event: "enter" | "exit";
|
|
122
|
+
/** Measured distance in metres at the time of the event (–1 if unavailable). */
|
|
123
|
+
distance: number;
|
|
124
|
+
};
|
|
125
|
+
/** Payload for periodic Eddystone distance update events during monitoring. */
|
|
126
|
+
export type EddystoneDistanceEvent = {
|
|
127
|
+
identifier: string;
|
|
128
|
+
namespace: string;
|
|
129
|
+
instance: string;
|
|
130
|
+
distance: number;
|
|
131
|
+
};
|
|
93
132
|
/** Module event map. */
|
|
94
133
|
export type ExpoBeaconModuleEvents = {
|
|
95
134
|
onBeaconEnter: (params: BeaconRegionEvent) => void;
|
|
96
135
|
onBeaconExit: (params: BeaconRegionEvent) => void;
|
|
97
136
|
onBeaconDistance: (params: BeaconDistanceEvent) => void;
|
|
98
|
-
/** Fired continuously during a live scan as each
|
|
137
|
+
/** Fired continuously during a live scan as each iBeacon is detected. */
|
|
99
138
|
onBeaconFound: (params: BeaconScanResult) => void;
|
|
139
|
+
/** Fired continuously during a live scan as each Eddystone beacon is detected. */
|
|
140
|
+
onEddystoneFound: (params: EddystoneScanResult) => void;
|
|
141
|
+
onEddystoneEnter: (params: EddystoneRegionEvent) => void;
|
|
142
|
+
onEddystoneExit: (params: EddystoneRegionEvent) => void;
|
|
143
|
+
onEddystoneDistance: (params: EddystoneDistanceEvent) => void;
|
|
100
144
|
};
|
|
101
145
|
//# sourceMappingURL=ExpoBeacon.types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoBeacon.types.d.ts","sourceRoot":"","sources":["../src/ExpoBeacon.types.ts"],"names":[],"mappings":"AAAA,2CAA2C;AAC3C,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,+DAA+D;AAC/D,MAAM,MAAM,YAAY,GAAG;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,4CAA4C;AAC5C,MAAM,MAAM,iBAAiB,GAAG;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC;IACxB,gFAAgF;IAChF,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,qEAAqE;AACrE,MAAM,MAAM,mBAAmB,GAAG;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,+DAA+D;AAC/D,MAAM,MAAM,wBAAwB,GAAG;IACrC,+DAA+D;IAC/D,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,qEAAqE;IACrE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mEAAmE;IACnE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oEAAoE;IACpE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,yFAAyF;IACzF,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,mGAAmG;AACnG,MAAM,MAAM,uBAAuB,GAAG;IACpC,iFAAiF;IACjF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sGAAsG;IACtG,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gEAAgE;IAChE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,0DAA0D;AAC1D,MAAM,MAAM,yBAAyB,GAAG;IACtC,mFAAmF;IACnF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,8GAA8G;IAC9G,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,UAAU,CAAC,EAAE,KAAK,GAAG,SAAS,GAAG,MAAM,CAAC;CACzC,CAAC;AAEF,sEAAsE;AACtE,MAAM,MAAM,kBAAkB,GAAG;IAC/B,0DAA0D;IAC1D,YAAY,CAAC,EAAE,wBAAwB,CAAC;IACxC,kFAAkF;IAClF,iBAAiB,CAAC,EAAE,uBAAuB,CAAC;IAC5C,oEAAoE;IACpE,OAAO,CAAC,EAAE,yBAAyB,CAAC;CACrC,CAAC;AAEF,6CAA6C;AAC7C,MAAM,MAAM,iBAAiB,GAAG;IAC9B;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iFAAiF;IACjF,aAAa,CAAC,EAAE,kBAAkB,CAAC;CACpC,CAAC;AAEF,wBAAwB;AACxB,MAAM,MAAM,sBAAsB,GAAG;IACnC,aAAa,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACnD,YAAY,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAClD,gBAAgB,EAAE,CAAC,MAAM,EAAE,mBAAmB,KAAK,IAAI,CAAC;IACxD,
|
|
1
|
+
{"version":3,"file":"ExpoBeacon.types.d.ts","sourceRoot":"","sources":["../src/ExpoBeacon.types.ts"],"names":[],"mappings":"AAAA,2CAA2C;AAC3C,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,+DAA+D;AAC/D,MAAM,MAAM,YAAY,GAAG;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,4CAA4C;AAC5C,MAAM,MAAM,iBAAiB,GAAG;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC;IACxB,gFAAgF;IAChF,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,qEAAqE;AACrE,MAAM,MAAM,mBAAmB,GAAG;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,+DAA+D;AAC/D,MAAM,MAAM,wBAAwB,GAAG;IACrC,+DAA+D;IAC/D,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,qEAAqE;IACrE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mEAAmE;IACnE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oEAAoE;IACpE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,yFAAyF;IACzF,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,mGAAmG;AACnG,MAAM,MAAM,uBAAuB,GAAG;IACpC,iFAAiF;IACjF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sGAAsG;IACtG,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gEAAgE;IAChE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,0DAA0D;AAC1D,MAAM,MAAM,yBAAyB,GAAG;IACtC,mFAAmF;IACnF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,8GAA8G;IAC9G,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,UAAU,CAAC,EAAE,KAAK,GAAG,SAAS,GAAG,MAAM,CAAC;CACzC,CAAC;AAEF,sEAAsE;AACtE,MAAM,MAAM,kBAAkB,GAAG;IAC/B,0DAA0D;IAC1D,YAAY,CAAC,EAAE,wBAAwB,CAAC;IACxC,kFAAkF;IAClF,iBAAiB,CAAC,EAAE,uBAAuB,CAAC;IAC5C,oEAAoE;IACpE,OAAO,CAAC,EAAE,yBAAyB,CAAC;CACrC,CAAC;AAEF,6CAA6C;AAC7C,MAAM,MAAM,iBAAiB,GAAG;IAC9B;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iFAAiF;IACjF,aAAa,CAAC,EAAE,kBAAkB,CAAC;CACpC,CAAC;AAEF,4BAA4B;AAC5B,MAAM,MAAM,kBAAkB,GAAG,KAAK,GAAG,KAAK,CAAC;AAE/C,qDAAqD;AACrD,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,EAAE,kBAAkB,CAAC;IAC9B,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2CAA2C;IAC3C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,8EAA8E;AAC9E,MAAM,MAAM,eAAe,GAAG;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,SAAS,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,sDAAsD;AACtD,MAAM,MAAM,oBAAoB,GAAG;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC;IACxB,gFAAgF;IAChF,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,+EAA+E;AAC/E,MAAM,MAAM,sBAAsB,GAAG;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,wBAAwB;AACxB,MAAM,MAAM,sBAAsB,GAAG;IACnC,aAAa,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACnD,YAAY,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAClD,gBAAgB,EAAE,CAAC,MAAM,EAAE,mBAAmB,KAAK,IAAI,CAAC;IACxD,yEAAyE;IACzE,aAAa,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAClD,kFAAkF;IAClF,gBAAgB,EAAE,CAAC,MAAM,EAAE,mBAAmB,KAAK,IAAI,CAAC;IACxD,gBAAgB,EAAE,CAAC,MAAM,EAAE,oBAAoB,KAAK,IAAI,CAAC;IACzD,eAAe,EAAE,CAAC,MAAM,EAAE,oBAAoB,KAAK,IAAI,CAAC;IACxD,mBAAmB,EAAE,CAAC,MAAM,EAAE,sBAAsB,KAAK,IAAI,CAAC;CAC/D,CAAC"}
|
|
@@ -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};\r\n\r\n/** A beacon that has been paired/registered for monitoring. */\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};\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};\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};\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 /**\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/** 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 /** Notification configuration overrides to apply for this monitoring session. */\r\n notifications?: NotificationConfig;\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 continuously during a live scan as each
|
|
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};\r\n\r\n/** A beacon that has been paired/registered for monitoring. */\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};\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};\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};\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 /**\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/** 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 /** 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};\r\n\r\n/** An Eddystone-UID beacon that has been paired/registered for monitoring. */\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};\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};\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};\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 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};\r\n"]}
|
|
@@ -1,2 +1,76 @@
|
|
|
1
|
-
|
|
1
|
+
import { NativeModule } from "expo";
|
|
2
|
+
import { ExpoBeaconModuleEvents, BeaconScanResult, EddystoneScanResult, PairedBeacon, PairedEddystone, NotificationConfig, MonitoringOptions } from "./ExpoBeacon.types";
|
|
3
|
+
declare class ExpoBeaconModule extends NativeModule<ExpoBeaconModuleEvents> {
|
|
4
|
+
/**
|
|
5
|
+
* Start a one-shot iBeacon scan. Resolves with discovered beacons after scanDuration ms.
|
|
6
|
+
*
|
|
7
|
+
* Pass one or more UUIDs to scan for specific beacons (uses CoreLocation on iOS).
|
|
8
|
+
* Pass an empty array or omit to perform a wildcard scan that discovers all nearby
|
|
9
|
+
* iBeacons (uses CoreBluetooth on iOS — foreground only).
|
|
10
|
+
*
|
|
11
|
+
* @param uuids Proximity UUIDs to filter by. Empty/omitted = wildcard scan.
|
|
12
|
+
* @param scanDuration Duration in ms (default 5000)
|
|
13
|
+
*/
|
|
14
|
+
scanForBeaconsAsync(uuids?: string[], scanDuration?: number): Promise<BeaconScanResult[]>;
|
|
15
|
+
/**
|
|
16
|
+
* Start a one-shot Eddystone beacon scan using BLE.
|
|
17
|
+
* Discovers Eddystone-UID and Eddystone-URL frames.
|
|
18
|
+
*
|
|
19
|
+
* @param scanDuration Duration in ms (default 5000)
|
|
20
|
+
*/
|
|
21
|
+
scanForEddystonesAsync(scanDuration?: number): Promise<EddystoneScanResult[]>;
|
|
22
|
+
/**
|
|
23
|
+
* Register a beacon for persistent region monitoring.
|
|
24
|
+
*/
|
|
25
|
+
pairBeacon(identifier: string, uuid: string, major: number, minor: number): void;
|
|
26
|
+
/**
|
|
27
|
+
* Remove a previously paired beacon.
|
|
28
|
+
*/
|
|
29
|
+
unpairBeacon(identifier: string): void;
|
|
30
|
+
/**
|
|
31
|
+
* Return all currently paired beacons.
|
|
32
|
+
*/
|
|
33
|
+
getPairedBeacons(): PairedBeacon[];
|
|
34
|
+
/**
|
|
35
|
+
* Register an Eddystone-UID beacon for persistent monitoring.
|
|
36
|
+
*/
|
|
37
|
+
pairEddystone(identifier: string, namespace: string, instance: string): void;
|
|
38
|
+
/**
|
|
39
|
+
* Remove a previously paired Eddystone beacon.
|
|
40
|
+
*/
|
|
41
|
+
unpairEddystone(identifier: string): void;
|
|
42
|
+
/**
|
|
43
|
+
* Return all currently paired Eddystone beacons.
|
|
44
|
+
*/
|
|
45
|
+
getPairedEddystones(): PairedEddystone[];
|
|
46
|
+
/**
|
|
47
|
+
* Set persistent notification configuration. Settings are saved and applied to all
|
|
48
|
+
* subsequent monitoring sessions until explicitly changed.
|
|
49
|
+
*/
|
|
50
|
+
setNotificationConfig(config: NotificationConfig): void;
|
|
51
|
+
/**
|
|
52
|
+
* Start background region monitoring for all paired beacons.
|
|
53
|
+
* On Android starts a foreground service.
|
|
54
|
+
* On iOS starts CLLocationManager region monitoring.
|
|
55
|
+
*
|
|
56
|
+
* Accepts a plain number (backward-compatible maxDistance shorthand) or a
|
|
57
|
+
* MonitoringOptions object with maxDistance and/or notification overrides.
|
|
58
|
+
*/
|
|
59
|
+
startMonitoring(options?: MonitoringOptions | number): Promise<void>;
|
|
60
|
+
/**
|
|
61
|
+
* Stop background region monitoring.
|
|
62
|
+
*/
|
|
63
|
+
stopMonitoring(): Promise<void>;
|
|
64
|
+
/**
|
|
65
|
+
* Start a continuous BLE scan. Fires `onBeaconFound` events as beacons are detected.
|
|
66
|
+
* Call stopContinuousScan() to end the scan.
|
|
67
|
+
*/
|
|
68
|
+
startContinuousScan(): void;
|
|
69
|
+
/** Stop the continuous scan started by startContinuousScan(). */
|
|
70
|
+
stopContinuousScan(): void;
|
|
71
|
+
/** Request Bluetooth + Location permissions. Returns true if granted. */
|
|
72
|
+
requestPermissionsAsync(): Promise<boolean>;
|
|
73
|
+
}
|
|
74
|
+
declare const _default: ExpoBeaconModule;
|
|
75
|
+
export default _default;
|
|
2
76
|
//# sourceMappingURL=ExpoBeaconModule.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoBeaconModule.d.ts","sourceRoot":"","sources":["../src/ExpoBeaconModule.ts"],"names":[],"mappings":"
|
|
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,EAClB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,OAAO,gBAAiB,SAAQ,YAAY,CAAC,sBAAsB,CAAC;IACzE;;;;;;;;;OASG;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,GACZ,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,GACf,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,yEAAyE;IACzE,uBAAuB,IAAI,OAAO,CAAC,OAAO,CAAC;CAC5C;;AAED,wBAAmE"}
|
|
@@ -1,11 +1,3 @@
|
|
|
1
1
|
import { requireNativeModule } from "expo";
|
|
2
|
-
|
|
3
|
-
// eslint-disable-next-line import/no-mutable-exports
|
|
4
|
-
var module = requireNativeModule("ExpoBeacon");
|
|
5
|
-
}
|
|
6
|
-
catch {
|
|
7
|
-
throw new Error("expo-beacon: native module not found. Make sure you are using a development build " +
|
|
8
|
-
"(not Expo Go) and have run `npx expo prebuild` followed by a native rebuild.");
|
|
9
|
-
}
|
|
10
|
-
export default module;
|
|
2
|
+
export default requireNativeModule("ExpoBeacon");
|
|
11
3
|
//# sourceMappingURL=ExpoBeaconModule.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoBeaconModule.js","sourceRoot":"","sources":["../src/ExpoBeaconModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,mBAAmB,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"ExpoBeaconModule.js","sourceRoot":"","sources":["../src/ExpoBeaconModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,mBAAmB,EAAE,MAAM,MAAM,CAAC;AA+GzD,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} 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 * Pass an empty array or omit to perform a wildcard scan that discovers all nearby\r\n * iBeacons (uses CoreBluetooth on iOS — foreground only).\r\n *\r\n * @param uuids Proximity UUIDs to filter by. Empty/omitted = wildcard scan.\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 ): 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 ): 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 /** Request Bluetooth + Location permissions. Returns true if granted. */\r\n requestPermissionsAsync(): Promise<boolean>;\r\n}\r\n\r\nexport default requireNativeModule<ExpoBeaconModule>(\"ExpoBeacon\");\r\n"]}
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
import type { ExpoBeaconModuleEvents, BeaconScanResult, PairedBeacon } from "./ExpoBeacon.types";
|
|
1
|
+
import type { ExpoBeaconModuleEvents, BeaconScanResult, EddystoneScanResult, PairedBeacon, PairedEddystone } from "./ExpoBeacon.types";
|
|
2
2
|
declare const stub: {
|
|
3
3
|
scanForBeaconsAsync: (_uuids: string[], _scanDuration?: number) => Promise<BeaconScanResult[]>;
|
|
4
|
+
scanForEddystonesAsync: (_scanDuration?: number) => Promise<EddystoneScanResult[]>;
|
|
4
5
|
pairBeacon: (_identifier: string, _uuid: string, _major: number, _minor: number) => void;
|
|
5
6
|
unpairBeacon: (_identifier: string) => void;
|
|
6
7
|
getPairedBeacons: () => PairedBeacon[];
|
|
8
|
+
pairEddystone: (_identifier: string, _namespace: string, _instance: string) => void;
|
|
9
|
+
unpairEddystone: (_identifier: string) => void;
|
|
10
|
+
getPairedEddystones: () => PairedEddystone[];
|
|
7
11
|
startMonitoring: () => Promise<void>;
|
|
8
12
|
stopMonitoring: () => Promise<void>;
|
|
9
13
|
requestPermissionsAsync: () => Promise<boolean>;
|
|
@@ -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,YAAY,
|
|
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,EAChB,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;mCACJ,OAAO,CAAC,OAAO,CAAC;8BACnB,MAAM,sBAAsB,aAAa,GAAG;;;qCAGrC,MAAM,sBAAsB;CAC9D,CAAC;AAEF,eAAe,IAAI,CAAC"}
|
|
@@ -3,9 +3,13 @@ const notSupported = () => {
|
|
|
3
3
|
};
|
|
4
4
|
const stub = {
|
|
5
5
|
scanForBeaconsAsync: (_uuids, _scanDuration) => notSupported(),
|
|
6
|
+
scanForEddystonesAsync: (_scanDuration) => notSupported(),
|
|
6
7
|
pairBeacon: (_identifier, _uuid, _major, _minor) => notSupported(),
|
|
7
8
|
unpairBeacon: (_identifier) => notSupported(),
|
|
8
9
|
getPairedBeacons: () => notSupported(),
|
|
10
|
+
pairEddystone: (_identifier, _namespace, _instance) => notSupported(),
|
|
11
|
+
unpairEddystone: (_identifier) => notSupported(),
|
|
12
|
+
getPairedEddystones: () => notSupported(),
|
|
9
13
|
startMonitoring: () => notSupported(),
|
|
10
14
|
stopMonitoring: () => notSupported(),
|
|
11
15
|
requestPermissionsAsync: () => notSupported(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoBeaconModule.web.js","sourceRoot":"","sources":["../src/ExpoBeaconModule.web.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ExpoBeaconModule.web.js","sourceRoot":"","sources":["../src/ExpoBeaconModule.web.ts"],"names":[],"mappings":"AAQA,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,uBAAuB,EAAE,GAAqB,EAAE,CAAC,YAAY,EAAE;IAC/D,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} 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 requestPermissionsAsync: (): Promise<boolean> => notSupported(),\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, ExpoBeaconModuleEvents, NotificationConfig, MonitoringOptions, BeaconNotificationConfig, ForegroundServiceConfig, NotificationChannelConfig, } from "./ExpoBeacon.types";
|
|
2
|
+
export type { BeaconScanResult, PairedBeacon, BeaconRegionEvent, BeaconDistanceEvent, ExpoBeaconModuleEvents, NotificationConfig, MonitoringOptions, BeaconNotificationConfig, ForegroundServiceConfig, NotificationChannelConfig, EddystoneFrameType, EddystoneScanResult, PairedEddystone, EddystoneRegionEvent, EddystoneDistanceEvent, } from "./ExpoBeacon.types";
|
|
3
3
|
//# sourceMappingURL=index.d.ts.map
|
package/build/index.d.ts.map
CHANGED
|
@@ -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,sBAAsB,EACtB,kBAAkB,EAClB,iBAAiB,EACjB,wBAAwB,EACxB,uBAAuB,EACvB,yBAAyB,
|
|
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,sBAAsB,EACtB,kBAAkB,EAClB,iBAAiB,EACjB,wBAAwB,EACxB,uBAAuB,EACvB,yBAAyB,EACzB,kBAAkB,EAClB,mBAAmB,EACnB,eAAe,EACf,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,oBAAoB,CAAC"}
|
package/build/index.js.map
CHANGED
|
@@ -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 ExpoBeaconModuleEvents,\r\n NotificationConfig,\r\n MonitoringOptions,\r\n BeaconNotificationConfig,\r\n ForegroundServiceConfig,\r\n NotificationChannelConfig,\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 ExpoBeaconModuleEvents,\r\n NotificationConfig,\r\n MonitoringOptions,\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} from \"./ExpoBeacon.types\";\r\n"]}
|