react-native-nitro-geolocation 0.1.2 → 0.2.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.
Files changed (127) hide show
  1. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/GetCurrentPosition.kt +4 -4
  2. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/NitroGeolocation.kt +642 -50
  3. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/NitroGeolocationCompat.kt +81 -0
  4. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/WatchPosition.kt +4 -4
  5. package/ios/LocationManager.swift +4 -4
  6. package/ios/NitroGeolocation.swift +543 -68
  7. package/ios/NitroGeolocationCompat.swift +109 -0
  8. package/nitrogen/generated/android/c++/JAuthorizationLevel.hpp +61 -0
  9. package/nitrogen/generated/android/c++/JAuthorizationLevelInternal.hpp +3 -4
  10. package/nitrogen/generated/android/c++/JFunc_void.hpp +2 -1
  11. package/nitrogen/generated/android/c++/JFunc_void_GeolocationError.hpp +2 -1
  12. package/nitrogen/generated/android/c++/JFunc_void_GeolocationResponse.hpp +6 -1
  13. package/nitrogen/generated/android/c++/JFunc_void_LocationError.hpp +78 -0
  14. package/nitrogen/generated/android/c++/JGeolocationCoordinates.hpp +25 -17
  15. package/nitrogen/generated/android/c++/JGeolocationError.hpp +5 -1
  16. package/nitrogen/generated/android/c++/JGeolocationOptions.hpp +5 -1
  17. package/nitrogen/generated/android/c++/JGeolocationResponse.hpp +9 -1
  18. package/nitrogen/generated/android/c++/JHybridNitroGeolocationCompatSpec.cpp +109 -0
  19. package/nitrogen/generated/android/c++/JHybridNitroGeolocationCompatSpec.hpp +70 -0
  20. package/nitrogen/generated/android/c++/JHybridNitroGeolocationSpec.cpp +98 -42
  21. package/nitrogen/generated/android/c++/JHybridNitroGeolocationSpec.hpp +7 -5
  22. package/nitrogen/generated/android/c++/JLocationError.hpp +61 -0
  23. package/nitrogen/generated/android/c++/JLocationProvider.hpp +61 -0
  24. package/nitrogen/generated/android/c++/JLocationProviderInternal.hpp +3 -4
  25. package/nitrogen/generated/android/c++/JLocationRequestOptions.hpp +81 -0
  26. package/nitrogen/generated/android/c++/JModernGeolocationConfiguration.hpp +73 -0
  27. package/nitrogen/generated/android/c++/JNullableDouble.cpp +26 -0
  28. package/nitrogen/generated/android/c++/JNullableDouble.hpp +69 -0
  29. package/nitrogen/generated/android/c++/JPermissionStatus.hpp +64 -0
  30. package/nitrogen/generated/android/c++/JRNConfigurationInternal.hpp +5 -1
  31. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/AuthorizationLevel.kt +24 -0
  32. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/AuthorizationLevelInternal.kt +2 -0
  33. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/Func_void.kt +0 -1
  34. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/Func_void_GeolocationError.kt +0 -1
  35. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/Func_void_GeolocationResponse.kt +0 -1
  36. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/Func_void_LocationError.kt +80 -0
  37. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/GeolocationCoordinates.kt +34 -25
  38. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/GeolocationError.kt +27 -18
  39. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/GeolocationOptions.kt +33 -24
  40. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/GeolocationResponse.kt +18 -9
  41. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/HybridNitroGeolocationCompatSpec.kt +92 -0
  42. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/HybridNitroGeolocationSpec.kt +17 -17
  43. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/LocationError.kt +41 -0
  44. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/LocationProvider.kt +24 -0
  45. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/LocationProviderInternal.kt +2 -0
  46. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/LocationRequestOptions.kt +56 -0
  47. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/ModernGeolocationConfiguration.kt +47 -0
  48. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/NullableDouble.kt +59 -0
  49. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/PermissionStatus.kt +25 -0
  50. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/RNConfigurationInternal.kt +24 -15
  51. package/nitrogen/generated/android/nitrogeolocation+autolinking.cmake +3 -0
  52. package/nitrogen/generated/android/nitrogeolocationOnLoad.cpp +14 -2
  53. package/nitrogen/generated/ios/NitroGeolocation+autolinking.rb +1 -1
  54. package/nitrogen/generated/ios/NitroGeolocation-Swift-Cxx-Bridge.cpp +55 -13
  55. package/nitrogen/generated/ios/NitroGeolocation-Swift-Cxx-Bridge.hpp +325 -68
  56. package/nitrogen/generated/ios/NitroGeolocation-Swift-Cxx-Umbrella.hpp +26 -0
  57. package/nitrogen/generated/ios/NitroGeolocationAutolinking.mm +8 -0
  58. package/nitrogen/generated/ios/NitroGeolocationAutolinking.swift +15 -0
  59. package/nitrogen/generated/ios/c++/HybridNitroGeolocationCompatSpecSwift.cpp +11 -0
  60. package/nitrogen/generated/ios/c++/HybridNitroGeolocationCompatSpecSwift.hpp +130 -0
  61. package/nitrogen/generated/ios/c++/HybridNitroGeolocationSpecSwift.hpp +47 -26
  62. package/nitrogen/generated/ios/swift/AuthorizationLevel.swift +44 -0
  63. package/nitrogen/generated/ios/swift/Func_void.swift +1 -1
  64. package/nitrogen/generated/ios/swift/Func_void_GeolocationError.swift +1 -1
  65. package/nitrogen/generated/ios/swift/Func_void_GeolocationResponse.swift +1 -1
  66. package/nitrogen/generated/ios/swift/Func_void_LocationError.swift +47 -0
  67. package/nitrogen/generated/ios/swift/Func_void_PermissionStatus.swift +47 -0
  68. package/nitrogen/generated/ios/swift/Func_void_std__exception_ptr.swift +47 -0
  69. package/nitrogen/generated/ios/swift/GeolocationCoordinates.swift +132 -93
  70. package/nitrogen/generated/ios/swift/GeolocationError.swift +11 -40
  71. package/nitrogen/generated/ios/swift/GeolocationOptions.swift +29 -98
  72. package/nitrogen/generated/ios/swift/GeolocationResponse.swift +5 -16
  73. package/nitrogen/generated/ios/swift/HybridNitroGeolocationCompatSpec.swift +61 -0
  74. package/nitrogen/generated/ios/swift/HybridNitroGeolocationCompatSpec_cxx.swift +244 -0
  75. package/nitrogen/generated/ios/swift/HybridNitroGeolocationSpec.swift +13 -5
  76. package/nitrogen/generated/ios/swift/HybridNitroGeolocationSpec_cxx.swift +66 -64
  77. package/nitrogen/generated/ios/swift/LocationError.swift +35 -0
  78. package/nitrogen/generated/ios/swift/LocationProvider.swift +44 -0
  79. package/nitrogen/generated/ios/swift/LocationRequestOptions.swift +116 -0
  80. package/nitrogen/generated/ios/swift/ModernGeolocationConfiguration.swift +83 -0
  81. package/nitrogen/generated/ios/swift/NullableDouble.swift +18 -0
  82. package/nitrogen/generated/ios/swift/PermissionStatus.swift +48 -0
  83. package/nitrogen/generated/ios/swift/RNConfigurationInternal.swift +16 -50
  84. package/nitrogen/generated/shared/c++/AuthorizationLevel.hpp +80 -0
  85. package/nitrogen/generated/shared/c++/GeolocationCoordinates.hpp +45 -27
  86. package/nitrogen/generated/shared/c++/GeolocationError.hpp +32 -16
  87. package/nitrogen/generated/shared/c++/GeolocationOptions.hpp +38 -22
  88. package/nitrogen/generated/shared/c++/GeolocationResponse.hpp +23 -7
  89. package/nitrogen/generated/shared/c++/HybridNitroGeolocationCompatSpec.cpp +26 -0
  90. package/nitrogen/generated/shared/c++/HybridNitroGeolocationCompatSpec.hpp +79 -0
  91. package/nitrogen/generated/shared/c++/HybridNitroGeolocationSpec.cpp +4 -3
  92. package/nitrogen/generated/shared/c++/HybridNitroGeolocationSpec.hpp +22 -16
  93. package/nitrogen/generated/shared/c++/LocationError.hpp +87 -0
  94. package/nitrogen/generated/shared/c++/LocationProvider.hpp +80 -0
  95. package/nitrogen/generated/shared/c++/LocationRequestOptions.hpp +107 -0
  96. package/nitrogen/generated/shared/c++/ModernGeolocationConfiguration.hpp +100 -0
  97. package/nitrogen/generated/shared/c++/PermissionStatus.hpp +84 -0
  98. package/nitrogen/generated/shared/c++/RNConfigurationInternal.hpp +29 -13
  99. package/package.json +16 -7
  100. package/src/GeolocationClient.ts +116 -0
  101. package/src/NitroGeolocation.nitro.ts +177 -30
  102. package/src/NitroGeolocationCompat.nitro.ts +41 -0
  103. package/src/NitroGeolocationModule.ts +6 -0
  104. package/src/compat/clearWatch.ts +9 -0
  105. package/src/{getCurrentPosition.ts → compat/getCurrentPosition.ts} +7 -3
  106. package/src/compat/index.tsx +34 -0
  107. package/src/compat/requestAuthorization.ts +9 -0
  108. package/src/{setRNConfiguration.ts → compat/setRNConfiguration.ts} +6 -4
  109. package/src/{stopObserving.ts → compat/stopObserving.ts} +4 -2
  110. package/src/{watchPosition.ts → compat/watchPosition.ts} +7 -6
  111. package/src/components/GeolocationProvider.tsx +91 -0
  112. package/src/components/index.ts +13 -0
  113. package/src/hooks/index.ts +9 -0
  114. package/src/hooks/useCheckPermission.ts +46 -0
  115. package/src/hooks/useGetCurrentPosition.ts +44 -0
  116. package/src/hooks/useRequestPermission.ts +38 -0
  117. package/src/hooks/useWatchPosition.ts +127 -0
  118. package/src/index.tsx +72 -27
  119. package/src/types.ts +32 -4
  120. package/src/utils/cache.ts +25 -0
  121. package/src/utils/config.ts +93 -0
  122. package/src/utils/errors.ts +82 -0
  123. package/src/utils/index.ts +27 -0
  124. package/src/utils/provider.ts +61 -0
  125. package/src/utils/quality.ts +98 -0
  126. package/src/clearWatch.ts +0 -13
  127. package/src/requestAuthorization.ts +0 -9
