react-native-pointr 10.8.0 → 10.10.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/API_REFERENCE.md +132 -0
- package/CHANGELOG.md +18 -1
- package/EXTENDING.md +12 -2
- package/android/build.gradle +1 -1
- package/android/src/main/java/com/pointr/PTRBridgeKeys.kt +45 -3
- package/android/src/main/java/com/pointr/PTRNativeLibrary.kt +224 -0
- package/ios/PTRBridgeKeys.swift +41 -3
- package/ios/PTRNativeLibrary-Bridging.m +42 -0
- package/ios/PTRNativeLibrary.swift +262 -9
- package/package.json +1 -1
- package/react-native-pointr.podspec +1 -1
- package/src/NativePointrModule.ts +29 -0
- package/src/api/PointrSdk.ts +163 -2
- package/src/constants/bridgeKeys.ts +51 -3
- package/src/constants/index.ts +14 -0
- package/src/hooks/index.ts +9 -0
- package/src/hooks/usePointrData.ts +94 -0
- package/src/hooks/usePointrDataEvents.ts +74 -0
- package/src/hooks/usePointrSite.ts +73 -0
- package/src/index.tsx +17 -0
- package/src/managers/PTRDataManager.ts +57 -0
- package/src/managers/PTRSiteManager.ts +143 -0
- package/src/types/events.ts +73 -0
|
@@ -12,7 +12,24 @@ import React
|
|
|
12
12
|
class PTRNativeLibrary: RCTEventEmitter, PTREventManagerDelegate {
|
|
13
13
|
|
|
14
14
|
private var hasListeners = false
|
|
15
|
-
|
|
15
|
+
|
|
16
|
+
/// Names of the events emitted to JS through the event emitter. JS reads
|
|
17
|
+
/// them from `PTREvents` in `src/constants/index.ts` and Android declares
|
|
18
|
+
/// them in `PTRNativeLibrary`'s companion object — the three must match.
|
|
19
|
+
///
|
|
20
|
+
/// The payload keys of these events live in `PTRBridgeKeys.EventPayloadKeys`.
|
|
21
|
+
enum EventNames {
|
|
22
|
+
static let onPositionManagerCalculatedLocation = "OnPositionManagerCalculatedLocation"
|
|
23
|
+
static let onBuildingClicked = "OnBuildingClicked"
|
|
24
|
+
static let onSiteClicked = "OnSiteClicked"
|
|
25
|
+
static let onGeofenceEvent = "OnGeofenceEvent"
|
|
26
|
+
static let onDataManagerStartDataManagementForSite = "OnDataManagerStartDataManagementForSite"
|
|
27
|
+
static let onDataManagerCompleteAllForSite = "OnDataManagerCompleteAllForSite"
|
|
28
|
+
static let onDataManagerBeginProcessingDataForSite = "OnDataManagerBeginProcessingDataForSite"
|
|
29
|
+
static let onDataManagerEndProcessingDataForSite = "OnDataManagerEndProcessingDataForSite"
|
|
30
|
+
static let onDataManagerReadyForSite = "OnDataManagerReadyForSite"
|
|
31
|
+
}
|
|
32
|
+
|
|
16
33
|
// PointrApp functionality moved here
|
|
17
34
|
@objc public weak var eventManagerDelegate: PTREventManagerDelegate?
|
|
18
35
|
@objc public static var shouldRequestPermissionsAtStartup: Bool = true
|
|
@@ -78,10 +95,15 @@ class PTRNativeLibrary: RCTEventEmitter, PTREventManagerDelegate {
|
|
|
78
95
|
|
|
79
96
|
override func supportedEvents() -> [String]! {
|
|
80
97
|
return [
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
98
|
+
EventNames.onPositionManagerCalculatedLocation,
|
|
99
|
+
EventNames.onBuildingClicked,
|
|
100
|
+
EventNames.onSiteClicked,
|
|
101
|
+
EventNames.onGeofenceEvent,
|
|
102
|
+
EventNames.onDataManagerStartDataManagementForSite,
|
|
103
|
+
EventNames.onDataManagerCompleteAllForSite,
|
|
104
|
+
EventNames.onDataManagerBeginProcessingDataForSite,
|
|
105
|
+
EventNames.onDataManagerEndProcessingDataForSite,
|
|
106
|
+
EventNames.onDataManagerReadyForSite,
|
|
85
107
|
]
|
|
86
108
|
}
|
|
87
109
|
|
|
@@ -242,6 +264,7 @@ class PTRNativeLibrary: RCTEventEmitter, PTREventManagerDelegate {
|
|
|
242
264
|
if Pointr.shared.state == .running {
|
|
243
265
|
Pointr.shared.positioningManager?.addListener(self)
|
|
244
266
|
Pointr.shared.geofenceManager?.addListener(self)
|
|
267
|
+
Pointr.shared.dataManager?.addListener(self)
|
|
245
268
|
resolve(nil)
|
|
246
269
|
} else {
|
|
247
270
|
let stateStr = self.getPointrStateStringFromPointrState(state: Pointr.shared.state)
|
|
@@ -252,6 +275,7 @@ class PTRNativeLibrary: RCTEventEmitter, PTREventManagerDelegate {
|
|
|
252
275
|
@objc func stop() {
|
|
253
276
|
Pointr.shared.positioningManager?.removeListener(self)
|
|
254
277
|
Pointr.shared.geofenceManager?.removeListener(self)
|
|
278
|
+
Pointr.shared.dataManager?.removeListener(self)
|
|
255
279
|
Pointr.shared.stop()
|
|
256
280
|
}
|
|
257
281
|
|
|
@@ -347,6 +371,150 @@ class PTRNativeLibrary: RCTEventEmitter, PTREventManagerDelegate {
|
|
|
347
371
|
resolve(poisData)
|
|
348
372
|
}
|
|
349
373
|
|
|
374
|
+
// MARK: - Data Manager
|
|
375
|
+
|
|
376
|
+
@objc(loadDataForSite:shouldRespectCachePolicy:isExternalIdentifier:resolver:rejecter:)
|
|
377
|
+
func loadDataForSite(_ siteId: String,
|
|
378
|
+
shouldRespectCachePolicy: Bool,
|
|
379
|
+
isExternalIdentifier: Bool,
|
|
380
|
+
resolver resolve: @escaping RCTPromiseResolveBlock,
|
|
381
|
+
rejecter reject: @escaping RCTPromiseRejectBlock) {
|
|
382
|
+
guard let site = resolveSite(siteId, isExternalIdentifier: isExternalIdentifier) else {
|
|
383
|
+
reject("SITE_NOT_FOUND", "Site not found: \(siteId)", nil)
|
|
384
|
+
return
|
|
385
|
+
}
|
|
386
|
+
Pointr.shared.dataManager?.loadData(forSite: site.internalIdentifier,
|
|
387
|
+
shouldRespectCachePolicy: shouldRespectCachePolicy)
|
|
388
|
+
resolve(nil)
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
@objc(isSiteContentReady:isExternalIdentifier:resolver:rejecter:)
|
|
392
|
+
func isSiteContentReady(_ siteId: String,
|
|
393
|
+
isExternalIdentifier: Bool,
|
|
394
|
+
resolver resolve: @escaping RCTPromiseResolveBlock,
|
|
395
|
+
rejecter reject: @escaping RCTPromiseRejectBlock) {
|
|
396
|
+
guard let site = resolveSite(siteId, isExternalIdentifier: isExternalIdentifier) else {
|
|
397
|
+
reject("SITE_NOT_FOUND", "Site not found: \(siteId)", nil)
|
|
398
|
+
return
|
|
399
|
+
}
|
|
400
|
+
let ready = Pointr.shared.dataManager?.isContentReady(forSite: site.internalIdentifier) ?? false
|
|
401
|
+
resolve(ready)
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
private func resolveSite(_ siteId: String, isExternalIdentifier: Bool) -> PTRSite? {
|
|
405
|
+
guard let siteManager = Pointr.shared.siteManager else { return nil }
|
|
406
|
+
return isExternalIdentifier
|
|
407
|
+
? siteManager.site(withExternalIdentifier: siteId)
|
|
408
|
+
: siteManager.site(withInternalIdentifier: siteId)
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
// MARK: - Site Manager
|
|
412
|
+
|
|
413
|
+
@objc(getSite:isExternalIdentifier:resolver:rejecter:)
|
|
414
|
+
func getSite(_ siteId: String,
|
|
415
|
+
isExternalIdentifier: Bool,
|
|
416
|
+
resolver resolve: @escaping RCTPromiseResolveBlock,
|
|
417
|
+
rejecter reject: @escaping RCTPromiseRejectBlock) {
|
|
418
|
+
if let site = resolveSite(siteId, isExternalIdentifier: isExternalIdentifier) {
|
|
419
|
+
resolve(site.dict)
|
|
420
|
+
} else {
|
|
421
|
+
resolve(NSNull())
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
@objc(getSiteBuildings:isExternalIdentifier:resolver:rejecter:)
|
|
426
|
+
func getSiteBuildings(_ siteId: String,
|
|
427
|
+
isExternalIdentifier: Bool,
|
|
428
|
+
resolver resolve: @escaping RCTPromiseResolveBlock,
|
|
429
|
+
rejecter reject: @escaping RCTPromiseRejectBlock) {
|
|
430
|
+
guard let site = resolveSite(siteId, isExternalIdentifier: isExternalIdentifier) else {
|
|
431
|
+
reject("SITE_NOT_FOUND", "Site not found: \(siteId)", nil)
|
|
432
|
+
return
|
|
433
|
+
}
|
|
434
|
+
let buildings = Pointr.shared.siteManager?.buildings(forSiteId: site.internalIdentifier) ?? []
|
|
435
|
+
resolve(buildings.map { $0.dict })
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
@objc(getBuilding:buildingId:isExternalIdentifier:resolver:rejecter:)
|
|
439
|
+
func getBuilding(_ siteId: String,
|
|
440
|
+
buildingId: String,
|
|
441
|
+
isExternalIdentifier: Bool,
|
|
442
|
+
resolver resolve: @escaping RCTPromiseResolveBlock,
|
|
443
|
+
rejecter reject: @escaping RCTPromiseRejectBlock) {
|
|
444
|
+
guard let siteManager = Pointr.shared.siteManager else {
|
|
445
|
+
reject("NOT_READY", "Site manager is not available", nil)
|
|
446
|
+
return
|
|
447
|
+
}
|
|
448
|
+
// Unknown site resolves null rather than rejecting, matching Android's
|
|
449
|
+
// getBuilding, which returns null for a site it cannot find.
|
|
450
|
+
guard let site = resolveSite(siteId, isExternalIdentifier: isExternalIdentifier) else {
|
|
451
|
+
resolve(NSNull())
|
|
452
|
+
return
|
|
453
|
+
}
|
|
454
|
+
// PointrKit's sync accessors search globally, so the result has to be
|
|
455
|
+
// checked against the requested site — Android scopes the lookup itself.
|
|
456
|
+
// The site-scoped async variants are not used here: they resolve nil
|
|
457
|
+
// until the site's content is ready, which would make this return null
|
|
458
|
+
// for buildings that `getSiteBuildings` already returns.
|
|
459
|
+
let building = isExternalIdentifier
|
|
460
|
+
? siteManager.building(withExternalIdentifier: buildingId)
|
|
461
|
+
: siteManager.building(withInternalIdentifier: buildingId)
|
|
462
|
+
if let building = building,
|
|
463
|
+
building.site.internalIdentifier == site.internalIdentifier {
|
|
464
|
+
resolve(building.dict)
|
|
465
|
+
} else {
|
|
466
|
+
resolve(NSNull())
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
@objc(getLevelByExternalIdentifier:levelExternalIdentifier:resolver:rejecter:)
|
|
471
|
+
func getLevelByExternalIdentifier(_ buildingExternalIdentifier: String,
|
|
472
|
+
levelExternalIdentifier: String,
|
|
473
|
+
resolver resolve: @escaping RCTPromiseResolveBlock,
|
|
474
|
+
rejecter reject: @escaping RCTPromiseRejectBlock) {
|
|
475
|
+
// PointrKit takes (level, building); this bridge and the Android SDK take
|
|
476
|
+
// (building, level). Keep the labels explicit so the order can't drift.
|
|
477
|
+
let level = Pointr.shared.siteManager?.level(
|
|
478
|
+
withExternalIdentifier: levelExternalIdentifier,
|
|
479
|
+
buildingExternalIdentifier: buildingExternalIdentifier
|
|
480
|
+
)
|
|
481
|
+
if let level = level {
|
|
482
|
+
typealias ModelKeys = PTRBridgeKeys.ModelKeys
|
|
483
|
+
resolve([
|
|
484
|
+
ModelKeys.identifier: level.identifier,
|
|
485
|
+
ModelKeys.externalIdentifier: level.externalIdentifier,
|
|
486
|
+
ModelKeys.name: level.name,
|
|
487
|
+
ModelKeys.index: level.index
|
|
488
|
+
])
|
|
489
|
+
} else {
|
|
490
|
+
resolve(NSNull())
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
@objc(getMapUrl:isExternalIdentifier:resolver:rejecter:)
|
|
495
|
+
func getMapUrl(_ siteId: String,
|
|
496
|
+
isExternalIdentifier: Bool,
|
|
497
|
+
resolver resolve: @escaping RCTPromiseResolveBlock,
|
|
498
|
+
rejecter reject: @escaping RCTPromiseRejectBlock) {
|
|
499
|
+
guard let site = resolveSite(siteId, isExternalIdentifier: isExternalIdentifier) else {
|
|
500
|
+
reject("SITE_NOT_FOUND", "Site not found: \(siteId)", nil)
|
|
501
|
+
return
|
|
502
|
+
}
|
|
503
|
+
Pointr.shared.siteManager?.mapUrl(forSite: site.internalIdentifier) { mapUrl, error in
|
|
504
|
+
if let error = error {
|
|
505
|
+
reject("ERROR", error, nil)
|
|
506
|
+
} else {
|
|
507
|
+
resolve(mapUrl?.absoluteString)
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
@objc(getStyleJsonUrl:rejecter:)
|
|
513
|
+
func getStyleJsonUrl(_ resolve: @escaping RCTPromiseResolveBlock,
|
|
514
|
+
rejecter reject: @escaping RCTPromiseRejectBlock) {
|
|
515
|
+
resolve(Pointr.shared.siteManager?.styleJsonURL()?.absoluteString)
|
|
516
|
+
}
|
|
517
|
+
|
|
350
518
|
// MARK: - Sites & Buildings
|
|
351
519
|
|
|
352
520
|
@objc
|
|
@@ -494,22 +662,22 @@ class PTRNativeLibrary: RCTEventEmitter, PTREventManagerDelegate {
|
|
|
494
662
|
|
|
495
663
|
func onPositionManagerCalculatedLocation(location: [String : Any]) {
|
|
496
664
|
guard hasListeners else { return }
|
|
497
|
-
sendEvent(withName:
|
|
665
|
+
sendEvent(withName: EventNames.onPositionManagerCalculatedLocation, body: location)
|
|
498
666
|
}
|
|
499
667
|
|
|
500
668
|
func onGeofenceEvent(_ geofenceEvent: [String: Any]) {
|
|
501
669
|
guard hasListeners else { return }
|
|
502
|
-
sendEvent(withName:
|
|
670
|
+
sendEvent(withName: EventNames.onGeofenceEvent, body: geofenceEvent)
|
|
503
671
|
}
|
|
504
672
|
|
|
505
673
|
func onBuildingClicked(_ building: [String : Any]) {
|
|
506
674
|
guard hasListeners else { return }
|
|
507
|
-
sendEvent(withName:
|
|
675
|
+
sendEvent(withName: EventNames.onBuildingClicked, body: building)
|
|
508
676
|
}
|
|
509
677
|
|
|
510
678
|
func onSiteClicked(_ site: [String : Any]) {
|
|
511
679
|
guard hasListeners else { return }
|
|
512
|
-
sendEvent(withName:
|
|
680
|
+
sendEvent(withName: EventNames.onSiteClicked, body: site)
|
|
513
681
|
}
|
|
514
682
|
}
|
|
515
683
|
|
|
@@ -526,6 +694,91 @@ extension PTRNativeLibrary: PTRGeofenceManagerDelegate {
|
|
|
526
694
|
}
|
|
527
695
|
}
|
|
528
696
|
|
|
697
|
+
// MARK: - PTRDataManagerDelegate
|
|
698
|
+
extension PTRNativeLibrary: PTRDataManagerDelegate {
|
|
699
|
+
private typealias Keys = PTRBridgeKeys.EventPayloadKeys
|
|
700
|
+
|
|
701
|
+
@objc func onDataManagerStartDataManagement(for site: PTRSite, dataFromOnline isOnlineData: Bool) {
|
|
702
|
+
guard hasListeners else { return }
|
|
703
|
+
sendEvent(withName: EventNames.onDataManagerStartDataManagementForSite, body: [
|
|
704
|
+
Keys.site: site.dict,
|
|
705
|
+
Keys.isOnlineData: isOnlineData,
|
|
706
|
+
])
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
@objc func onDataManagerCompleteAll(for site: PTRSite,
|
|
710
|
+
isSuccessful: Bool,
|
|
711
|
+
dataFromOnline isOnlineData: Bool,
|
|
712
|
+
errorMessages: [NSNumber: String]) {
|
|
713
|
+
guard hasListeners else { return }
|
|
714
|
+
sendEvent(withName: EventNames.onDataManagerCompleteAllForSite, body: [
|
|
715
|
+
Keys.site: site.dict,
|
|
716
|
+
Keys.isSuccessful: isSuccessful,
|
|
717
|
+
Keys.isOnlineData: isOnlineData,
|
|
718
|
+
Keys.errors: Array(errorMessages.values),
|
|
719
|
+
])
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
@objc func onDataManagerBeginProcessingData(for site: PTRSite,
|
|
723
|
+
dataType: PTRDataType,
|
|
724
|
+
dataFromOnline isOnlineData: Bool) {
|
|
725
|
+
guard hasListeners else { return }
|
|
726
|
+
sendEvent(withName: EventNames.onDataManagerBeginProcessingDataForSite, body: [
|
|
727
|
+
Keys.site: site.dict,
|
|
728
|
+
Keys.dataType: dataTypeDict(dataType),
|
|
729
|
+
Keys.isOnlineData: isOnlineData,
|
|
730
|
+
])
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
@objc func onDataManagerEndProcessingData(for site: PTRSite,
|
|
734
|
+
dataType: PTRDataType,
|
|
735
|
+
dataFromOnline isOnlineData: Bool,
|
|
736
|
+
isSuccessful: Bool,
|
|
737
|
+
errorMessages: [String]) {
|
|
738
|
+
guard hasListeners else { return }
|
|
739
|
+
sendEvent(withName: EventNames.onDataManagerEndProcessingDataForSite, body: [
|
|
740
|
+
Keys.site: site.dict,
|
|
741
|
+
Keys.dataType: dataTypeDict(dataType),
|
|
742
|
+
Keys.isOnlineData: isOnlineData,
|
|
743
|
+
Keys.isSuccessful: isSuccessful,
|
|
744
|
+
Keys.errors: errorMessages,
|
|
745
|
+
])
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
@objc func onDataManagerReady(for site: PTRSite) {
|
|
749
|
+
guard hasListeners else { return }
|
|
750
|
+
sendEvent(withName: EventNames.onDataManagerReadyForSite, body: [
|
|
751
|
+
Keys.site: site.dict,
|
|
752
|
+
])
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
private func dataTypeDict(_ dataType: PTRDataType) -> [String: Any] {
|
|
756
|
+
return [
|
|
757
|
+
Keys.dataTypeValue: dataType.rawValue,
|
|
758
|
+
Keys.dataTypeName: dataTypeName(dataType),
|
|
759
|
+
]
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
private func dataTypeName(_ dataType: PTRDataType) -> String {
|
|
763
|
+
switch dataType {
|
|
764
|
+
case .poi: return "Poi"
|
|
765
|
+
case .beacon: return "Beacon"
|
|
766
|
+
case .obstacle: return "Obstacle"
|
|
767
|
+
case .configuration: return "Config"
|
|
768
|
+
case .graph: return "Graph"
|
|
769
|
+
case .versions: return "Versions"
|
|
770
|
+
case .geofence: return "Geofence"
|
|
771
|
+
case .sites: return "Sites"
|
|
772
|
+
case .featureType: return "FeatureType"
|
|
773
|
+
case .beaconUuid: return "BeaconUuid"
|
|
774
|
+
case .client: return "Client"
|
|
775
|
+
case .buildings: return "Buildings"
|
|
776
|
+
case .mapContent: return "MapContent"
|
|
777
|
+
default: return "Unknown"
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
|
|
529
782
|
// MARK: - PTRExitButtonEventsListener
|
|
530
783
|
extension PTRNativeLibrary: PTRExitButtonEventsListener {
|
|
531
784
|
func exitButtonDidTap() {
|
package/package.json
CHANGED
|
@@ -16,7 +16,7 @@ Pod::Spec.new do |s|
|
|
|
16
16
|
|
|
17
17
|
s.source_files = "ios/**/*.{h,m,mm,swift}"
|
|
18
18
|
|
|
19
|
-
s.dependency 'PointrKit', '10.
|
|
19
|
+
s.dependency 'PointrKit', '10.10.0'
|
|
20
20
|
|
|
21
21
|
# Use install_modules_dependencies helper to install the dependencies if React Native version >=0.71.0.
|
|
22
22
|
# See https://github.com/facebook/react-native/blob/febf6b7f33fdb4904669f99d795eba4c0f95d7bf/scripts/cocoapods/new_architecture.rb#L79.
|
|
@@ -36,10 +36,39 @@ export interface Spec extends TurboModule {
|
|
|
36
36
|
// ─── Config ─────────────────────────────────────────────────────────────────
|
|
37
37
|
setPointrMapWidgetConfiguration(configJson: string): void;
|
|
38
38
|
|
|
39
|
+
// ─── Data Manager ─────────────────────────────────────────────────────────────
|
|
40
|
+
loadDataForSite(
|
|
41
|
+
siteId: string,
|
|
42
|
+
shouldRespectCachePolicy: boolean,
|
|
43
|
+
isExternalIdentifier: boolean
|
|
44
|
+
): Promise<void>;
|
|
45
|
+
isSiteContentReady(
|
|
46
|
+
siteId: string,
|
|
47
|
+
isExternalIdentifier: boolean
|
|
48
|
+
): Promise<boolean>;
|
|
49
|
+
|
|
39
50
|
// ─── POIs ───────────────────────────────────────────────────────────────────
|
|
40
51
|
getPois(siteId: string): Promise<Object[]>;
|
|
41
52
|
searchPois(siteId: string, query: string): Promise<Object[]>;
|
|
42
53
|
|
|
54
|
+
// ─── Site Manager ─────────────────────────────────────────────────────────────
|
|
55
|
+
getSite(siteId: string, isExternalIdentifier: boolean): Promise<Object | null>;
|
|
56
|
+
getSiteBuildings(
|
|
57
|
+
siteId: string,
|
|
58
|
+
isExternalIdentifier: boolean
|
|
59
|
+
): Promise<Object[]>;
|
|
60
|
+
getBuilding(
|
|
61
|
+
siteId: string,
|
|
62
|
+
buildingId: string,
|
|
63
|
+
isExternalIdentifier: boolean
|
|
64
|
+
): Promise<Object | null>;
|
|
65
|
+
getLevelByExternalIdentifier(
|
|
66
|
+
buildingExternalIdentifier: string,
|
|
67
|
+
levelExternalIdentifier: string
|
|
68
|
+
): Promise<Object | null>;
|
|
69
|
+
getMapUrl(siteId: string, isExternalIdentifier: boolean): Promise<string | null>;
|
|
70
|
+
getStyleJsonUrl(): Promise<string | null>;
|
|
71
|
+
|
|
43
72
|
// ─── Sites & Buildings ──────────────────────────────────────────────────────
|
|
44
73
|
getSites(): Promise<Object[]>;
|
|
45
74
|
getBuildings(siteId: string): Promise<Object[]>;
|
package/src/api/PointrSdk.ts
CHANGED
|
@@ -8,8 +8,15 @@ import { NativeModules, NativeEventEmitter, Platform } from 'react-native';
|
|
|
8
8
|
import type { PTRConfiguration, PTRMapWidgetConfiguration } from '../types/config';
|
|
9
9
|
import type { PTRPosition } from '../types/PTRPosition';
|
|
10
10
|
import type { PTRPoi } from '../types/PTRPoi';
|
|
11
|
-
import type { PTRSite, PTRBuilding } from '../types/PTRSite';
|
|
12
|
-
import type {
|
|
11
|
+
import type { PTRSite, PTRBuilding, PTRLevel } from '../types/PTRSite';
|
|
12
|
+
import type {
|
|
13
|
+
PTRGeofence,
|
|
14
|
+
PTRDataManagerStartEvent,
|
|
15
|
+
PTRDataManagerCompleteAllEvent,
|
|
16
|
+
PTRDataManagerBeginProcessingEvent,
|
|
17
|
+
PTRDataManagerEndProcessingEvent,
|
|
18
|
+
PTRDataManagerReadyEvent,
|
|
19
|
+
} from '../types/events';
|
|
13
20
|
import { PTRState, PTRLogLevel, PTRErrorMessages, PTREvents } from '../constants';
|
|
14
21
|
|
|
15
22
|
const LINKING_ERROR =
|
|
@@ -172,6 +179,45 @@ export class PointrSdk {
|
|
|
172
179
|
return this.eventEmitter.addListener(PTREvents.ON_GEOFENCE_EVENT, callback);
|
|
173
180
|
}
|
|
174
181
|
|
|
182
|
+
// ─── Data manager events ─────────────────────────────────────────────────────
|
|
183
|
+
|
|
184
|
+
/** Subscribe to data-management-start events. */
|
|
185
|
+
public onDataManagerStart(callback: (event: PTRDataManagerStartEvent) => void) {
|
|
186
|
+
return this.eventEmitter.addListener(PTREvents.ON_DATA_MANAGER_START, callback);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/** Subscribe to data-management-complete-all events. */
|
|
190
|
+
public onDataManagerCompleteAll(
|
|
191
|
+
callback: (event: PTRDataManagerCompleteAllEvent) => void
|
|
192
|
+
) {
|
|
193
|
+
return this.eventEmitter.addListener(PTREvents.ON_DATA_MANAGER_COMPLETE_ALL, callback);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/** Subscribe to begin-processing events for a specific data type. */
|
|
197
|
+
public onDataManagerBeginProcessing(
|
|
198
|
+
callback: (event: PTRDataManagerBeginProcessingEvent) => void
|
|
199
|
+
) {
|
|
200
|
+
return this.eventEmitter.addListener(
|
|
201
|
+
PTREvents.ON_DATA_MANAGER_BEGIN_PROCESSING,
|
|
202
|
+
callback
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/** Subscribe to end-processing events for a specific data type. */
|
|
207
|
+
public onDataManagerEndProcessing(
|
|
208
|
+
callback: (event: PTRDataManagerEndProcessingEvent) => void
|
|
209
|
+
) {
|
|
210
|
+
return this.eventEmitter.addListener(
|
|
211
|
+
PTREvents.ON_DATA_MANAGER_END_PROCESSING,
|
|
212
|
+
callback
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/** Subscribe to site-ready events (all data available to display a site). */
|
|
217
|
+
public onDataManagerReady(callback: (event: PTRDataManagerReadyEvent) => void) {
|
|
218
|
+
return this.eventEmitter.addListener(PTREvents.ON_DATA_MANAGER_READY, callback);
|
|
219
|
+
}
|
|
220
|
+
|
|
175
221
|
// ─── Map widget ────────────────────────────────────────────────────────────
|
|
176
222
|
|
|
177
223
|
/**
|
|
@@ -208,6 +254,42 @@ export class PointrSdk {
|
|
|
208
254
|
return PTRNativeLibrary.getGeofences(siteId);
|
|
209
255
|
}
|
|
210
256
|
|
|
257
|
+
// ─── Data Manager ────────────────────────────────────────────────────────────
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Start data management for a site if the data is not already present.
|
|
261
|
+
* @param siteId - Site identifier
|
|
262
|
+
* @param shouldRespectCachePolicy - When `true` (default), waits until the
|
|
263
|
+
* cache expires if data is already present. When `false`, ignores the internal
|
|
264
|
+
* cache and triggers a data update immediately.
|
|
265
|
+
* @param isExternalIdentifier - When `false` (default), `siteId` is the site's
|
|
266
|
+
* internal identifier. When `true`, it is the external identifier.
|
|
267
|
+
*/
|
|
268
|
+
public loadDataForSite(
|
|
269
|
+
siteId: string,
|
|
270
|
+
shouldRespectCachePolicy: boolean = true,
|
|
271
|
+
isExternalIdentifier: boolean = false
|
|
272
|
+
): Promise<void> {
|
|
273
|
+
return PTRNativeLibrary.loadDataForSite(
|
|
274
|
+
siteId,
|
|
275
|
+
shouldRespectCachePolicy,
|
|
276
|
+
isExternalIdentifier
|
|
277
|
+
);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Whether all data is ready for use for the given site.
|
|
282
|
+
* @param siteId - Site identifier
|
|
283
|
+
* @param isExternalIdentifier - When `false` (default), `siteId` is the site's
|
|
284
|
+
* internal identifier. When `true`, it is the external identifier.
|
|
285
|
+
*/
|
|
286
|
+
public isSiteContentReady(
|
|
287
|
+
siteId: string,
|
|
288
|
+
isExternalIdentifier: boolean = false
|
|
289
|
+
): Promise<boolean> {
|
|
290
|
+
return PTRNativeLibrary.isSiteContentReady(siteId, isExternalIdentifier);
|
|
291
|
+
}
|
|
292
|
+
|
|
211
293
|
// ─── POIs ──────────────────────────────────────────────────────────────────
|
|
212
294
|
|
|
213
295
|
/**
|
|
@@ -256,6 +338,85 @@ export class PointrSdk {
|
|
|
256
338
|
return PTRNativeLibrary.getClientName();
|
|
257
339
|
}
|
|
258
340
|
|
|
341
|
+
// ─── Site Manager ──────────────────────────────────────────────────────────────
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* Get a single site by its identifier.
|
|
345
|
+
* @param siteId - Site identifier
|
|
346
|
+
* @param isExternalIdentifier - When `false` (default), `siteId` is the
|
|
347
|
+
* internal identifier; when `true`, it is the external identifier.
|
|
348
|
+
*/
|
|
349
|
+
public getSite(
|
|
350
|
+
siteId: string,
|
|
351
|
+
isExternalIdentifier: boolean = false
|
|
352
|
+
): Promise<PTRSite | null> {
|
|
353
|
+
return PTRNativeLibrary.getSite(siteId, isExternalIdentifier);
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* Get all buildings for a site, resolving the site by internal or external id.
|
|
358
|
+
* @param siteId - Site identifier
|
|
359
|
+
* @param isExternalIdentifier - When `false` (default), `siteId` is the
|
|
360
|
+
* internal identifier; when `true`, it is the external identifier.
|
|
361
|
+
*/
|
|
362
|
+
public getSiteBuildings(
|
|
363
|
+
siteId: string,
|
|
364
|
+
isExternalIdentifier: boolean = false
|
|
365
|
+
): Promise<PTRBuilding[]> {
|
|
366
|
+
return PTRNativeLibrary.getSiteBuildings(siteId, isExternalIdentifier);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* Get a single building within a site by its identifier.
|
|
371
|
+
* @param siteId - Site identifier
|
|
372
|
+
* @param buildingId - Building identifier
|
|
373
|
+
* @param isExternalIdentifier - When `false` (default), both ids are internal;
|
|
374
|
+
* when `true`, both are external.
|
|
375
|
+
*/
|
|
376
|
+
public getBuilding(
|
|
377
|
+
siteId: string,
|
|
378
|
+
buildingId: string,
|
|
379
|
+
isExternalIdentifier: boolean = false
|
|
380
|
+
): Promise<PTRBuilding | null> {
|
|
381
|
+
return PTRNativeLibrary.getBuilding(siteId, buildingId, isExternalIdentifier);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* Get a level by its external identifier within a building.
|
|
386
|
+
* Resolves with the level or null if not found.
|
|
387
|
+
* Level ids are only unique within a building, so the building scopes the
|
|
388
|
+
* lookup. Both SDKs expose this by external identifier only.
|
|
389
|
+
* @param buildingExternalIdentifier - External identifier of the building
|
|
390
|
+
* @param levelExternalIdentifier - External identifier of the level
|
|
391
|
+
*/
|
|
392
|
+
public getLevelByExternalIdentifier(
|
|
393
|
+
buildingExternalIdentifier: string,
|
|
394
|
+
levelExternalIdentifier: string
|
|
395
|
+
): Promise<PTRLevel | null> {
|
|
396
|
+
return PTRNativeLibrary.getLevelByExternalIdentifier(
|
|
397
|
+
buildingExternalIdentifier,
|
|
398
|
+
levelExternalIdentifier
|
|
399
|
+
);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* Get the map data URL for a site.
|
|
404
|
+
* @param siteId - Site identifier
|
|
405
|
+
* @param isExternalIdentifier - When `false` (default), `siteId` is the
|
|
406
|
+
* internal identifier; when `true`, it is the external identifier.
|
|
407
|
+
*/
|
|
408
|
+
public getMapUrl(
|
|
409
|
+
siteId: string,
|
|
410
|
+
isExternalIdentifier: boolean = false
|
|
411
|
+
): Promise<string | null> {
|
|
412
|
+
return PTRNativeLibrary.getMapUrl(siteId, isExternalIdentifier);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
/** Get the URL for the map style JSON, or null if unavailable. */
|
|
416
|
+
public getStyleJsonUrl(): Promise<string | null> {
|
|
417
|
+
return PTRNativeLibrary.getStyleJsonUrl();
|
|
418
|
+
}
|
|
419
|
+
|
|
259
420
|
// ─── Wayfinding ──────────────────────────────────────────────────────────────
|
|
260
421
|
|
|
261
422
|
/**
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Every string that crosses the JS <-> native boundary
|
|
3
|
-
*
|
|
4
|
-
* keys
|
|
2
|
+
* Every string that crosses the JS <-> native boundary: action type
|
|
3
|
+
* discriminators, `action` / `sdkConfig` payload keys and view-manager command
|
|
4
|
+
* names on the JS -> native path, plus the payload keys of the events native
|
|
5
|
+
* emits back to JS.
|
|
5
6
|
*
|
|
6
7
|
* Nothing here may be hard-coded anywhere else — a key renamed on one side only
|
|
7
8
|
* fails silently (the native side reads an empty string), so all three sides
|
|
@@ -125,3 +126,50 @@ export const PTRCommandNames = {
|
|
|
125
126
|
|
|
126
127
|
export type PTRCommandName =
|
|
127
128
|
(typeof PTRCommandNames)[keyof typeof PTRCommandNames];
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Field names of the event payloads native emits to JS through the event
|
|
132
|
+
* emitter. Native writes them, JS reads them back through the typed interfaces
|
|
133
|
+
* in `src/types/events.ts` — the interface field names must match these values.
|
|
134
|
+
*
|
|
135
|
+
* Event *names* are not listed here: they live in {@link PTREvents} on the JS
|
|
136
|
+
* side, in `PTRNativeLibrary`'s companion object on Android and in
|
|
137
|
+
* `PTRNativeLibrary.EventNames` on iOS.
|
|
138
|
+
*/
|
|
139
|
+
export const PTREventPayloadKeys = {
|
|
140
|
+
/** Site the event refers to, serialized by {@link PTRModelKeys} */
|
|
141
|
+
SITE: 'site',
|
|
142
|
+
/** Whether the data came from the server (online) or a local bundle */
|
|
143
|
+
IS_ONLINE_DATA: 'isOnlineData',
|
|
144
|
+
/** Whether the reported operation succeeded */
|
|
145
|
+
IS_SUCCESSFUL: 'isSuccessful',
|
|
146
|
+
/** Error messages collected during the operation */
|
|
147
|
+
ERRORS: 'errors',
|
|
148
|
+
/** Data type being processed */
|
|
149
|
+
DATA_TYPE: 'dataType',
|
|
150
|
+
/** Numeric value of `dataType` */
|
|
151
|
+
DATA_TYPE_VALUE: 'value',
|
|
152
|
+
/** Human-readable name of `dataType` */
|
|
153
|
+
DATA_TYPE_NAME: 'name',
|
|
154
|
+
} as const;
|
|
155
|
+
|
|
156
|
+
export type PTREventPayloadKey =
|
|
157
|
+
(typeof PTREventPayloadKeys)[keyof typeof PTREventPayloadKeys];
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Field names shared by the site, building and level objects native serializes
|
|
161
|
+
* for JS — both as promise results and inside event payloads. They match the
|
|
162
|
+
* interfaces in `src/types/PTRSite.ts`.
|
|
163
|
+
*/
|
|
164
|
+
export const PTRModelKeys = {
|
|
165
|
+
/** Internal identifier */
|
|
166
|
+
IDENTIFIER: 'identifier',
|
|
167
|
+
/** External (customer-facing) identifier */
|
|
168
|
+
EXTERNAL_IDENTIFIER: 'externalIdentifier',
|
|
169
|
+
/** Human-readable name */
|
|
170
|
+
NAME: 'name',
|
|
171
|
+
/** Zero-based level index */
|
|
172
|
+
INDEX: 'index',
|
|
173
|
+
} as const;
|
|
174
|
+
|
|
175
|
+
export type PTRModelKey = (typeof PTRModelKeys)[keyof typeof PTRModelKeys];
|
package/src/constants/index.ts
CHANGED
|
@@ -11,11 +11,15 @@ export {
|
|
|
11
11
|
PTRActionParamKeys,
|
|
12
12
|
PTRSdkConfigKeys,
|
|
13
13
|
PTRCommandNames,
|
|
14
|
+
PTREventPayloadKeys,
|
|
15
|
+
PTRModelKeys,
|
|
14
16
|
} from './bridgeKeys';
|
|
15
17
|
export type {
|
|
16
18
|
PTRActionParamKey,
|
|
17
19
|
PTRSdkConfigKey,
|
|
18
20
|
PTRCommandName,
|
|
21
|
+
PTREventPayloadKey,
|
|
22
|
+
PTRModelKey,
|
|
19
23
|
} from './bridgeKeys';
|
|
20
24
|
|
|
21
25
|
/**
|
|
@@ -86,6 +90,16 @@ export const PTREvents = {
|
|
|
86
90
|
ON_WAYFINDING_EVENT: 'onWayfindingEvent',
|
|
87
91
|
/** Fired when map widget finishes loading */
|
|
88
92
|
ON_MAP_WIDGET_DID_END_LOADING: 'onMapWidgetDidEndLoading',
|
|
93
|
+
/** Fired when the data manager starts data management for a site */
|
|
94
|
+
ON_DATA_MANAGER_START: 'OnDataManagerStartDataManagementForSite',
|
|
95
|
+
/** Fired when the data manager completes all processing for a site */
|
|
96
|
+
ON_DATA_MANAGER_COMPLETE_ALL: 'OnDataManagerCompleteAllForSite',
|
|
97
|
+
/** Fired when the data manager begins processing a specific data type */
|
|
98
|
+
ON_DATA_MANAGER_BEGIN_PROCESSING: 'OnDataManagerBeginProcessingDataForSite',
|
|
99
|
+
/** Fired when the data manager ends processing a specific data type */
|
|
100
|
+
ON_DATA_MANAGER_END_PROCESSING: 'OnDataManagerEndProcessingDataForSite',
|
|
101
|
+
/** Fired when all data needed to display a site is available */
|
|
102
|
+
ON_DATA_MANAGER_READY: 'OnDataManagerReadyForSite',
|
|
89
103
|
} as const;
|
|
90
104
|
|
|
91
105
|
/**
|