react-native-maplibre-gl-js 1.0.0 → 1.0.2
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 +7 -5
- package/lib/module/index.js +4 -4
- package/lib/module/index.js.map +1 -1
- package/lib/module/react-native/components/Map/Map.js +1 -1
- package/lib/module/react-native/components/Map/Map.js.map +1 -1
- package/lib/module/react-native/components/MapProvider/MapProvider.js +5 -5
- package/lib/module/react-native/components/MapProvider/MapProvider.js.map +1 -1
- package/lib/module/react-native/components/Marker/Marker.js +1 -1
- package/lib/module/react-native/components/Marker/Marker.js.map +1 -1
- package/lib/module/react-native/components/Popup/Popup.js +1 -1
- package/lib/module/react-native/components/Popup/Popup.js.map +1 -1
- package/lib/module/react-native/components-factory/createWebObjectAsComponent.js +2 -2
- package/lib/module/react-native/components-factory/createWebObjectAsComponent.js.map +1 -1
- package/lib/module/react-native/components-factory/hooks/useWebObjectMethodsProxy.js +1 -1
- package/lib/module/react-native/components-factory/hooks/useWebObjectMethodsProxy.js.map +1 -1
- package/lib/module/react-native/components-factory/hooks/useWebObjectMountOnLaunch.js +1 -1
- package/lib/module/react-native/components-factory/hooks/useWebObjectMountOnLaunch.js.map +1 -1
- package/lib/module/react-native/hooks/atoms/useMapAtoms.js +1 -1
- package/lib/module/react-native/hooks/atoms/useMapAtoms.js.map +1 -1
- package/lib/module/web/bridge/ReactNativeBridge.js +1 -1
- package/lib/module/web/bridge/ReactNativeBridge.js.map +1 -1
- package/lib/module/web/generated/index.js +2 -2
- package/lib/module/web/generated/index.js.map +1 -1
- package/lib/module/web/maplibre-gl-js/MapController.js +2 -2
- package/lib/module/web/maplibre-gl-js/MapController.js.map +1 -1
- package/lib/typescript/src/communication/messages.types.d.ts +1 -1
- package/lib/typescript/src/communication/messages.types.d.ts.map +1 -1
- package/lib/typescript/src/communication/messages.utils.d.ts +1 -1
- package/lib/typescript/src/communication/messages.utils.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +8 -8
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/react-native/components/Map/Map.d.ts +1 -1
- package/lib/typescript/src/react-native/components/Map/Map.d.ts.map +1 -1
- package/lib/typescript/src/react-native/components/Map/Map.types.d.ts +1 -1
- package/lib/typescript/src/react-native/components/Map/Map.types.d.ts.map +1 -1
- package/lib/typescript/src/react-native/components/MapProvider/MapProvider.d.ts +1 -1
- package/lib/typescript/src/react-native/components/MapProvider/MapProvider.d.ts.map +1 -1
- package/lib/typescript/src/react-native/components/Marker/Marker.d.ts +1 -1
- package/lib/typescript/src/react-native/components/Marker/Marker.d.ts.map +1 -1
- package/lib/typescript/src/react-native/components/Marker/Marker.types.d.ts +2 -2
- package/lib/typescript/src/react-native/components/Marker/Marker.types.d.ts.map +1 -1
- package/lib/typescript/src/react-native/components/Popup/Popup.d.ts +1 -1
- package/lib/typescript/src/react-native/components/Popup/Popup.d.ts.map +1 -1
- package/lib/typescript/src/react-native/components/Popup/Popup.types.d.ts +1 -1
- package/lib/typescript/src/react-native/components/Popup/Popup.types.d.ts.map +1 -1
- package/lib/typescript/src/react-native/components-factory/createWebObjectAsComponent.d.ts +2 -2
- package/lib/typescript/src/react-native/components-factory/createWebObjectAsComponent.d.ts.map +1 -1
- package/lib/typescript/src/react-native/components-factory/hooks/useWebObjectMethodsProxy.d.ts +1 -1
- package/lib/typescript/src/react-native/components-factory/hooks/useWebObjectMethodsProxy.d.ts.map +1 -1
- package/lib/typescript/src/react-native/components-factory/hooks/useWebObjectMountOnLaunch.d.ts +2 -2
- package/lib/typescript/src/react-native/components-factory/hooks/useWebObjectMountOnLaunch.d.ts.map +1 -1
- package/lib/typescript/src/react-native/components-factory/hooks/useWebObjectOptionsUpdater.d.ts +2 -2
- package/lib/typescript/src/react-native/components-factory/hooks/useWebObjectOptionsUpdater.d.ts.map +1 -1
- package/lib/typescript/src/react-native/hooks/atoms/useMapAtoms.d.ts +2 -2
- package/lib/typescript/src/react-native/hooks/atoms/useMapAtoms.d.ts.map +1 -1
- package/lib/typescript/src/typedoc.d.ts +1 -1
- package/lib/typescript/src/typedoc.d.ts.map +1 -1
- package/lib/typescript/src/web/bridge/ReactNativeBridge.d.ts +2 -2
- package/lib/typescript/src/web/bridge/ReactNativeBridge.d.ts.map +1 -1
- package/lib/typescript/src/web/maplibre-gl-js/MapController.d.ts +2 -2
- package/lib/typescript/src/web/maplibre-gl-js/MapController.d.ts.map +1 -1
- package/package.json +20 -14
- package/src/communication/messages.types.ts +0 -121
- package/src/communication/messages.utils.ts +0 -58
- package/src/index.ts +0 -31
- package/src/react-native/components/Map/Map.tsx +0 -14
- package/src/react-native/components/Map/Map.types.ts +0 -149
- package/src/react-native/components/MapProvider/MapProvider.hooks.ts +0 -13
- package/src/react-native/components/MapProvider/MapProvider.tsx +0 -139
- package/src/react-native/components/MapProvider/MapProvider.types.ts +0 -12
- package/src/react-native/components/Marker/Marker.tsx +0 -14
- package/src/react-native/components/Marker/Marker.types.ts +0 -56
- package/src/react-native/components/Popup/Popup.tsx +0 -14
- package/src/react-native/components/Popup/Popup.types.ts +0 -43
- package/src/react-native/components-factory/createWebObjectAsComponent.ts +0 -33
- package/src/react-native/components-factory/createWebObjectAsComponent.types.ts +0 -176
- package/src/react-native/components-factory/hooks/useWebObjectMethodsProxy.ts +0 -61
- package/src/react-native/components-factory/hooks/useWebObjectMountOnLaunch.ts +0 -79
- package/src/react-native/components-factory/hooks/useWebObjectOptionsUpdater.ts +0 -29
- package/src/react-native/hooks/atoms/useMapAtoms.ts +0 -261
- package/src/react-native/hooks/atoms/useMapAtoms.utils.ts +0 -15
- package/src/react-native/logger/rn-logger.ts +0 -51
- package/src/typedoc.ts +0 -35
- package/src/web/bridge/ReactNativeBridge.ts +0 -44
- package/src/web/generated/index.html +0 -18
- package/src/web/generated/index.ts +0 -17
- package/src/web/generated/webview_static_html.ts +0 -23528
- package/src/web/logger/web-logger.ts +0 -36
- package/src/web/maplibre-gl-js/MapController.ts +0 -322
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
import { View } from 'react-native'
|
|
2
|
-
import { WebView, type WebViewMessageEvent } from 'react-native-webview'
|
|
3
|
-
import { WEBVIEW_STATIC_HTML } from 'react-native-maplibre-gl-js/web/generated/webview_static_html'
|
|
4
|
-
import type { MessageFromWebToRN } from 'react-native-maplibre-gl-js/communication/messages.types'
|
|
5
|
-
import RNLogger from 'react-native-maplibre-gl-js/react-native/logger/rn-logger'
|
|
6
|
-
import useMapAtoms from 'react-native-maplibre-gl-js/react-native/hooks/atoms/useMapAtoms'
|
|
7
|
-
import {
|
|
8
|
-
isWebObjectListenerOnHTMLElement,
|
|
9
|
-
isWebObjectListenerOnMapLayer,
|
|
10
|
-
isWebObjectListenerOnObject,
|
|
11
|
-
isWebObjectListenerOnRN,
|
|
12
|
-
} from 'react-native-maplibre-gl-js/communication/messages.utils'
|
|
13
|
-
import { useStyles } from 'react-native-maplibre-gl-js/react-native/components/MapProvider/MapProvider.hooks'
|
|
14
|
-
import { useCallback, useEffect } from 'react'
|
|
15
|
-
import type {
|
|
16
|
-
WebObjectListenerOnHTMLElement,
|
|
17
|
-
WebObjectListenerOnMapLayer,
|
|
18
|
-
WebObjectListenerOnObject,
|
|
19
|
-
WebObjectListenerOnRN,
|
|
20
|
-
} from 'react-native-maplibre-gl-js/react-native/components-factory/createWebObjectAsComponent.types'
|
|
21
|
-
import type { MapProviderProps } from 'react-native-maplibre-gl-js/react-native/components/MapProvider/MapProvider.types'
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Provide the main
|
|
25
|
-
* @param props -
|
|
26
|
-
* @group Components
|
|
27
|
-
*/
|
|
28
|
-
const MapProvider = ({ children }: MapProviderProps) => {
|
|
29
|
-
// States.
|
|
30
|
-
// - Global.
|
|
31
|
-
const {
|
|
32
|
-
setWebView,
|
|
33
|
-
setIsWebWorldReady,
|
|
34
|
-
isMapMountMessageReady,
|
|
35
|
-
flushMessages,
|
|
36
|
-
getWebObjectListeners,
|
|
37
|
-
resolveWebObjectPendingMethodResponse,
|
|
38
|
-
} = useMapAtoms()
|
|
39
|
-
// Theme.
|
|
40
|
-
const styles = useStyles()
|
|
41
|
-
|
|
42
|
-
// On start, the map must be mounted before any other map element. When the
|
|
43
|
-
// mount message of the map is ready, we flush all the pending messages to
|
|
44
|
-
// the web world.
|
|
45
|
-
useEffect(() => {
|
|
46
|
-
if (isMapMountMessageReady) {
|
|
47
|
-
flushMessages()
|
|
48
|
-
}
|
|
49
|
-
}, [flushMessages, isMapMountMessageReady])
|
|
50
|
-
|
|
51
|
-
// Handler of messages from the web world.
|
|
52
|
-
const onMessage = useCallback(
|
|
53
|
-
// Not an anonymous function => get the function name for logger.
|
|
54
|
-
function handleMessage(event: WebViewMessageEvent) {
|
|
55
|
-
try {
|
|
56
|
-
RNLogger.debug('RN', handleMessage.name, event?.nativeEvent?.data)
|
|
57
|
-
const message = JSON.parse(event.nativeEvent.data) as MessageFromWebToRN
|
|
58
|
-
|
|
59
|
-
switch (message.type) {
|
|
60
|
-
case 'console': {
|
|
61
|
-
RNLogger[message.payload.level](
|
|
62
|
-
'Web',
|
|
63
|
-
message.payload.args[0],
|
|
64
|
-
...message.payload.args.slice(1),
|
|
65
|
-
)
|
|
66
|
-
break
|
|
67
|
-
}
|
|
68
|
-
case 'ready': {
|
|
69
|
-
setIsWebWorldReady(true)
|
|
70
|
-
break
|
|
71
|
-
}
|
|
72
|
-
case 'webObjectListenerEvent': {
|
|
73
|
-
// Retrieve the corresponding object listener.
|
|
74
|
-
const listener = getWebObjectListeners({
|
|
75
|
-
objectId: message.payload.objectId,
|
|
76
|
-
})?.[message.payload.eventName]
|
|
77
|
-
// Then, call it.
|
|
78
|
-
if (isWebObjectListenerOnRN(listener)) {
|
|
79
|
-
;(listener as WebObjectListenerOnRN<any>).rnListener(
|
|
80
|
-
message.payload.event,
|
|
81
|
-
)
|
|
82
|
-
}
|
|
83
|
-
if (isWebObjectListenerOnObject(listener)) {
|
|
84
|
-
;(listener as WebObjectListenerOnObject<any>).objectListener(
|
|
85
|
-
message.payload.event,
|
|
86
|
-
)
|
|
87
|
-
}
|
|
88
|
-
if (isWebObjectListenerOnMapLayer(listener)) {
|
|
89
|
-
;(listener as WebObjectListenerOnMapLayer<any>).layerListener(
|
|
90
|
-
message.payload.event,
|
|
91
|
-
)
|
|
92
|
-
}
|
|
93
|
-
if (isWebObjectListenerOnHTMLElement(listener)) {
|
|
94
|
-
;(
|
|
95
|
-
listener as WebObjectListenerOnHTMLElement<any>
|
|
96
|
-
).elementListener(message.payload.event)
|
|
97
|
-
}
|
|
98
|
-
break
|
|
99
|
-
}
|
|
100
|
-
case 'webObjectMethodResponse': {
|
|
101
|
-
resolveWebObjectPendingMethodResponse({
|
|
102
|
-
requestId: message.payload.requestId,
|
|
103
|
-
result: message.payload.result,
|
|
104
|
-
})
|
|
105
|
-
break
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
} catch (error: any) {
|
|
109
|
-
RNLogger.error('RN', handleMessage.name, error.message)
|
|
110
|
-
}
|
|
111
|
-
},
|
|
112
|
-
[
|
|
113
|
-
setIsWebWorldReady,
|
|
114
|
-
getWebObjectListeners,
|
|
115
|
-
resolveWebObjectPendingMethodResponse,
|
|
116
|
-
],
|
|
117
|
-
)
|
|
118
|
-
|
|
119
|
-
return (
|
|
120
|
-
<View style={styles.container}>
|
|
121
|
-
<WebView
|
|
122
|
-
ref={setWebView}
|
|
123
|
-
style={styles.webview}
|
|
124
|
-
originWhitelist={['*']}
|
|
125
|
-
javaScriptEnabled={true}
|
|
126
|
-
allowFileAccess={true}
|
|
127
|
-
domStorageEnabled={true}
|
|
128
|
-
scrollEnabled={false}
|
|
129
|
-
allowUniversalAccessFromFileURLs={true}
|
|
130
|
-
mixedContentMode={'always'}
|
|
131
|
-
onMessage={onMessage}
|
|
132
|
-
source={{ html: WEBVIEW_STATIC_HTML }}
|
|
133
|
-
/>
|
|
134
|
-
{children}
|
|
135
|
-
</View>
|
|
136
|
-
)
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
export default MapProvider
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import createWebObjectAsComponent from 'react-native-maplibre-gl-js/react-native/components-factory/createWebObjectAsComponent'
|
|
2
|
-
import type {
|
|
3
|
-
MarkerProps,
|
|
4
|
-
MarkerRef,
|
|
5
|
-
} from 'react-native-maplibre-gl-js/react-native/components/Marker/Marker.types'
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* MapLibre Marker view.
|
|
9
|
-
* @see {@link https://maplibre.org/maplibre-gl-js/docs/API/classes/Marker/ MapLibre GL JS docs}
|
|
10
|
-
* @group Components
|
|
11
|
-
*/
|
|
12
|
-
const Marker = createWebObjectAsComponent<MarkerRef, MarkerProps>('marker')
|
|
13
|
-
|
|
14
|
-
export default Marker
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type Event,
|
|
3
|
-
type Marker as MapLibreMarker,
|
|
4
|
-
type MarkerOptions as MapLibreMarkerOptions,
|
|
5
|
-
} from 'maplibre-gl'
|
|
6
|
-
import type { HTMLElementDescriptor } from 'react-native-maplibre-gl-js/communication/messages.types'
|
|
7
|
-
import type {
|
|
8
|
-
WebObjectMethodsInferred,
|
|
9
|
-
WebObjectOptionsInferred,
|
|
10
|
-
WebObjectListenerOnHTMLElement,
|
|
11
|
-
WebObjectListenerOnObject,
|
|
12
|
-
WebObjectListenerOnRN,
|
|
13
|
-
WebObjectProps,
|
|
14
|
-
WebObjectRef,
|
|
15
|
-
} from 'react-native-maplibre-gl-js/react-native/components-factory/createWebObjectAsComponent.types'
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* TODO
|
|
19
|
-
* @group Types
|
|
20
|
-
*/
|
|
21
|
-
export type MarkerRef = WebObjectRef<MarkerMethods>
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* TODO
|
|
25
|
-
* @group Types
|
|
26
|
-
*/
|
|
27
|
-
export type MarkerProps = WebObjectProps<MarkerOptions, MarkerListeners>
|
|
28
|
-
|
|
29
|
-
type MarkerMethods = WebObjectMethodsInferred<
|
|
30
|
-
MapLibreMarker,
|
|
31
|
-
{
|
|
32
|
-
addTo: () => Promise<void>
|
|
33
|
-
setEventedParent: (parentId: string) => Promise<void>
|
|
34
|
-
setPopup: (popupId: string) => Promise<void>
|
|
35
|
-
}
|
|
36
|
-
>
|
|
37
|
-
|
|
38
|
-
type MarkerOptions = WebObjectOptionsInferred<
|
|
39
|
-
MapLibreMarkerOptions,
|
|
40
|
-
{
|
|
41
|
-
element?: HTMLElementDescriptor
|
|
42
|
-
}
|
|
43
|
-
>
|
|
44
|
-
|
|
45
|
-
type MarkerListeners = {
|
|
46
|
-
// React native events.
|
|
47
|
-
mount: WebObjectListenerOnRN<void>
|
|
48
|
-
unmount: WebObjectListenerOnRN<void>
|
|
49
|
-
// MapLibre GL JS events.
|
|
50
|
-
// https://maplibre.org/maplibre-gl-js/docs/API/classes/Marker/#events
|
|
51
|
-
dragstart: WebObjectListenerOnObject<Event>
|
|
52
|
-
drag: WebObjectListenerOnObject<Event>
|
|
53
|
-
dragend: WebObjectListenerOnObject<Event>
|
|
54
|
-
// HTMLElement events.
|
|
55
|
-
click: WebObjectListenerOnHTMLElement<MouseEvent>
|
|
56
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
PopupProps,
|
|
3
|
-
PopupRef,
|
|
4
|
-
} from 'react-native-maplibre-gl-js/react-native/components/Popup/Popup.types'
|
|
5
|
-
import createWebObjectAsComponent from 'react-native-maplibre-gl-js/react-native/components-factory/createWebObjectAsComponent'
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* MapLibre Popup view.
|
|
9
|
-
* @see {@link https://maplibre.org/maplibre-gl-js/docs/API/classes/Popup/ MapLibre GL JS docs}
|
|
10
|
-
* @group Components
|
|
11
|
-
*/
|
|
12
|
-
const Popup = createWebObjectAsComponent<PopupRef, PopupProps>('popup')
|
|
13
|
-
|
|
14
|
-
export default Popup
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type Event,
|
|
3
|
-
type Popup as MapLibrePopup,
|
|
4
|
-
type PopupOptions as MapLibrePopupOptions,
|
|
5
|
-
} from 'maplibre-gl'
|
|
6
|
-
import type {
|
|
7
|
-
WebObjectMethodsInferred,
|
|
8
|
-
WebObjectOptionsInferred,
|
|
9
|
-
WebObjectListenerOnObject,
|
|
10
|
-
WebObjectListenerOnRN,
|
|
11
|
-
WebObjectProps,
|
|
12
|
-
WebObjectRef,
|
|
13
|
-
} from 'react-native-maplibre-gl-js/react-native/components-factory/createWebObjectAsComponent.types'
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* TODO
|
|
17
|
-
* @group Types
|
|
18
|
-
*/
|
|
19
|
-
export type PopupRef = WebObjectRef<PopupMethods>
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* TODO
|
|
23
|
-
* @group Types
|
|
24
|
-
*/
|
|
25
|
-
export type PopupProps = WebObjectProps<PopUpOptions, PopupListeners>
|
|
26
|
-
|
|
27
|
-
type PopupMethods = WebObjectMethodsInferred<
|
|
28
|
-
MapLibrePopup,
|
|
29
|
-
{
|
|
30
|
-
addTo: () => Promise<void>
|
|
31
|
-
setEventedParent: (parentId: string) => Promise<void>
|
|
32
|
-
}
|
|
33
|
-
>
|
|
34
|
-
type PopUpOptions = WebObjectOptionsInferred<MapLibrePopupOptions>
|
|
35
|
-
type PopupListeners = {
|
|
36
|
-
// React native events.
|
|
37
|
-
mount: WebObjectListenerOnRN<void>
|
|
38
|
-
unmount: WebObjectListenerOnRN<void>
|
|
39
|
-
// MapLibre GL JS events.
|
|
40
|
-
// https://maplibre.org/maplibre-gl-js/docs/API/classes/Popup/#events
|
|
41
|
-
open: WebObjectListenerOnObject<Event>
|
|
42
|
-
close: WebObjectListenerOnObject<Event>
|
|
43
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { forwardRef, useId } from 'react'
|
|
2
|
-
import type { WebObjectType } from 'react-native-maplibre-gl-js/communication/messages.types'
|
|
3
|
-
import type {
|
|
4
|
-
WebObjectProps,
|
|
5
|
-
WebObjectComponent,
|
|
6
|
-
WebObjectRef,
|
|
7
|
-
} from 'react-native-maplibre-gl-js/react-native/components-factory/createWebObjectAsComponent.types'
|
|
8
|
-
import useWebObjectMountOnLaunch from 'react-native-maplibre-gl-js/react-native/components-factory/hooks/useWebObjectMountOnLaunch'
|
|
9
|
-
import useWebObjectMethodsProxy from 'react-native-maplibre-gl-js/react-native/components-factory/hooks/useWebObjectMethodsProxy'
|
|
10
|
-
|
|
11
|
-
const createWebObjectAsComponent = <
|
|
12
|
-
Ref extends WebObjectRef<any>,
|
|
13
|
-
Props extends WebObjectProps<any, any>,
|
|
14
|
-
>(
|
|
15
|
-
objectType: WebObjectType,
|
|
16
|
-
): WebObjectComponent<Ref, Props> => {
|
|
17
|
-
return forwardRef<Ref, Props>((props, ref) => {
|
|
18
|
-
// UID of the web object.
|
|
19
|
-
const id = useId()
|
|
20
|
-
// Mount the web object on launch.
|
|
21
|
-
useWebObjectMountOnLaunch<Props>(props, id, objectType)
|
|
22
|
-
// Forward a method call on the RN object to the web object.
|
|
23
|
-
useWebObjectMethodsProxy<Ref>(ref, id)
|
|
24
|
-
// TODO needed?
|
|
25
|
-
//useWebObjectOptionsUpdater<Options, Listener>(
|
|
26
|
-
// props, id, dispatchMessage
|
|
27
|
-
//)
|
|
28
|
-
|
|
29
|
-
return null
|
|
30
|
-
})
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export default createWebObjectAsComponent
|
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type ForwardRefExoticComponent,
|
|
3
|
-
type PropsWithoutRef,
|
|
4
|
-
type RefAttributes,
|
|
5
|
-
} from 'react'
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* React Native component that corresponds and perform actions with a web object
|
|
9
|
-
* in the web world.
|
|
10
|
-
* @group Types
|
|
11
|
-
*/
|
|
12
|
-
export type WebObjectComponent<
|
|
13
|
-
Ref extends WebObjectRef<any>,
|
|
14
|
-
Props extends WebObjectProps<any, any>,
|
|
15
|
-
> = ForwardRefExoticComponent<PropsWithoutRef<Props> & RefAttributes<Ref>>
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* React Native ref of a component (corresponds to the web object methods in the
|
|
19
|
-
* web world).
|
|
20
|
-
* @group Types
|
|
21
|
-
*/
|
|
22
|
-
export type WebObjectRef<Methods extends WebObjectMethodsInferred<object>> =
|
|
23
|
-
Omit<Methods, 0>
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* React Native props of a component (used to instantiate the web object in the
|
|
27
|
-
* web world).
|
|
28
|
-
* @group Types
|
|
29
|
-
*/
|
|
30
|
-
export type WebObjectProps<
|
|
31
|
-
Options extends WebObjectOptionsInferred<any>,
|
|
32
|
-
Listeners extends WebObjectListeners,
|
|
33
|
-
> = {
|
|
34
|
-
/**
|
|
35
|
-
* The MapLibreGL JS options used to mount the web object.
|
|
36
|
-
*/
|
|
37
|
-
options?: Partial<Options>
|
|
38
|
-
/**
|
|
39
|
-
* The listeners to be set on the web object events.
|
|
40
|
-
*/
|
|
41
|
-
listeners?: Partial<Listeners>
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Listeners that can be set by a component on the corresponding web object
|
|
46
|
-
* events.
|
|
47
|
-
* Event can be emitted by the web object itself, its HTML element, or be
|
|
48
|
-
* specific to a map layer (if the object is the map).
|
|
49
|
-
* By default, the mount/unmount events are available (they are custom, added
|
|
50
|
-
* on top of the MapLibre GL JS events).
|
|
51
|
-
*
|
|
52
|
-
* Note: sadly, listeners cannot be inferred as Methods and Options, therefore,
|
|
53
|
-
* when adding a new listener, one must ensure that the listeners correspond to
|
|
54
|
-
* the real web object events.
|
|
55
|
-
* @group Types
|
|
56
|
-
*/
|
|
57
|
-
export type WebObjectListeners = WebObjectListenersDefault &
|
|
58
|
-
WebObjectListenersWeb
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Custom events introduced by this library, executed once the web object is
|
|
62
|
-
* (un)mounted to the map.
|
|
63
|
-
* @group Types
|
|
64
|
-
*/
|
|
65
|
-
export type WebObjectListenersDefault = {
|
|
66
|
-
mount?: WebObjectListenerOnRN<void>
|
|
67
|
-
unmount?: WebObjectListenerOnRN<void>
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* MapLibre GL JS events as defined in the official documentation of the object.
|
|
72
|
-
* @group Types
|
|
73
|
-
*/
|
|
74
|
-
export type WebObjectListenersWeb = {
|
|
75
|
-
[eventName: string]:
|
|
76
|
-
| WebObjectListenerOnRN<void>
|
|
77
|
-
| WebObjectListenerOnObject<any>
|
|
78
|
-
| WebObjectListenerOnMapLayer<any>
|
|
79
|
-
| WebObjectListenerOnHTMLElement<any>
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
export type Listener<Event> = (event: Event) => void
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* A listener on an event introduced by the React Native usage.
|
|
86
|
-
* @group Types
|
|
87
|
-
*/
|
|
88
|
-
export type WebObjectListenerOnRN<Event> = {
|
|
89
|
-
rnListener: Listener<Event>
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* A listener to be set on an event emitted by the web object.
|
|
94
|
-
* @group Types
|
|
95
|
-
*/
|
|
96
|
-
export type WebObjectListenerOnObject<Event> = {
|
|
97
|
-
objectListener: Listener<Event>
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* A listener to be set on an event emitted by the web object, but specific to
|
|
102
|
-
* a map layer.
|
|
103
|
-
* @group Types
|
|
104
|
-
*/
|
|
105
|
-
export type WebObjectListenerOnMapLayer<Event> = {
|
|
106
|
-
layerListener: Listener<Event>
|
|
107
|
-
layerId: string
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* A listener to be set on an event emitted by the HTMLElement associated with
|
|
112
|
-
* the web object.
|
|
113
|
-
* @group Types
|
|
114
|
-
*/
|
|
115
|
-
export type WebObjectListenerOnHTMLElement<Event> = {
|
|
116
|
-
elementListener: Listener<Event>
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Options that are used to instantiate a web object.
|
|
121
|
-
* Filter out those options that cannot be set from the RN world and replace
|
|
122
|
-
* them with the given replacements (e.g., HTMLElement that cannot be
|
|
123
|
-
* instantiated in RN is replaced by HTMLElementDescriptor). Also, remove the
|
|
124
|
-
* ones that should not be specified and used.
|
|
125
|
-
* @group Types
|
|
126
|
-
*/
|
|
127
|
-
export type WebObjectOptionsInferred<
|
|
128
|
-
WebObjectOptions,
|
|
129
|
-
ReplacedOptions extends Partial<Record<keyof WebObjectOptions, any>> = {},
|
|
130
|
-
RemovedOptions extends Partial<keyof WebObjectOptions> = never,
|
|
131
|
-
> = Omit<
|
|
132
|
-
Omit<WebObjectOptions, keyof ReplacedOptions> & ReplacedOptions,
|
|
133
|
-
RemovedOptions
|
|
134
|
-
>
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* Methods that are used to call web object methods from the RN world.
|
|
138
|
-
* Filter out those methods that cannot be used from the RN world and replace
|
|
139
|
-
* them with the given replacements (e.g., Marker.setPopup cannot be used
|
|
140
|
-
* because we cannot instantiate a web Popup object in RN, therefore, we
|
|
141
|
-
* override it to allow the usage of a React Native Popup object).
|
|
142
|
-
* The goal of this type is to provide all the web methods of the object
|
|
143
|
-
* within the RN world as a 1:1 mapping.
|
|
144
|
-
* All methods are transformed into async ones that return a Promise of the
|
|
145
|
-
* original return type.
|
|
146
|
-
* To be used with the associated proxy to make the call to the methods
|
|
147
|
-
* effective.
|
|
148
|
-
* @group Types
|
|
149
|
-
*/
|
|
150
|
-
export type WebObjectMethodsInferred<
|
|
151
|
-
WebObject,
|
|
152
|
-
ReplacedMethods extends {
|
|
153
|
-
[K in keyof OnlyMethods<WebObject>]?: (...args: any[]) => any
|
|
154
|
-
} = {},
|
|
155
|
-
> = Merge<
|
|
156
|
-
AllMethodsToAsyncMethods<Merge<OnlyMethods<WebObject>, ReplacedMethods>>,
|
|
157
|
-
{ getId: () => string }
|
|
158
|
-
>
|
|
159
|
-
|
|
160
|
-
type OnlyMethods<T> = {
|
|
161
|
-
[K in keyof T as T[K] extends (...args: any[]) => any ? K : never]: T[K]
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
type AllMethodsToAsyncMethods<T> = {
|
|
165
|
-
[K in keyof T]: T[K] extends (...args: infer A) => infer R
|
|
166
|
-
? (...args: A) => Promise<R>
|
|
167
|
-
: never
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
type Merge<M, N> = {
|
|
171
|
-
[K in keyof M | keyof N]: K extends keyof N
|
|
172
|
-
? N[K]
|
|
173
|
-
: K extends keyof M
|
|
174
|
-
? M[K]
|
|
175
|
-
: never
|
|
176
|
-
}
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type ForwardedRef,
|
|
3
|
-
useCallback,
|
|
4
|
-
useImperativeHandle,
|
|
5
|
-
useMemo,
|
|
6
|
-
} from 'react'
|
|
7
|
-
import useMapAtoms from 'react-native-maplibre-gl-js/react-native/hooks/atoms/useMapAtoms'
|
|
8
|
-
import type { WebObjectRef } from 'react-native-maplibre-gl-js/react-native/components-factory/createWebObjectAsComponent.types'
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Create a proxy to call the methods of the corresponding web world object,
|
|
12
|
-
* then expose it as the given `ref`.
|
|
13
|
-
* @param ref - A React ref object that will be updated to point to the web
|
|
14
|
-
* methods proxy.
|
|
15
|
-
* @param objectId - The ID of the web object that owns the method.
|
|
16
|
-
*/
|
|
17
|
-
export const useWebObjectMethodsProxy = <Ref extends WebObjectRef<any>>(
|
|
18
|
-
ref: ForwardedRef<Ref>,
|
|
19
|
-
objectId: string,
|
|
20
|
-
) => {
|
|
21
|
-
// States.
|
|
22
|
-
// - Global.
|
|
23
|
-
const { dispatchMessage, setWebObjectPendingMethodResponse } = useMapAtoms()
|
|
24
|
-
|
|
25
|
-
const createProxy = useCallback((): Ref => {
|
|
26
|
-
return new Proxy(
|
|
27
|
-
{},
|
|
28
|
-
{
|
|
29
|
-
get(_, propKey) {
|
|
30
|
-
if (propKey === 'getId') {
|
|
31
|
-
return () => objectId
|
|
32
|
-
}
|
|
33
|
-
return (...args: any[]) => {
|
|
34
|
-
return new Promise((resolve) => {
|
|
35
|
-
// TODO generator.
|
|
36
|
-
const requestId = Math.random().toString(36).slice(2, 11)
|
|
37
|
-
// Store the resolver as a pending response.
|
|
38
|
-
setWebObjectPendingMethodResponse({ requestId, resolve })
|
|
39
|
-
// Send the method call message to the WebView.
|
|
40
|
-
dispatchMessage({
|
|
41
|
-
type: 'webObjectMethodCall',
|
|
42
|
-
payload: {
|
|
43
|
-
requestId,
|
|
44
|
-
objectId,
|
|
45
|
-
method: propKey as string,
|
|
46
|
-
args,
|
|
47
|
-
},
|
|
48
|
-
})
|
|
49
|
-
})
|
|
50
|
-
}
|
|
51
|
-
},
|
|
52
|
-
},
|
|
53
|
-
) as Ref
|
|
54
|
-
}, [objectId, dispatchMessage, setWebObjectPendingMethodResponse])
|
|
55
|
-
|
|
56
|
-
const methodsProxy = useMemo(() => createProxy(), [createProxy])
|
|
57
|
-
// Expose the web methods as the component methods.
|
|
58
|
-
useImperativeHandle(ref, () => methodsProxy)
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export default useWebObjectMethodsProxy
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import { type PropsWithoutRef, useCallback, useEffect, useRef } from 'react'
|
|
2
|
-
import useMapAtoms from 'react-native-maplibre-gl-js/react-native/hooks/atoms/useMapAtoms'
|
|
3
|
-
import type { WebObjectType } from 'react-native-maplibre-gl-js/communication/messages.types'
|
|
4
|
-
import type { WebObjectProps } from 'react-native-maplibre-gl-js/react-native/components-factory/createWebObjectAsComponent.types'
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Mount the web object once the React Native one is mounted.
|
|
8
|
-
* @param props - The RN object props.
|
|
9
|
-
* @param objectId - The ID of the web object that owns the method.
|
|
10
|
-
* @param objectType - The type of the associated web object.
|
|
11
|
-
*/
|
|
12
|
-
const useWebObjectMountOnLaunch = <Props extends WebObjectProps<any, any>>(
|
|
13
|
-
props: PropsWithoutRef<Props>,
|
|
14
|
-
objectId: string,
|
|
15
|
-
objectType: WebObjectType,
|
|
16
|
-
) => {
|
|
17
|
-
// Refs.
|
|
18
|
-
const isMounted = useRef<boolean>(false)
|
|
19
|
-
// States.
|
|
20
|
-
// - Global.
|
|
21
|
-
const {
|
|
22
|
-
isWebWorldReady,
|
|
23
|
-
dispatchMessage,
|
|
24
|
-
setWebObjectListeners,
|
|
25
|
-
deleteWebObjectListeners,
|
|
26
|
-
} = useMapAtoms()
|
|
27
|
-
|
|
28
|
-
const mount = useCallback(() => {
|
|
29
|
-
// Mount the component as a web object on the web world.
|
|
30
|
-
dispatchMessage({
|
|
31
|
-
type: `webObjectMount`,
|
|
32
|
-
payload: {
|
|
33
|
-
objectId: objectId,
|
|
34
|
-
objectType,
|
|
35
|
-
options: props.options ?? {},
|
|
36
|
-
listeners: props.listeners ?? {},
|
|
37
|
-
},
|
|
38
|
-
})
|
|
39
|
-
// Register listeners on event from the web world.
|
|
40
|
-
setWebObjectListeners({
|
|
41
|
-
objectId: objectId,
|
|
42
|
-
listeners: props.listeners ?? {},
|
|
43
|
-
})
|
|
44
|
-
isMounted.current = true
|
|
45
|
-
}, [
|
|
46
|
-
objectId,
|
|
47
|
-
objectType,
|
|
48
|
-
props.options,
|
|
49
|
-
props.listeners,
|
|
50
|
-
dispatchMessage,
|
|
51
|
-
setWebObjectListeners,
|
|
52
|
-
])
|
|
53
|
-
|
|
54
|
-
const unmount = useCallback(() => {
|
|
55
|
-
dispatchMessage({
|
|
56
|
-
type: `webObjectUnmount`,
|
|
57
|
-
payload: { objectId },
|
|
58
|
-
})
|
|
59
|
-
deleteWebObjectListeners({ objectId })
|
|
60
|
-
isMounted.current = false
|
|
61
|
-
}, [objectId, dispatchMessage, deleteWebObjectListeners])
|
|
62
|
-
|
|
63
|
-
// On mount/unmount update the web object.
|
|
64
|
-
useEffect(() => {
|
|
65
|
-
if (!isWebWorldReady) {
|
|
66
|
-
return
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
if (!isMounted.current) {
|
|
70
|
-
mount()
|
|
71
|
-
}
|
|
72
|
-
// TODO verify if we unmount here? it sure that it must not be in this
|
|
73
|
-
// use effect, otherwise on start if mount then unmount then mount, but
|
|
74
|
-
// we may have to unmount in another effect
|
|
75
|
-
//return unmount
|
|
76
|
-
}, [objectId, isWebWorldReady, dispatchMessage, props, unmount, mount])
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export default useWebObjectMountOnLaunch
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { useEffect } from 'react'
|
|
2
|
-
import type { WebObjectType } from 'react-native-maplibre-gl-js/communication/messages.types'
|
|
3
|
-
import type {
|
|
4
|
-
WebObjectOptionsInferred,
|
|
5
|
-
WebObjectProps,
|
|
6
|
-
WebObjectListeners,
|
|
7
|
-
} from 'react-native-maplibre-gl-js/react-native/components-factory/createWebObjectAsComponent.types'
|
|
8
|
-
|
|
9
|
-
export const useWebObjectOptionsUpdater = <
|
|
10
|
-
Options extends WebObjectOptionsInferred<WebObjectType>,
|
|
11
|
-
Listeners extends WebObjectListeners,
|
|
12
|
-
>(
|
|
13
|
-
props: WebObjectProps<Options, Listeners>,
|
|
14
|
-
id: string,
|
|
15
|
-
dispatchMessage: (msg: any) => void,
|
|
16
|
-
) => {
|
|
17
|
-
// Refs.
|
|
18
|
-
//const previousProps = useRef<Record<string, any>>({})
|
|
19
|
-
|
|
20
|
-
useEffect(() => {
|
|
21
|
-
// TODO compare previous and new props and update only if new.
|
|
22
|
-
dispatchMessage({
|
|
23
|
-
type: 'webObjectOptionsUpdate',
|
|
24
|
-
payload: { id, options: props.options },
|
|
25
|
-
})
|
|
26
|
-
}, [id, dispatchMessage, props])
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export default useWebObjectOptionsUpdater
|