@@ -0,0 +1,9 @@
1
+ import { NitroGeolocationHybridCompatObject } from "../NitroGeolocationModule";
2
+ import type { GeolocationError } from "../types";
3
+
4
+ export function requestAuthorization(
5
+ success?: () => void,
6
+ error?: (error: GeolocationError) => void
7
+ ): void {
8
+ NitroGeolocationHybridCompatObject.requestAuthorization(success, error);
9
+ }
@@ -1,6 +1,6 @@
1
- import type { RNConfigurationInternal } from "./NitroGeolocation.nitro";
2
- import { NitroGeolocationHybridObject } from "./NitroGeolocationModule";
3
- import type { GeolocationConfiguration } from "./types";
1
+ import type { RNConfigurationInternal } from "../NitroGeolocationCompat.nitro";
2
+ import { NitroGeolocationHybridCompatObject } from "../NitroGeolocationModule";
3
+ import type { GeolocationConfiguration } from "../types";
4
4
 
5
5
  // Mapping layer: convert "android" to "android_platform" for C++
6
6
  function mapConfigToInternal(
@@ -18,5 +18,7 @@ function mapConfigToInternal(
18
18
  }
19
19
 
20
20
  export function setRNConfiguration(config: GeolocationConfiguration): void {
21
- NitroGeolocationHybridObject.setRNConfiguration(mapConfigToInternal(config));
21
+ NitroGeolocationHybridCompatObject.setRNConfiguration(
22
+ mapConfigToInternal(config)
23
+ );
22
24
  }
@@ -1,5 +1,5 @@
1
1
  import { NitroModules } from "react-native-nitro-modules";
2
- import type { NitroGeolocation } from "./NitroGeolocation.nitro";
2
+ import type { NitroGeolocationCompat } from "../NitroGeolocationCompat.nitro";
3
3
 
4
4
  /**
5
5
  * Stops observing all location updates.
@@ -7,6 +7,8 @@ import type { NitroGeolocation } from "./NitroGeolocation.nitro";
7
7
  */
8
8
  export function stopObserving(): void {
9
9
  const nitroGeolocation =
10
- NitroModules.createHybridObject<NitroGeolocation>("NitroGeolocation");
10
+ NitroModules.createHybridObject<NitroGeolocationCompat>(
11
+ "NitroGeolocationCompat"
12
+ );
11
13
  nitroGeolocation.stopObserving();
12
14
  }
@@ -1,10 +1,9 @@
1
- import { NitroModules } from "react-native-nitro-modules";
2
- import type { NitroGeolocation } from "./NitroGeolocation.nitro";
1
+ import { NitroGeolocationHybridCompatObject } from "../NitroGeolocationModule";
3
2
  import type {
4
3
  GeolocationError,
5
4
  GeolocationOptions,
6
5
  GeolocationResponse
7
- } from "./types";
6
+ } from "../types";
8
7
 
