react-native-pointr 9.6.0 → 9.7.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.
@@ -6,7 +6,34 @@ import PointrKit
6
6
  @objc var onMapWidgetDidEndLoading: RCTBubblingEventBlock?
7
7
 
8
8
  @objc var onWayfindingEvent: RCTBubblingEventBlock?
9
-
9
+
10
+ // Declarative command prop — JSON string encoding command type and its parameters.
11
+ // When set alongside an optional sdkConfig prop, the widget auto-starts and focuses
12
+ // without the JS caller needing to imperatively dispatch a command afterwards.
13
+ //
14
+ // Expected shape: { "type": "site"|"building"|"level"|"poi"|"path"|"staticPath"|"staticWayfinding",
15
+ // "site": "...", "building"?: "...", "level"?: 0,
16
+ // "poi"?: "...", "fromPoi"?: "...", "toPoi"?: "...",
17
+ // "sourcePoi"?: "...", "destinationPoi"?: "..." }
18
+ @objc var command: String? {
19
+ didSet { pendingCommandString = command }
20
+ }
21
+
22
+ // Optional SDK config prop — JSON with clientId / licenseKey / baseUrl / logLevel.
23
+ // When provided the widget uses these credentials instead of the globally-configured params.
24
+ @objc var sdkConfig: String? {
25
+ didSet { applySDKConfigIfNeeded() }
26
+ }
27
+
28
+ // Optional map widget UI configuration — JSON encoding PTRMapWidgetConfiguration keys.
29
+ // Applied before the map widget is created so that it takes effect on first render.
30
+ @objc var mapWidgetConfig: String? {
31
+ didSet { applyMapWidgetConfigIfNeeded() }
32
+ }
33
+
34
+ private var pendingCommandString: String?
35
+ private var commandDidExecute = false
36
+
10
37
  private(set) var mapWidget: PTRMapWidgetViewController?
11
38
  var semaphore: DispatchSemaphore?
12
39
  var site: PTRSite?
@@ -295,5 +322,156 @@ import PointrKit
295
322
  semaphore.wait()
296
323
  return Pointr.shared.state
297
324
  }
