@chaosity/location-client-react 0.1.2 → 0.1.3
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 +126 -38
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -12,12 +12,12 @@ npm install @chaosity/location-client-react @chaosity/location-client
|
|
|
12
12
|
|
|
13
13
|
```tsx
|
|
14
14
|
import { LocationClientProvider, useLocationClient } from '@chaosity/location-client-react'
|
|
15
|
-
import {
|
|
15
|
+
import { SuggestCommand } from '@chaosity/location-client'
|
|
16
16
|
|
|
17
17
|
// 1. Wrap your app with the provider
|
|
18
18
|
function App() {
|
|
19
19
|
return (
|
|
20
|
-
<LocationClientProvider
|
|
20
|
+
<LocationClientProvider getConfig={getLocationConfig}>
|
|
21
21
|
<MapComponent />
|
|
22
22
|
</LocationClientProvider>
|
|
23
23
|
)
|
|
@@ -25,10 +25,12 @@ function App() {
|
|
|
25
25
|
|
|
26
26
|
// 2. Use the client in any component
|
|
27
27
|
function MapComponent() {
|
|
28
|
-
const client = useLocationClient()
|
|
28
|
+
const { client, config, loading, error } = useLocationClient()
|
|
29
29
|
|
|
30
30
|
const searchPlaces = async (query: string) => {
|
|
31
|
-
|
|
31
|
+
if (!client) return
|
|
32
|
+
|
|
33
|
+
const command = new SuggestCommand({
|
|
32
34
|
QueryText: query,
|
|
33
35
|
MaxResults: 5
|
|
34
36
|
})
|
|
@@ -47,17 +49,13 @@ function MapComponent() {
|
|
|
47
49
|
Provides the location client to all child components.
|
|
48
50
|
|
|
49
51
|
```tsx
|
|
50
|
-
<LocationClientProvider
|
|
51
|
-
apiUrl="https://api.example.com"
|
|
52
|
-
token="your-bearer-token"
|
|
53
|
-
>
|
|
52
|
+
<LocationClientProvider getConfig={getLocationConfig}>
|
|
54
53
|
{children}
|
|
55
54
|
</LocationClientProvider>
|
|
56
55
|
```
|
|
57
56
|
|
|
58
57
|
**Props:**
|
|
59
|
-
- `
|
|
60
|
-
- `token` (string, required) - Bearer token for authentication
|
|
58
|
+
- `getConfig` (function, required) - Async function that returns `{ apiUrl: string, token: string }`
|
|
61
59
|
- `children` (ReactNode, required) - Child components
|
|
62
60
|
|
|
63
61
|
### useLocationClient
|
|
@@ -65,14 +63,18 @@ Provides the location client to all child components.
|
|
|
65
63
|
Hook to access the location client in any component.
|
|
66
64
|
|
|
67
65
|
```tsx
|
|
68
|
-
const client = useLocationClient()
|
|
66
|
+
const { client, config, loading, error } = useLocationClient()
|
|
69
67
|
```
|
|
70
68
|
|
|
71
|
-
**Returns:**
|
|
69
|
+
**Returns:**
|
|
70
|
+
- `client` (GeoPlacesClient | null) - The location client instance
|
|
71
|
+
- `config` (ClientConfig | null) - The client configuration (apiUrl, token)
|
|
72
|
+
- `loading` (boolean) - Whether the client is initializing
|
|
73
|
+
- `error` (string | null) - Error message if initialization failed
|
|
72
74
|
|
|
73
75
|
**Throws:** Error if used outside `LocationClientProvider`
|
|
74
76
|
|
|
75
|
-
## Usage with Server Actions
|
|
77
|
+
## Usage with Next.js Server Actions
|
|
76
78
|
|
|
77
79
|
```tsx
|
|
78
80
|
// app/actions/location.ts (Server-side)
|
|
@@ -96,63 +98,149 @@ export async function getLocationConfig() {
|
|
|
96
98
|
}
|
|
97
99
|
}
|
|
98
100
|
|
|
99
|
-
// app/
|
|
101
|
+
// app/layout.tsx (Client-side)
|
|
100
102
|
'use client'
|
|
103
|
+
|
|
101
104
|
import { LocationClientProvider } from '@chaosity/location-client-react'
|
|
102
105
|
import { getLocationConfig } from './actions/location'
|
|
103
106
|
|
|
104
|
-
export default
|
|
105
|
-
const config = await getLocationConfig()
|
|
106
|
-
|
|
107
|
+
export default function RootLayout({ children }) {
|
|
107
108
|
return (
|
|
108
|
-
<LocationClientProvider {
|
|
109
|
-
|
|
109
|
+
<LocationClientProvider getConfig={getLocationConfig}>
|
|
110
|
+
{children}
|
|
110
111
|
</LocationClientProvider>
|
|
111
112
|
)
|
|
112
113
|
}
|
|
113
114
|
```
|
|
114
115
|
|
|
115
|
-
##
|
|
116
|
-
|
|
117
|
-
All AWS Location Service commands are available through the client:
|
|
116
|
+
## Complete Example with MapLibre
|
|
118
117
|
|
|
119
118
|
```tsx
|
|
120
|
-
|
|
119
|
+
'use client'
|
|
121
120
|
|
|
122
|
-
|
|
123
|
-
|
|
121
|
+
import { useLocationClient } from '@chaosity/location-client-react'
|
|
122
|
+
import { GeoPlaces } from '@chaosity/location-client'
|
|
123
|
+
import maplibregl from 'maplibre-gl'
|
|
124
|
+
import MaplibreGeocoder from '@maplibre/maplibre-gl-geocoder'
|
|
125
|
+
import { useEffect, useRef } from 'react'
|
|
126
|
+
|
|
127
|
+
export default function MapComponent() {
|
|
128
|
+
const mapContainer = useRef<HTMLDivElement>(null)
|
|
129
|
+
const map = useRef<maplibregl.Map | null>(null)
|
|
130
|
+
const { config, client, loading, error } = useLocationClient()
|
|
131
|
+
|
|
132
|
+
useEffect(() => {
|
|
133
|
+
if (!mapContainer.current || map.current || loading || !config || !client) return
|
|
134
|
+
|
|
135
|
+
// Initialize map
|
|
136
|
+
const mapInstance = new maplibregl.Map({
|
|
137
|
+
container: mapContainer.current,
|
|
138
|
+
style: `${config.apiUrl}/maps/Standard/descriptor`,
|
|
139
|
+
center: [-123.12, 49.28],
|
|
140
|
+
zoom: 10,
|
|
141
|
+
transformRequest: (url) => {
|
|
142
|
+
if (url.startsWith(config.apiUrl)) {
|
|
143
|
+
return {
|
|
144
|
+
url,
|
|
145
|
+
headers: { 'Authorization': `Bearer ${config.token}` }
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return { url }
|
|
149
|
+
}
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
// Add navigation controls
|
|
153
|
+
mapInstance.addControl(new maplibregl.NavigationControl(), 'top-right')
|
|
124
154
|
|
|
125
|
-
//
|
|
126
|
-
new
|
|
155
|
+
// Add geocoder
|
|
156
|
+
const geoPlaces = new GeoPlaces(config.apiUrl, config.token, mapInstance)
|
|
157
|
+
const geocoder = new MaplibreGeocoder(geoPlaces, {
|
|
158
|
+
maplibregl,
|
|
159
|
+
showResultsWhileTyping: true,
|
|
160
|
+
limit: 30
|
|
161
|
+
})
|
|
162
|
+
mapInstance.addControl(geocoder, 'top-left')
|
|
163
|
+
|
|
164
|
+
// Handle result selection
|
|
165
|
+
geocoder.on('result', async (event) => {
|
|
166
|
+
const { id, result_type } = event.result
|
|
167
|
+
if (result_type === 'Place') {
|
|
168
|
+
const details = await geoPlaces.searchByPlaceId(id)
|
|
169
|
+
console.log('Place details:', details)
|
|
170
|
+
}
|
|
171
|
+
})
|
|
127
172
|
|
|
128
|
-
|
|
129
|
-
new places.ReverseGeocodeCommand({ QueryPosition: [-123.1207, 49.2827] })
|
|
173
|
+
map.current = mapInstance
|
|
130
174
|
|
|
131
|
-
|
|
132
|
-
|
|
175
|
+
return () => {
|
|
176
|
+
if (map.current) {
|
|
177
|
+
map.current.remove()
|
|
178
|
+
map.current = null
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}, [config, client, loading])
|
|
133
182
|
|
|
134
|
-
|
|
135
|
-
|
|
183
|
+
if (error) {
|
|
184
|
+
return <div>Error: {error}</div>
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (loading) {
|
|
188
|
+
return <div>Loading map...</div>
|
|
189
|
+
}
|
|
136
190
|
|
|
137
|
-
|
|
138
|
-
|
|
191
|
+
return <div ref={mapContainer} style={{ width: '100%', height: '600px' }} />
|
|
192
|
+
}
|
|
139
193
|
```
|
|
140
194
|
|
|
141
|
-
|
|
195
|
+
## Available Commands
|
|
196
|
+
|
|
197
|
+
All AWS Location Service commands are available through the client:
|
|
198
|
+
|
|
199
|
+
```tsx
|
|
200
|
+
import {
|
|
201
|
+
SuggestCommand,
|
|
202
|
+
GeocodeCommand,
|
|
203
|
+
ReverseGeocodeCommand,
|
|
204
|
+
GetPlaceCommand,
|
|
205
|
+
SearchTextCommand,
|
|
206
|
+
SearchNearbyCommand
|
|
207
|
+
} from '@chaosity/location-client'
|
|
208
|
+
|
|
209
|
+
function MyComponent() {
|
|
210
|
+
const { client } = useLocationClient()
|
|
211
|
+
|
|
212
|
+
const searchPlaces = async () => {
|
|
213
|
+
const response = await client.send(
|
|
214
|
+
new SuggestCommand({ QueryText: 'Vancouver', MaxResults: 5 })
|
|
215
|
+
)
|
|
216
|
+
return response.ResultItems
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
```
|
|
142
220
|
|
|
143
221
|
## TypeScript Support
|
|
144
222
|
|
|
145
223
|
Full TypeScript support with types from AWS SDK:
|
|
146
224
|
|
|
147
225
|
```tsx
|
|
148
|
-
import { places } from '@chaosity/location-client'
|
|
149
226
|
import type { SuggestCommandOutput } from '@aws-sdk/client-geo-places'
|
|
150
227
|
|
|
228
|
+
const { client } = useLocationClient()
|
|
229
|
+
|
|
151
230
|
const response: SuggestCommandOutput = await client.send(
|
|
152
|
-
new
|
|
231
|
+
new SuggestCommand({ QueryText: 'Vancouver' })
|
|
153
232
|
)
|
|
154
233
|
```
|
|
155
234
|
|
|
235
|
+
## Security Best Practices
|
|
236
|
+
|
|
237
|
+
⚠️ **NEVER expose client credentials in browser code!**
|
|
238
|
+
|
|
239
|
+
- The `getConfig` function should call a server-side API or Server Action
|
|
240
|
+
- Store `client_id` and `client_secret` in server environment variables only
|
|
241
|
+
- Only the JWT token should be sent to the browser
|
|
242
|
+
- Tokens should be short-lived and refreshed as needed
|
|
243
|
+
|
|
156
244
|
## License
|
|
157
245
|
|
|
158
246
|
MIT
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chaosity/location-client-react",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "React bindings for Chaosity Location Service client",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"url": "https://github.com/chaosity-io/location-service-client-react/issues"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@chaosity/location-client": "^0.1.
|
|
30
|
+
"@chaosity/location-client": "^0.1.3"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
33
33
|
"react": "^18.0.0 || ^19.0.0"
|