9
8
  /**
10
9
  * Invokes the success callback whenever the location changes.
@@ -20,7 +19,9 @@ export function watchPosition(
20
19
  error?: (error: GeolocationError) => void,
21
20
  options?: GeolocationOptions
22
21
  ): number {
23
- const nitroGeolocation =
24
- NitroModules.createHybridObject<NitroGeolocation>("NitroGeolocation");
25
- return nitroGeolocation.watchPosition(success, error, options);
22
+ return NitroGeolocationHybridCompatObject.watchPosition(
23
+ success,
24
+ error,
25
+ options
26
+ );
26
27
  }
@@ -0,0 +1,91 @@
1
+ import React, { createContext, useContext } from "react";
2
+ import type { GeolocationClient } from "../GeolocationClient";
3
+
4
+ /**
5
+ * Geolocation context value.
6
+ */
7
+ export interface GeolocationContextValue {
8
+ client: GeolocationClient;
9
+ }
10
+
11
+ /**
12
+ * Geolocation context.
13
+ */
14
+ const GeolocationContext = createContext<GeolocationContextValue | null>(null);
15
+
16
+ /**
17
+ * Hook to access GeolocationClient from context.
18
+ * Throws error if used outside GeolocationClientProvider.
19
+ */
20
+ export function useGeolocationClient(): GeolocationClient {
21
+ const context = useContext(GeolocationContext);
22
+
23
+ if (!context) {
24
+ throw new Error(
25
+ "useGeolocationClient must be used within GeolocationClientProvider. " +
26
+ "Wrap your component with <GeolocationClientProvider client={...}> at the root level."
27
+ );
28
+ }
29
+
30
+ return context.client;
31
+ }
32
+
33
+ /**
34
+ * Props for GeolocationProvider component.
35
+ */
36
+ export interface GeolocationProviderProps {
37
+ /**
38
+ * GeolocationClient instance (required).
39
+ * Create with: new GeolocationClient({...config})
40
+ */
41
+ client: GeolocationClient;
42
+
43
+ /**
44
+ * Child components that can use geolocation hooks.
45
+ */
46
+ children: React.ReactNode;
47
+ }
48
+
49
+ /**
50
+ * Provider component for GeolocationClient.
51
+ *
52
+ * This component should wrap your app at the root level.
53
+ * It provides a GeolocationClient instance to all child components via context.
54
+ *
55
+ * @example
56
+ * ```tsx
57
+ * // Create client instance
58
+ * const geolocationClient = new GeolocationClient({
59
+ * authorizationLevel: 'whenInUse',
60
+ * enableBackgroundLocationUpdates: false,
61
+ * locationProvider: 'auto'
62
+ * });
63
+ *
64
+ * function App() {
65
+ * return (
66
+ * <GeolocationClientProvider client={geolocationClient}>
67
+ * <NavigationContainer>
68
+ * <YourApp />
69
+ * </NavigationContainer>
70
+ * </GeolocationClientProvider>
71
+ * );
72
+ * }
73
+ * ```
74
+ */
75
+ export function GeolocationProvider({
76
+ client,
77
+ children
78
+ }: GeolocationProviderProps) {
79
+ const value: GeolocationContextValue = {
80
+ client
81
+ };
82
+
83
+ return (
84
+ <GeolocationContext.Provider value={value}>
85
+ {children}
86
+ </GeolocationContext.Provider>
87
+ );
88
+ }
89
+
90
+ // Modern alias (preferred)
91
+ export const GeolocationClientProvider = GeolocationProvider;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * React components for geolocation.
3
+ */
4
+
5
+ export {
6
+ GeolocationProvider,
7
+ GeolocationClientProvider,
8
+ useGeolocationClient
9
+ } from "./GeolocationProvider";
10
+ export type {
11
+ GeolocationProviderProps,
12
+ GeolocationContextValue
13
+ } from "./GeolocationProvider";
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Modern React hooks for geolocation.
3
+ * These hooks provide a declarative, React-friendly API for location services.
4
+ */
5
+
6
+ export * from "./useCheckPermission";
7
+ export * from "./useRequestPermission";
8
+ export * from "./useGetCurrentPosition";
9
+ export * from "./useWatchPosition";
@@ -0,0 +1,46 @@
1
+ import type { PermissionStatus } from "../NitroGeolocation.nitro";
2
+ import { useGeolocationClient } from "../components/GeolocationProvider";
3
+
4
+ /**
5
+ * Hook that returns a function to check current location permission status.
6
+ * Does NOT request permission, only checks current state.
7
+ *
8
+ * Must be used within GeolocationClientProvider.
9
+ *
10
+ * @returns Object containing checkPermission function
11
+ *
12
+ * @example
13
+ * ```tsx
14
+ * const geolocationClient = new GeolocationClient({...config});
15
+ *
16
+ * function App() {
17
+ * return (
18
+ * <GeolocationClientProvider client={geolocationClient}>
19
+ * <MyComponent />
20
+ * </GeolocationClientProvider>
21
+ * );
22
+ * }
23
+ *
24
+ * function MyComponent() {
25
+ * const { checkPermission } = useCheckPermission();
26
+ *
27
+ * const handleCheck = async () => {
28
+ * const status = await checkPermission();
29
+ * if (status === 'granted') {
30
+ * // Can use location
31
+ * }
32
+ * };
33
+ *
34
+ * return <Button onPress={handleCheck} />;
35
+ * }
36
+ * ```
37
+ */
38
+ export function useCheckPermission() {
39
+ const client = useGeolocationClient();
40
+
41
+ return {
42
+ checkPermission: (): Promise<PermissionStatus> => {
43
+ return client.checkPermission();
44
+ }
45
+ };
46
+ }
@@ -0,0 +1,44 @@
1
+ import type { LocationRequestOptions } from "../NitroGeolocation.nitro";
2
+ import { useGeolocationClient } from "../components/GeolocationProvider";
3
+ import type { GeolocationResponse } from "../types";
4
+
5
+ /**
6
+ * Hook that returns a function to get current location (one-time request).
7
+ * The returned function throws error if permission denied, timeout, or unavailable.
8
+ *
9
+ * @returns Object containing getCurrentPosition function
10
+ * @throws LocationError with code and message
11
+ *
12
+ * @example
13
+ * ```tsx
14
+ * function MyComponent() {
15
+ * const { getCurrentPosition } = useGetCurrentPosition();
16
+ *
17
+ * const handleGetLocation = async () => {
18
+ * try {
19
+ * const position = await getCurrentPosition({
20
+ * enableHighAccuracy: true,
21
+ * timeout: 15000,
22
+ * });
23
+ * console.log('Lat:', position.coords.latitude);
24
+ * console.log('Lng:', position.coords.longitude);
25
+ * } catch (error) {
26
+ * console.error('Location error:', error.message);
27
+ * }
28
+ * };
29
+ *
30
+ * return <Button onPress={handleGetLocation} />;
31
+ * }
32
+ * ```
33
+ */
34
+ export function useGetCurrentPosition() {
35
+ const client = useGeolocationClient();
36
+
37
+ return {
38
+ getCurrentPosition: (
39
+ options?: LocationRequestOptions
40
+ ): Promise<GeolocationResponse> => {
41
+ return client.getCurrentPosition(options);
42
+ }
43
+ };
44
+ }
@@ -0,0 +1,38 @@
1
+ import type { PermissionStatus } from "../NitroGeolocation.nitro";
2
+ import { useGeolocationClient } from "../components/GeolocationProvider";
3
+
4
+ /**
5
+ * Hook that returns a function to request location permission from the user.
6
+ * Shows system permission dialog if not yet determined.
7
+ *
8
+ * @returns Object containing requestPermission function
9
+ *
10
+ * @example
11
+ * ```tsx
12
+ * function MyComponent() {
13
+ * const { requestPermission } = useRequestPermission();
14
+ *
15
+ * const handleRequest = async () => {
16
+ * try {
17
+ * const status = await requestPermission();
18
+ * if (status === 'granted') {
19
+ * console.log('Permission granted!');
20
+ * }
21
+ * } catch (error) {
22
+ * console.error('Permission error:', error);
23
+ * }
24
+ * };
25
+ *
26
+ * return <Button onPress={handleRequest} />;
27
+ * }
28
+ * ```
29
+ */
30
+ export function useRequestPermission() {
31
+ const client = useGeolocationClient();
32
+
33
+ return {
34
+ requestPermission: (): Promise<PermissionStatus> => {
35
+ return client.requestPermission();
36
+ }
37
+ };
38
+ }
@@ -0,0 +1,127 @@
1
+ import { useEffect, useRef, useState } from "react";
2
+ import type {
3
+ LocationError,
4
+ LocationRequestOptions
5
+ } from "../NitroGeolocation.nitro";
6
+ import { useGeolocationClient } from "../components/GeolocationProvider";
7
+ import type { GeolocationResponse } from "../types";
8
+
9
+ /**
10
+ * Options for useWatchPosition hook.
11
+ */
12
+ export interface UseWatchPositionOptions extends LocationRequestOptions {
13
+ /**
14
+ * Whether to actively watch for location updates.
15
+ * When false, watching is paused and cleanup is performed.
16
+ * @default false
17
+ */
18
+ enabled?: boolean;
19
+ }
20
+
21
+ /**
22
+ * Hook for continuous location tracking.
23
+ * Automatically subscribes/unsubscribes based on component lifecycle.
24
+ *
25
+ * The subscription token is completely hidden from the user.
26
+ * Cleanup is automatic via useEffect.
27
+ *
28
+ * @param options - Location request options
29
+ * @returns Object containing current position data, error, and watching status
30
+ *
31
+ * @example
32
+ * ```tsx
33
+ * function LiveTracking() {
34
+ * const { data, error, isWatching } = useWatchPosition({
35
+ * enabled: true,
36
+ * enableHighAccuracy: true,
37
+ * distanceFilter: 10 // Update every 10 meters
38
+ * });
39
+ *
40
+ * if (!isWatching) return <Text>Not watching</Text>;
41
+ * if (error) return <Text>Error: {error.message}</Text>;
42
+ * if (!data) return <Text>Waiting for location...</Text>;
43
+ *
44
+ * return (
45
+ * <Text>
46
+ * Current: {data.coords.latitude}, {data.coords.longitude}
47
+ * Accuracy: {data.coords.accuracy}m
48
+ * </Text>
49
+ * );
50
+ * }
51
+ * ```
52
+ */
53
+ export function useWatchPosition(options?: UseWatchPositionOptions) {
54
+ const client = useGeolocationClient();
55
+
56
+ const [data, setData] = useState<GeolocationResponse | null>(null);
57
+ const [isWatching, setIsWatching] = useState(false);
58
+
59
+ // Store subscription token (hidden from user!)
60
+ const tokenRef = useRef<string | null>(null);
61
+
62
+ // Track if component is mounted to prevent state updates after unmount
63
+ const isMountedRef = useRef(true);
64
+
65
+ useEffect(() => {
66
+ const enabled = options?.enabled ?? false;
67
+
68
+ if (!enabled) {
69
+ // Not enabled, ensure cleanup
70
+ if (tokenRef.current) {
71
+ client.unwatch(tokenRef.current);
72
+ tokenRef.current = null;
73
+ }
74
+ setIsWatching(false);
75
+ return;
76
+ }
77
+
78
+ // Start watching
79
+ setIsWatching(true);
80
+
81
+ const token = client.watchPosition(
82
+ (position: GeolocationResponse) => {
83
+ // Success callback
84
+ if (!isMountedRef.current) return;
85
+ setData(position);
86
+ },
87
+ (err: LocationError) => {
88
+ // Error callback - throw to be caught by Error Boundary
89
+ if (!isMountedRef.current) return;
90
+ throw new Error(err.message);
91
+ },
92
+ options
93
+ );
94
+
95
+ tokenRef.current = token;
96
+
97
+ // Cleanup function
98
+ return () => {
99
+ if (token) {
100
+ client.unwatch(token);
101
+ }
102
+ };
103
+ }, [
104
+ client,
105
+ options?.enabled,
106
+ options?.enableHighAccuracy,
107
+ options?.distanceFilter,
108
+ options?.interval,
109
+ options?.fastestInterval,
110
+ options?.timeout,
111
+ options?.maximumAge,
112
+ options?.useSignificantChanges
113
+ ]);
114
+
115
+ // Track mount status
116
+ useEffect(() => {
117
+ isMountedRef.current = true;
118
+ return () => {
119
+ isMountedRef.current = false;
120
+ };
121
+ }, []);
122
+
123
+ return {
124
+ data,
125
+ isWatching
126
+ };
127
+ }
package/src/index.tsx CHANGED
@@ -1,34 +1,79 @@
1
- // Export methods
2
- export { clearWatch } from "./clearWatch";
3
- export { getCurrentPosition } from "./getCurrentPosition";
4
- export { requestAuthorization } from "./requestAuthorization";
5
- export { setRNConfiguration } from "./setRNConfiguration";
6
- export { stopObserving } from "./stopObserving";
7
- export { watchPosition } from "./watchPosition";
1
+ /**
2
+ * Modern Geolocation API for React Native.
3
+ *
4
+ * This is the main entry point for the modern, React-friendly API.
5
+ * For legacy compatibility, use: import Geolocation from 'react-native-nitro-geolocation/compat'
6
+ *
7
+ * @example
8
+ * ```tsx
9
+ * import {
10
+ * GeolocationClient,
11
+ * GeolocationClientProvider,
12
+ * useRequestPermission,
13
+ * useGetCurrentPosition,
14
+ * useWatchPosition
15
+ * } from 'react-native-nitro-geolocation';
16
+ *
17
+ * // Create GeolocationClient instance
18
+ * const geolocationClient = new GeolocationClient({
19
+ * authorizationLevel: 'whenInUse',
20
+ * enableBackgroundLocationUpdates: false,
21
+ * locationProvider: 'auto'
22
+ * });
23
+ *
24
+ * function App() {
25
+ * return (
26
+ * <GeolocationClientProvider client={geolocationClient}>
27
+ * <YourApp />
28
+ * </GeolocationClientProvider>
29
+ * );
30
+ * }
31
+ *
32
+ * function LocationButton() {
33
+ * const { getCurrentPosition } = useGetCurrentPosition();
34
+ * const [loading, setLoading] = useState(false);
35
+ *
36
+ * const handlePress = async () => {
37
+ * setLoading(true);
38
+ * try {
39
+ * const pos = await getCurrentPosition({ enableHighAccuracy: true });
40
+ * console.log('Position:', pos);
41
+ * } catch (error) {
42
+ * console.error('Error:', error);
43
+ * } finally {
44
+ * setLoading(false);
45
+ * }
46
+ * };
47
+ *
48
+ * return <Button onPress={handlePress} disabled={loading} />;
49
+ * }
50
+ * ```
51
+ */
8
52
 