325
+
326
+ // MARK: - Declarative command prop handling
327
+
328
+ override func didMoveToWindow() {
329
+ super.didMoveToWindow()
330
+ guard window != nil, !commandDidExecute, let jsonString = pendingCommandString else { return }
331
+ commandDidExecute = true
332
+ DispatchQueue.global(qos: .userInitiated).async { [weak self] in
333
+ self?.executeCommandFromJSON(jsonString)
334
+ }
335
+ }
336
+
337
+ private func applySDKConfigIfNeeded() {
338
+ guard let jsonString = sdkConfig,
339
+ let data = jsonString.data(using: .utf8),
340
+ let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any] else { return }
341
+ if let clientId = json["clientId"] as? String { PTRNativeLibrary.params.clientIdentifier = clientId }
342
+ if let licenseKey = json["licenseKey"] as? String { PTRNativeLibrary.params.licenseKey = licenseKey }
343
+ if let baseUrl = json["baseUrl"] as? String { PTRNativeLibrary.params.baseUrl = baseUrl }
344
+ if let logLevel = json["logLevel"] as? Int32 {
345
+ PTRNativeLibrary.params.loggerLevel = PTRLoggerLevel(rawValue: logLevel) ?? .error
346
+ }
347
+ PTRNativeLibrary.params.mode = PointrDebugMode()
348
+ PTRNativeLibrary.mapWidgetConfiguration.sdkParams = PTRNativeLibrary.params
349
+ }
350
+
351
+ private func applyMapWidgetConfigIfNeeded() {
352
+ guard let jsonString = mapWidgetConfig,
353
+ let data = jsonString.data(using: .utf8),
354
+ let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any] else { return }
355
+ let cfg = PTRNativeLibrary.mapWidgetConfiguration
356
+ let mirror = Mirror(reflecting: cfg)
357
+ for child in mirror.children {
358
+ guard let key = child.label, let value = json[key] as? Bool else { continue }
359
+ cfg.setValue(value, forKey: key)
360
+ }
361
+ // The following properties are computed in PTRMapWidgetConfiguration, so Mirror
362
+ // does not include them in children. Assign them directly.
363
+ if let value = json["isQuickAccessEnabled"] as? Bool {
364
+ cfg.isQuickAccessEnabled = value
365
+ }
366
+ if let value = json["isMarkMyCarEnabled"] as? Bool {
367
+ cfg.isMarkMyCarEnabled = value
368
+ }
369
+ if let value = json["isInfoButtonEnabled"] as? Bool {
370
+ cfg.isInfoButtonEnabled = value
371
+ }
372
+ if let value = json["shouldFocusOnFirstUserPosition"] as? Bool {
373
+ cfg.shouldFocusOnFirstUserPosition = value
374
+ }
375
+ }
376
+
377
+ private func executeCommandFromJSON(_ jsonString: String) {
378
+ guard let data = jsonString.data(using: .utf8),
379
+ let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
380
+ let type = json["type"] as? String else {
381
+ print("PTRMapWidget: invalid command JSON")
382
+ return
383
+ }
384
+
385
+ let siteId = json["site"] as? String ?? ""
386
+ let buildingId = json["building"] as? String ?? ""
387
+ let levelIndex = json["level"] as? Int ?? 0
388
+ let poiId = json["poi"] as? String ?? ""
389
+ let fromPoiId = json["fromPoi"] as? String ?? ""
390
+ let toPoiId = json["toPoi"] as? String ?? ""
391
+ let sourcePoiId = json["sourcePoi"] as? String ?? ""
392
+ let destinationPoiId = json["destinationPoi"] as? String ?? ""
393
+
394
+ let action: PTRMapWidgetAction
395
+ let commandParams: [String: Any]
396
+
397
+ switch type {
398
+ case "site":
399
+ let location = PTRMapWidgetSiteLocation(siteIdentifier: siteId, isExternalIdentifiers: true)
400
+ let focus = PTRMapWidgetMapFocusAction(location: location, completion: nil)
401
+ commandParams = ["command": "site", "siteExternalIdentifier": siteId]
402
+ focus.completion = { [weak self] error in
403
+ var p = commandParams; p["error"] = error?.errorCode ?? ""
404
+ self?.ptrMapWidgetDidEndLoading(withParameters: p)
405
+ }
406
+ action = focus
407
+
408
+ case "building":
409
+ let location = PTRMapWidgetBuildingLocation(siteIdentifier: siteId, buildingIdentifier: buildingId, isExternalIdentifiers: true)
410
+ let focus = PTRMapWidgetMapFocusAction(location: location, completion: nil)
411
+ commandParams = ["command": "building", "siteExternalIdentifier": siteId, "buildingExternalIdentifier": buildingId]
412
+ focus.completion = { [weak self] error in
413
+ var p = commandParams; p["error"] = error?.errorCode ?? ""
414
+ self?.ptrMapWidgetDidEndLoading(withParameters: p)
415
+ }
416
+ action = focus
417
+
418
+ case "level":
419
+ let location = PTRMapWidgetLevelLocation(siteIdentifier: siteId, buildingIdentifier: buildingId, levelIndex: levelIndex, isExternalIdentifiers: true)
420
+ let focus = PTRMapWidgetMapFocusAction(location: location, completion: nil)
421
+ commandParams = ["command": "level", "siteExternalIdentifier": siteId, "buildingExternalIdentifier": buildingId, "levelIndex": levelIndex]
422
+ focus.completion = { [weak self] error in
423
+ var p = commandParams; p["error"] = error?.errorCode ?? ""
424
+ self?.ptrMapWidgetDidEndLoading(withParameters: p)
425
+ }
426
+ action = focus
427
+
428
+ case "poi":
429
+ let location = PTRMapWidgetPoiLocation(siteIdentifier: siteId, poiIdentifier: poiId, isExternalIdentifiers: true)
430
+ let focus = PTRMapWidgetMapFocusAction(location: location, completion: nil)
431
+ commandParams = ["command": "poi", "siteExternalIdentifier": siteId, "poiExternalIdentifier": poiId]
432
+ focus.completion = { [weak self] error in
433
+ var p = commandParams; p["error"] = error?.errorCode ?? ""
434
+ self?.ptrMapWidgetDidEndLoading(withParameters: p)
435
+ }
436
+ action = focus
437
+
438
+ case "path":
439
+ let wayfinding = PTRMapWidgetWayfindingAction(poiDestination: PTRMapWidgetPoiLocation(siteIdentifier: siteId, poiIdentifier: poiId, isExternalIdentifiers: true))
440
+ commandParams = ["command": "path", "siteExternalIdentifier": siteId, "poiExternalIdentifier": poiId]
441
+ wayfinding.completion = { [weak self] error in
442
+ var p = commandParams; p["error"] = error?.errorCode ?? ""
443
+ self?.ptrMapWidgetDidEndLoading(withParameters: p)
444
+ }
445
+ action = wayfinding
446
+
447
+ case "staticPath":
448
+ DispatchQueue.global(qos: .default).async { [weak self] in
449
+ self?.showStaticPath(siteId, fromPoiExternalIdentifier: fromPoiId, toPoiExternalIdentifier: toPoiId)
450
+ }
451
+ return
452
+
453
+ case "staticWayfinding":
454
+ let srcLocation = PTRMapWidgetPoiLocation(siteIdentifier: siteId, poiIdentifier: sourcePoiId, isExternalIdentifiers: true)
455
+ let dstLocation = PTRMapWidgetPoiLocation(siteIdentifier: siteId, poiIdentifier: destinationPoiId, isExternalIdentifiers: true)
456
+ let sw = PTRMapWidgetStaticWayfindingAction(poiSource: srcLocation, poiDestination: dstLocation)
457
+ commandParams = ["command": "staticWayfinding", "siteExternalIdentifier": siteId, "sourcePoiExternalIdentifier": sourcePoiId, "destinationPoiExternalIdentifier": destinationPoiId]
458
+ sw.completion = { [weak self] error in
459
+ var p = commandParams; p["error"] = error?.localizedDescription ?? ""
460
+ self?.ptrMapWidgetDidEndLoading(withParameters: p)
461
+ }
462
+ action = sw
463
+
464
+ default:
465
+ print("PTRMapWidget: unknown command type '\(type)'")
466
+ return
467
+ }
468
+
469
+ waitForPointrState()
470
+ DispatchQueue.main.async { [weak self] in
471
+ guard let self = self else { return }
472
+ let mapWidget = self.getMapWidget(action)
473
+ self.present(mapWidget)
474
+ }
475
+ }
298
476
  }
299
477
 
@@ -17,6 +17,12 @@ RCT_EXPORT_VIEW_PROPERTY(onMapWidgetDidEndLoading, RCTBubblingEventBlock)
17
17
 
18
18
  RCT_EXPORT_VIEW_PROPERTY(onWayfindingEvent, RCTBubblingEventBlock)
19
19
 
20
+ RCT_EXPORT_VIEW_PROPERTY(command, NSString)
21
+
22
+ RCT_EXPORT_VIEW_PROPERTY(sdkConfig, NSString)
23
+
24
+ RCT_EXPORT_VIEW_PROPERTY(mapWidgetConfig, NSString)
25
+
20
26
  RCT_EXTERN_METHOD(site:(nonnull NSNumber *)reactTag
21
27
  siteExternalIdentifier:(NSString *)siteExternalIdentifier)
22
28
  RCT_EXTERN_METHOD(building:(nonnull NSNumber *)reactTag
@@ -38,6 +38,20 @@ class PTRNativeLibrary: RCTEventEmitter, PTREventManagerDelegate {
38
38
  }
39
39
  mapWidgetConfiguration.setValue(value, forKey: key)
40
40
  }
41
+ // The following properties are computed in PTRMapWidgetConfiguration, so Mirror
42
+ // does not include them in children. Assign them directly.
43
+ if let value = configuration["isQuickAccessEnabled"] as? Bool {
44
+ mapWidgetConfiguration.isQuickAccessEnabled = value
45
+ }
46
+ if let value = configuration["isMarkMyCarEnabled"] as? Bool {
47
+ mapWidgetConfiguration.isMarkMyCarEnabled = value
48
+ }
49
+ if let value = configuration["isInfoButtonEnabled"] as? Bool {
50
+ mapWidgetConfiguration.isInfoButtonEnabled = value
51
+ }
52
+ if let value = configuration["shouldFocusOnFirstUserPosition"] as? Bool {
53
+ mapWidgetConfiguration.shouldFocusOnFirstUserPosition = value
54
+ }
41
55
  }