9
- // Default export for compatibility
10
- import { clearWatch } from "./clearWatch";
11
- import { getCurrentPosition } from "./getCurrentPosition";
12
- import { requestAuthorization } from "./requestAuthorization";
13
- import { setRNConfiguration } from "./setRNConfiguration";
14
- import { stopObserving } from "./stopObserving";
15
- import { watchPosition } from "./watchPosition";
53
+ // Core
54
+ export { GeolocationClient } from "./GeolocationClient";
55
+ export type { GeolocationClientConfig } from "./GeolocationClient";
16
56
 
17
- const Geolocation = {
18
- setRNConfiguration,
19
- requestAuthorization,
20
- getCurrentPosition,
21
- watchPosition,
22
- clearWatch,
23
- stopObserving
24
- };
57
+ // Components
58
+ export * from "./components";
59
+
60
+ // Hooks
61
+ export * from "./hooks";
62
+
63
+ // Types from Nitro spec
64
+ export type {
65
+ PermissionStatus,
66
+ LocationRequestOptions,
67
+ LocationError
68
+ } from "./NitroGeolocation.nitro";
25
69
 
26
- // Export types
27
70
  export type {
28
- GeolocationConfiguration,
29
71
  GeolocationResponse,
30
- GeolocationError,
31
- GeolocationOptions
72
+ GeolocationCoordinates,
73
+ AuthorizationLevel,
74
+ LocationProvider,
75
+ ModernGeolocationConfiguration
32
76
  } from "./types";