42
56
  }
43
57
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-pointr",
3
- "version": "9.6.0",
3
+ "version": "9.7.0",
4
4
  "description": "Pointr React-Native Module",
5
5
  "main": "src/index",
6
6
  "files": [
@@ -25,17 +25,28 @@
25
25
  "version": "0.41.0"
26
26
  },
27
27
  "peerDependencies": {
28
- "react-native": ">=0.64.0",
29
- "react": ">=17.0.0"
28
+ "react-native": ">=0.72",
29
+ "react": ">=18"
30
+ },
31
+ "peerDependenciesMeta": {
32
+ "react": {
33
+ "optional": true
34
+ },
35
+ "react-native": {
36
+ "optional": true
37
+ }
30
38
  },
31
39
  "devDependencies": {
32
- "@types/node": "^24.10.1",
33
- "react-native": "^0.82.1"
40
+ "@types/node": ">=20",
41
+ "react-native": "0.82.1",
42
+ "typescript": "^5.8.3"
34
43
  },
35
44
  "engines": {
36
45
  "node": ">=20"
37
46
  },
38
47
  "scripts": {
48
+ "check-react": "./check_react.sh",
49
+ "typescript": "tsc --noEmit",
39
50
  "prepare-dist": "chmod +x prepare-distribution.sh && ./prepare-distribution.sh"
40
51
  }
41
52
  }
@@ -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', '9.6.0'
19
+ s.dependency 'PointrKit', '9.7.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.
@@ -1,5 +1,5 @@
1
1
  import { UIManager } from 'react-native';
2
- import { PTRSiteCommand, PTRBuildingCommand, PTRLevelCommand, PTRPoiCommand, PTRPathCommand, PTRStaticPathCommand, PTRStaticWayfindingCommand, PTRCommand, PTRCommandType, PTRMarkMyCarLevelCommand, PTRMarkMyCarSiteCommand, PTRShowMyCarSiteCommand, PTRStartAndFocusCommand } from 'react-native-pointr/src/PTRCommand';
2
+ import { PTRSiteCommand, PTRBuildingCommand, PTRLevelCommand, PTRPoiCommand, PTRPathCommand, PTRStaticPathCommand, PTRStaticWayfindingCommand, PTRCommand, PTRCommandType, PTRMarkMyCarLevelCommand, PTRMarkMyCarSiteCommand, PTRShowMyCarSiteCommand, PTRStartAndFocusCommand } from './PTRCommand';
3
3
  /**
4
4
  * Handle PTRStartAndFocusCommand specifically
5
5
  * @param reactTag view tag of the map widget
@@ -7,10 +7,8 @@ import { PTRSiteCommand, PTRBuildingCommand, PTRLevelCommand, PTRPoiCommand, PTR
7
7
  */
8
8
  const handleStartAndFocusCommand = (reactTag: number, startAndFocusCommand: PTRStartAndFocusCommand) => {
9
9
  const innerCommand = startAndFocusCommand.command;
10
- console.info('Handling PTRStartAndFocusCommand with type:', innerCommand.type);
11
10
  // Build arguments based on the inner command type
12
11
  let args: any[];
13
- console.info('Inner command details:', innerCommand);
14
12
 
15
13
  switch (innerCommand.type) {
16
14
  case PTRCommandType.SITE: {
@@ -73,7 +71,6 @@ const handleStartAndFocusCommand = (reactTag: number, startAndFocusCommand: PTRS
73
71
  console.error('Unsupported command type in PTRStartAndFocusCommand:', innerCommand.type);
74
72
  return;
75
73
  }
76
- console.info('Dispatching startAndFocus with args:', args);
77
74
  UIManager.dispatchViewManagerCommand(
78
75
  reactTag,
79
76
  'startAndFocus',
@@ -89,15 +86,12 @@ const handleStartAndFocusCommand = (reactTag: number, startAndFocusCommand: PTRS
89
86
  export const showMapWidget = (reactTag: number, ptrCommand: PTRCommand | PTRStartAndFocusCommand) => {
90
87
  // Check if it's a PTRStartAndFocusCommand (which doesn't have a 'type' property)
91
88
  if ('command' in ptrCommand) {
92
- const startAndFocusCommand = ptrCommand as PTRStartAndFocusCommand;
93
- console.log(`Showing map widget with start and focus command: ${startAndFocusCommand.command.type} and reactTag: ${reactTag}`);
94
- handleStartAndFocusCommand(reactTag, startAndFocusCommand);
89
+ handleStartAndFocusCommand(reactTag, ptrCommand as PTRStartAndFocusCommand);
95
90
  return;
96
91
  }
97
92
 
98
93
  // Handle regular PTRCommand
99
94
  const command = ptrCommand as PTRCommand;
100
- console.log(`Showing map widget with command: ${command.type} and reactTag: ${reactTag}`);
101
95
  switch (command.type) {
102
96
  case PTRCommandType.SITE: {
103
97
  const siteCommand = ptrCommand as PTRSiteCommand;
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Map Widget API utilities
3
+ * Provides type-safe command execution for the map widget
4
+ * @module api/MapWidgetApi
5
+ */
6
+
7
+ import { findNodeHandle } from 'react-native';
8
+ import type { PTRCommand } from '../commands';
9
+ import { PTRErrorMessages } from '../constants';
10
+ import { showMapWidget } from '../PTRMapWidgetUtils';
11
+
12
+ /**
13
+ * Execute a command on the map widget
14
+ * @param mapRef - Reference to the map widget component
15
+ * @param command - Command to execute
16
+ * @throws Error if mapRef is null or command is invalid
17
+ */
18
+ export function executeMapCommand(
19
+ mapRef: React.RefObject<any> | any,
20
+ command: PTRCommand
21
+ ): void {
22
+ if (!mapRef) {
23
+ throw new Error(PTRErrorMessages.NO_MAP_REF);
24
+ }
25
+
26
+ const ref = 'current' in mapRef ? mapRef.current : mapRef;
27
+ const reactTag = findNodeHandle(ref);
28
+
29
+ if (!reactTag) {
30
+ throw new Error(PTRErrorMessages.NO_MAP_REF);
31
+ }
32
+
33
+ if (!command || !command.type) {
34
+ throw new Error(PTRErrorMessages.INVALID_COMMAND);
35
+ }
36
+
37
+ try {
38
+ showMapWidget(reactTag, command);
39
+ } catch (error) {
40
+ console.error('Error executing map command:', error);
41
+ throw error;
42
+ }
43
+ }
44
+
45
+
@@ -0,0 +1,241 @@
1
+ /**
2
+ * Pointr SDK singleton wrapper
3
+ * Provides a clean, type-safe API for the Pointr SDK
4
+ * @module api/PointrSdk
5
+ */
6
+
7
+ import { NativeModules, NativeEventEmitter, Platform } from 'react-native';
8
+ import type { PTRConfiguration, PTRMapWidgetConfiguration, PTRStateCallback } from '../types/config';
9
+ import type { PTRPosition } from '../types/PTRPosition';
10
+ import { PTRState, PTRLogLevel, PTRErrorMessages, PTREvents } from '../constants';
11
+
12
+ const LINKING_ERROR =
13
+ `The package 'react-native-pointr' doesn't seem to be linked. Make sure: \n\n` +
14
+ Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) +
15
+ '- You rebuilt the app after installing the package\n' +
16
+ '- You are not using Expo Go\n';
17
+
18
+ const PTRNativePointrLibrary = NativeModules.PTRNativePointrLibrary
19
+ ? NativeModules.PTRNativePointrLibrary
20
+ : new Proxy(
21
+ {},
22
+ {
23
+ get() {
24
+ throw new Error(LINKING_ERROR);
25
+ },
26
+ }
27
+ );
28
+
29
+ /**
30
+ * Singleton class for managing the Pointr SDK
31
+ */
32
+ export class PointrSdk {
33
+ private static instance: PointrSdk | null = null;
34
+ private state: PTRState = PTRState.NOT_INITIALIZED;
35
+ private config: PTRConfiguration | null = null;
36
+ private eventEmitter: NativeEventEmitter;
37
+
38
+ private constructor() {
39
+ this.eventEmitter = new NativeEventEmitter(PTRNativePointrLibrary);
40
+ }
41
+
42
+ /**
43
+ * Get the singleton instance of PointrSdk
44
+ */
45
+ public static getInstance(): PointrSdk {
46
+ if (!PointrSdk.instance) {
47
+ PointrSdk.instance = new PointrSdk();
48
+ }
49
+ return PointrSdk.instance;
50
+ }
51
+
52
+ /**
53
+ * Initialize the Pointr SDK with configuration
54
+ * @param config - Configuration options
55
+ * @throws Error if already initialized or invalid config
56
+ */
57
+ public initialize(config: PTRConfiguration): void {
58
+ if (this.state !== PTRState.NOT_INITIALIZED) {
59
+ throw new Error(PTRErrorMessages.ALREADY_INITIALIZED);
60
+ }
61
+
62
+ if (!config.clientId || !config.licenseKey || !config.baseUrl) {
63
+ throw new Error(PTRErrorMessages.INVALID_CONFIG);
64
+ }
65
+
66
+ this.state = PTRState.INITIALIZING;
67
+ this.config = config;
68
+
69
+ const logLevel = config.logLevel ?? PTRLogLevel.ERROR;
70
+
71
+ try {
72
+ PTRNativePointrLibrary.initialize(
73
+ config.clientId,
74
+ config.licenseKey,
75
+ config.baseUrl,
76
+ logLevel
77
+ );
78
+ this.state = PTRState.INITIALIZED;
79
+ } catch (error) {
80
+ this.state = PTRState.ERROR;
81
+ throw error;
82
+ }
83
+ }
84
+
85
+ /**
86
+ * Start the Pointr SDK
87
+ * @param callback - Optional callback for state changes
88
+ * @throws Error if not initialized
89
+ */
90
+ public start(callback?: PTRStateCallback): void {
91
+ if (this.state === PTRState.NOT_INITIALIZED) {
92
+ throw new Error(PTRErrorMessages.NOT_INITIALIZED);
93
+ }
94
+
95
+ this.state = PTRState.STARTING;
96
+
97
+ try {
98
+ PTRNativePointrLibrary.start((state: string) => {
99
+ this.state = PTRState.RUNNING;
100
+ if (callback) {
101
+ callback(state);
102
+ }
103
+ });
104
+ } catch (error) {
105
+ this.state = PTRState.ERROR;
106
+ throw error;
107
+ }
108
+ }
109
+
110
+ /**
111
+ * Stop the Pointr SDK
112
+ */
113
+ public stop(): void {
114
+ if (this.state === PTRState.RUNNING) {
115
+ try {
116
+ PTRNativePointrLibrary.stop();
117
+ this.state = PTRState.STOPPED;
118
+ } catch (error) {
119
+ console.error('Error stopping Pointr SDK:', error);
120
+ throw error;
121
+ }
122
+ }
123
+ }
124
+
125
+ /**
126
+ * Get the current SDK state
127
+ */
128
+ public getState(): PTRState {
129
+ return this.state;
130
+ }
131
+
132
+ /**
133
+ * Check if SDK is initialized
134
+ */
135
+ public isInitialized(): boolean {
136
+ return this.state !== PTRState.NOT_INITIALIZED;
137
+ }
138
+
139
+ /**
140
+ * Check if SDK is started and running
141
+ */
142
+ public isStarted(): boolean {
143
+ return this.state === PTRState.RUNNING;
144
+ }
145
+
146
+ /**
147
+ * Get the current configuration
148
+ */
149
+ public getConfig(): PTRConfiguration | null {
150
+ return this.config;
151
+ }
152
+
153
+ /**
154
+ * Get the event emitter for subscribing to Pointr events
155
+ */
156
+ public getEventEmitter(): NativeEventEmitter {
157
+ return this.eventEmitter;
158
+ }
159
+
160
+ /**
161
+ * Subscribe to position updates
162
+ * @param callback - Function to call when position is updated
163
+ * @returns Subscription that can be removed
164
+ */
165
+ public onPositionUpdate(callback: (position: any) => void) {
166
+ return this.eventEmitter.addListener(
167
+ PTREvents.ON_POSITION_CALCULATED,
168
+ callback
169
+ );
170
+ }
171
+
172
+ /**
173
+ * Subscribe to building click events
174
+ * @param callback - Function to call when building is clicked
175
+ * @returns Subscription that can be removed
176
+ */
177
+ public onBuildingClick(callback: (event: any) => void) {
178
+ return this.eventEmitter.addListener(
179
+ PTREvents.ON_BUILDING_CLICKED,
180
+ callback
181
+ );
182
+ }
183
+
184
+ /**
185
+ * Subscribe to site click events
186
+ * @param callback - Function to call when site is clicked
187
+ * @returns Subscription that can be removed
188
+ */
189
+ public onSiteClick(callback: (event: any) => void) {
190
+ return this.eventEmitter.addListener(PTREvents.ON_SITE_CLICKED, callback);
191
+ }
192
+
193
+ /**
194
+ * Subscribe to geofence events
195
+ * @param callback - Function to call when geofence event occurs
196
+ * @returns Subscription that can be removed
197
+ */
198
+ public onGeofenceEvent(callback: (event: any) => void) {
199
+ return this.eventEmitter.addListener(
200
+ PTREvents.ON_GEOFENCE_EVENT,
201
+ callback
202
+ );
203
+ }
204
+
205
+ /**
206
+ * Set the map widget configuration
207
+ * Must be called before the map widget renders to take effect.
208
+ * @param config - Map widget configuration options
209
+ */
210
+ public setMapWidgetConfiguration(config: PTRMapWidgetConfiguration): void {
211
+ PTRNativePointrLibrary.setPointrMapWidgetConfiguration(JSON.stringify(config));
212
+ }
213
+
214
+ /**
215
+ * Get the current calculated position.
216
+ * Resolves with the position or null if unavailable.
217
+ */
218
+ public getCurrentLocation(): Promise<PTRPosition | null> {
219
+ return new Promise((resolve) => {
220
+ PTRNativePointrLibrary.getCurrentLocation((result: any) => {
221
+ if (!result || typeof result === 'string') {
222
+ resolve(null);
223
+ } else {
224
+ resolve(result as PTRPosition);
225
+ }
226
+ });
227
+ });
228
+ }
229
+
230
+ /**
231
+ * Get native module reference (for advanced use cases)
232
+ */
233
+ public getNativeModule() {
234
+ return PTRNativePointrLibrary;
235
+ }
236
+ }
237
+
238
+ /**
239
+ * Export singleton instance for easy access
240
+ */
241
+ export const pointrSdk = PointrSdk.getInstance();
@@ -0,0 +1,9 @@
1
+ /**
2
+ * API utilities for the Pointr SDK
3
+ * @module api
4
+ */
5
+
6
+ export { PointrSdk, pointrSdk } from './PointrSdk';
7
+ export {
8
+ executeMapCommand,
9
+ } from './MapWidgetApi';