33
77
 
34
- export default Geolocation;
78
+ // Pure utility functions (advanced users only)
79
+ export * from "./utils";
package/src/types.ts CHANGED
@@ -1,6 +1,34 @@
1
1
  // Public API types (compatible with @react-native-community/geolocation)
2
2
  export type AuthorizationLevel = "always" | "whenInUse" | "auto";
3
3
  export type LocationProvider = "playServices" | "android" | "auto";
4
+ export type NullableDouble = number | null;
5
+
6
+ /**
7
+ * User-facing geolocation configuration.
8
+ * This uses "android" instead of "android_platform" for better DX.
9
+ */
10
+ export interface ModernGeolocationConfiguration {
11
+ /**
12
+ * Automatically request location permission when GeolocationProvider mounts.
13
+ * @default false
14
+ */
15
+ autoRequestPermission?: boolean;
16
+
17
+ /**
18
+ * iOS: Authorization level
19
+ */
20
+ authorizationLevel?: AuthorizationLevel;
21
+
22
+ /**
23
+ * iOS: Enable background location updates.
24
+ */
25
+ enableBackgroundLocationUpdates?: boolean;
26
+
27
+ /**
28
+ * Android: Location provider
29
+ */
30
+ locationProvider?: LocationProvider;
31
+ }
4
32
 
5
33
  export interface GeolocationConfiguration {
6
34
  skipPermissionRequests: boolean;
@@ -12,11 +40,11 @@ export interface GeolocationConfiguration {
12
40
  export interface GeolocationCoordinates {
13
41
  latitude: number;
14
42
  longitude: number;
15
- altitude: number | null;
43
+ altitude: NullableDouble;
16
44
  accuracy: number;
17
- altitudeAccuracy: number | null;
18
- heading: number | null;
19
- speed: number | null;
45
+ altitudeAccuracy: NullableDouble;
46
+ heading: NullableDouble;
47
+ speed: NullableDouble;
20
48
  }
21
49
 
22
50
  export interface GeolocationResponse {
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Validates whether a cached location is still fresh based on its age.
3
+ *
4
+ * @param timestampMs - The timestamp of the cached location (in milliseconds)
5
+ * @param currentTimeMs - The current time (in milliseconds)
6
+ * @param maximumAgeMs - The maximum age allowed for the cache (in milliseconds)
7
+ * @returns true if the cache is still valid, false otherwise
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * const timestampMs = Date.now() - 5000; // 5 seconds ago
12
+ * const currentTimeMs = Date.now();
13
+ * const maximumAgeMs = 10000; // 10 seconds
14
+ *
15
+ * isCachedLocationValid(timestampMs, currentTimeMs, maximumAgeMs); // true
16
+ * ```
17
+ */
18
+ export function isCachedLocationValid(
19
+ timestampMs: number,
20
+ currentTimeMs: number,
21
+ maximumAgeMs: number
22
+ ): boolean {
23
+ const age = currentTimeMs - timestampMs;
24
+ return age < maximumAgeMs;
25
+ }