react-native-maplibre-gl-js 1.0.0 → 1.0.1

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 (29) hide show
  1. package/README.md +7 -5
  2. package/package.json +19 -14
  3. package/src/communication/messages.types.ts +0 -121
  4. package/src/communication/messages.utils.ts +0 -58
  5. package/src/index.ts +0 -31
  6. package/src/react-native/components/Map/Map.tsx +0 -14
  7. package/src/react-native/components/Map/Map.types.ts +0 -149
  8. package/src/react-native/components/MapProvider/MapProvider.hooks.ts +0 -13
  9. package/src/react-native/components/MapProvider/MapProvider.tsx +0 -139
  10. package/src/react-native/components/MapProvider/MapProvider.types.ts +0 -12
  11. package/src/react-native/components/Marker/Marker.tsx +0 -14
  12. package/src/react-native/components/Marker/Marker.types.ts +0 -56
  13. package/src/react-native/components/Popup/Popup.tsx +0 -14
  14. package/src/react-native/components/Popup/Popup.types.ts +0 -43
  15. package/src/react-native/components-factory/createWebObjectAsComponent.ts +0 -33
  16. package/src/react-native/components-factory/createWebObjectAsComponent.types.ts +0 -176
  17. package/src/react-native/components-factory/hooks/useWebObjectMethodsProxy.ts +0 -61
  18. package/src/react-native/components-factory/hooks/useWebObjectMountOnLaunch.ts +0 -79
  19. package/src/react-native/components-factory/hooks/useWebObjectOptionsUpdater.ts +0 -29
  20. package/src/react-native/hooks/atoms/useMapAtoms.ts +0 -261
  21. package/src/react-native/hooks/atoms/useMapAtoms.utils.ts +0 -15
  22. package/src/react-native/logger/rn-logger.ts +0 -51
  23. package/src/typedoc.ts +0 -35
  24. package/src/web/bridge/ReactNativeBridge.ts +0 -44
  25. package/src/web/generated/index.html +0 -18
  26. package/src/web/generated/index.ts +0 -17
  27. package/src/web/generated/webview_static_html.ts +0 -23528
  28. package/src/web/logger/web-logger.ts +0 -36
  29. package/src/web/maplibre-gl-js/MapController.ts +0 -322
@@ -1,36 +0,0 @@
1
- import type { MessageFromWebToRN } from 'react-native-maplibre-gl-js/communication/messages.types'
2
-
3
- // TODO how to disable in prod?
4
- const __DEV__ = true
5
-
6
- const createLoggerMethod = (level: 'debug' | 'info' | 'error') => {
7
- if (!__DEV__) {
8
- return () => {}
9
- }
10
- return (func: string, ...args: any[]) => {
11
- // Send to React Native WebView if available.
12
- try {
13
- const message: MessageFromWebToRN = {
14
- type: 'console',
15
- payload: {
16
- level,
17
- args: [func, ...args],
18
- },
19
- }
20
- // @ts-ignore
21
- window.ReactNativeWebView?.postMessage(JSON.stringify(message))
22
- } catch {}
23
- }
24
- }
25
-
26
- /**
27
- * Logger to be used from the Web world. Will post the log to the React Native
28
- * world. Works only in __DEV__.
29
- */
30
- const WebLogger = {
31
- debug: createLoggerMethod('debug'),
32
- info: createLoggerMethod('info'),
33
- error: createLoggerMethod('error'),
34
- }
35
-
36
- export default WebLogger
@@ -1,322 +0,0 @@
1
- import maplibregl, { type MapLayerEventType } from 'maplibre-gl'
2
- import type ReactNativeBridge from 'react-native-maplibre-gl-js/web/bridge/ReactNativeBridge'
3
- import {
4
- type HTMLElementDescriptor,
5
- type MessageFromRNToWeb,
6
- type WebObjectClass,
7
- } from 'react-native-maplibre-gl-js/communication/messages.types'
8
- import WebLogger from 'react-native-maplibre-gl-js/web/logger/web-logger'
9
- import {
10
- isWebObjectListenerOnHTMLElement,
11
- isWebObjectListenerOnMapLayer,
12
- isWebObjectListenerOnObject,
13
- } from 'react-native-maplibre-gl-js/communication/messages.utils'
14
- import type {
15
- WebObjectListenerOnMapLayer,
16
- WebObjectListeners,
17
- } from 'react-native-maplibre-gl-js/react-native/components-factory/createWebObjectAsComponent.types'
18
-
19
- /**
20
- * Manage the MapLibre GL JS map and its objects. Receive messages from the
21
- * React Native world and act accordingly.
22
- */
23
- export default class MapController {
24
- #reactNativeBridge?: ReactNativeBridge
25
- #objects = new Map<string, WebObjectClass>()
26
- #mapId: string | undefined
27
-
28
- get reactNativeBridge(): ReactNativeBridge {
29
- if (!this.#reactNativeBridge) {
30
- throw new Error('React Native bridge not available')
31
- }
32
- return this.#reactNativeBridge
33
- }
34
-
35
- set reactNativeBridge(bridge: ReactNativeBridge) {
36
- this.#reactNativeBridge = bridge
37
- }
38
-
39
- get map(): maplibregl.Map {
40
- const map = this.#objects.get(this.#mapId ?? '')
41
- if (!map) {
42
- throw new Error('Map not available')
43
- }
44
- return map as maplibregl.Map
45
- }
46
-
47
- handleMessage = (message: MessageFromRNToWeb) => {
48
- WebLogger.info(this.handleMessage.name, message)
49
-
50
- switch (message.type) {
51
- case 'webObjectMount': {
52
- this.#handleWebObjectMountMessage(message)
53
- break
54
- }
55
- case 'webObjectUnmount': {
56
- this.#handleWebObjectUnmountMessage(message)
57
- break
58
- }
59
- case 'webObjectMethodCall': {
60
- this.#handleWebObjectMethodCall(message).then()
61
- break
62
- }
63
- }
64
- }
65
-
66
- #handleWebObjectMountMessage = (
67
- message: Extract<MessageFromRNToWeb, { type: 'webObjectMount' }>,
68
- ) => {
69
- switch (message.payload.objectType) {
70
- case 'map': {
71
- // 1) Create the MapLibre element.
72
- const container = document.getElementById('app')!
73
- const map = new maplibregl.Map({
74
- ...message.payload.options,
75
- container,
76
- })
77
- this.#objects.set(message.payload.objectId, map)
78
- this.#mapId = message.payload.objectId
79
- // 2) Add listeners on the map and/or HTML element.
80
- this.#setObjectListeners(
81
- map,
82
- message.payload.objectId,
83
- message.payload.listeners,
84
- )
85
- break
86
- }
87
- case 'marker': {
88
- // default marker element
89
- const element = this.#buildHTMLElement(message.payload.options.element)
90
- // 1) Create the MapLibre element.
91
- const marker = new maplibregl.Marker({
92
- ...message.payload.options,
93
- element,
94
- })
95
- // TODO setup default location (needed by default)
96
- .setLngLat([0, 0])
97
- .addTo(this.map)
98
- this.#objects.set(message.payload.objectId, marker)
99
- // 2) Add listeners on the map and/or HTML element.
100
- this.#setObjectListeners(
101
- marker,
102
- message.payload.objectId,
103
- message.payload.listeners,
104
- )
105
- break
106
- }
107
- case 'popup': {
108
- // 1) Create the MapLibre element.
109
- const popup = new maplibregl.Popup({
110
- ...message.payload.options,
111
- })
112
- //.addTo(this.map)
113
- this.#objects.set(message.payload.objectId, popup)
114
- // 2) Add listeners on the map and/or HTML element.
115
- this.#setObjectListeners(
116
- popup,
117
- message.payload.objectId,
118
- message.payload.listeners,
119
- )
120
- break
121
- }
122
- }
123
- // TODO confirm its indeed mounted.
124
- this.reactNativeBridge.postMessage({
125
- type: 'webObjectListenerEvent',
126
- payload: {
127
- objectId: message.payload.objectId,
128
- eventName: 'mount',
129
- },
130
- })
131
- }
132
-
133
- #handleWebObjectUnmountMessage = (
134
- message: Extract<MessageFromRNToWeb, { type: 'webObjectUnmount' }>,
135
- ) => {
136
- const object = this.#objects.get(message.payload.objectId)
137
- if (!object) {
138
- return
139
- }
140
-
141
- object.remove()
142
- this.#objects.delete(message.payload.objectId)
143
-
144
- this.reactNativeBridge.postMessage({
145
- type: 'webObjectListenerEvent',
146
- payload: {
147
- objectId: message.payload.objectId,
148
- eventName: 'unmount',
149
- },
150
- })
151
- }
152
-
153
- #handleWebObjectMethodCall = async (
154
- message: Extract<MessageFromRNToWeb, { type: 'webObjectMethodCall' }>,
155
- ) => {
156
- const object = this.#objects.get(message.payload.objectId)
157
-
158
- if (!object) {
159
- return
160
- }
161
-
162
- let result
163
-
164
- if (!this.#runIfSpecialMethod(message, object)) {
165
- result = await this.#runNormalMethod(message, object)
166
- }
167
-
168
- if (!(object instanceof maplibregl.Map)) {
169
- // Always add the object back to the map in case it was removed
170
- // (e.g., Popup's setLngLat or setHTML methods remove it from the map).
171
- object.addTo(this.map)
172
- }
173
-
174
- this.reactNativeBridge.postMessage({
175
- type: 'webObjectMethodResponse',
176
- payload: { requestId: message.payload.requestId, result },
177
- })
178
- }
179
-
180
- #runIfSpecialMethod = (
181
- message: Extract<MessageFromRNToWeb, { type: 'webObjectMethodCall' }>,
182
- object: WebObjectClass,
183
- ) => {
184
- // Special cases for methods that have special parameters not compatible
185
- // with RN (see RN component types definitions). These methods always return
186
- // something. Return undefined if the method is not special.
187
-
188
- if (object instanceof maplibregl.Marker) {
189
- switch (message.payload.method) {
190
- case 'addTo': {
191
- object.addTo(this.map)
192
- return true
193
- }
194
- case 'setEventedParent': {
195
- const parentId = message.payload.args[0] as string
196
- const parent = this.#objects.get(parentId) ?? null
197
- if (parent) {
198
- object.setEventedParent(parent)
199
- }
200
- return true
201
- }
202
- case 'setPopup': {
203
- const popupId = message.payload.args[0] as string
204
- const popup = this.#objects.get(popupId) ?? null
205
- if (popup && popup instanceof maplibregl.Popup) {
206
- object.setPopup(popup)
207
- }
208
- return true
209
- }
210
- }
211
- }
212
- if (object instanceof maplibregl.Popup) {
213
- switch (message.payload.method) {
214
- case 'addTo': {
215
- object.addTo(this.map)
216
- return true
217
- }
218
- case 'setEventedParent': {
219
- const parentId = message.payload.args[0] as string
220
- const parent = this.#objects.get(parentId) ?? null
221
- if (parent) {
222
- object.setEventedParent(parent)
223
- }
224
- return true
225
- }
226
- }
227
- }
228
- return false
229
- }
230
-
231
- #runNormalMethod = async (
232
- message: Extract<MessageFromRNToWeb, { type: 'webObjectMethodCall' }>,
233
- object: WebObjectClass,
234
- ) => {
235
- return await object[message.payload.method as keyof typeof object]?.(
236
- ...message.payload.args,
237
- )
238
- }
239
-
240
- #buildHTMLElement = (
241
- descriptor?: HTMLElementDescriptor,
242
- ): HTMLElement | undefined => {
243
- // From a descriptor, build the corresponding HTMLElement.
244
- if (!descriptor) {
245
- return undefined
246
- }
247
-
248
- const element = document.createElement(descriptor.tagName ?? 'div')
249
- element.className = descriptor.className ?? ''
250
-
251
- if (descriptor.attributes) {
252
- for (const [name, value] of Object.entries(descriptor.attributes)) {
253
- element.setAttribute(name, value)
254
- }
255
- }
256
- if (descriptor.style) {
257
- Object.assign(element.style, descriptor.style)
258
- }
259
- if (descriptor.dataset) {
260
- for (const [name, value] of Object.entries(descriptor.dataset)) {
261
- ;(element.dataset as any)[name] = value
262
- }
263
- }
264
- if (descriptor.innerHTML !== undefined) {
265
- element.innerHTML = descriptor.innerHTML
266
- }
267
-
268
- return element
269
- }
270
-
271
- #setObjectListeners = (
272
- object: WebObjectClass,
273
- objectId: string,
274
- listeners?: WebObjectListeners,
275
- ) => {
276
- if (!listeners) {
277
- return
278
- }
279
- Object.entries(listeners).forEach(([eventName, listener]) => {
280
- const sendEventToReactNative = (event: any) => {
281
- // Remove circular references that cannot be serialized.
282
- delete event.target
283
- // Send the event to the React Native listener.
284
- this.reactNativeBridge.postMessage({
285
- type: 'webObjectListenerEvent',
286
- payload: {
287
- objectId,
288
- eventName,
289
- event,
290
- },
291
- })
292
- }
293
-
294
- // Attach the listener to the object.
295
- if (isWebObjectListenerOnObject(listener)) {
296
- object.on(eventName, sendEventToReactNative)
297
- }
298
- // Attach the listener to a map layer.
299
- if (isWebObjectListenerOnMapLayer(listener)) {
300
- // Listening to only one layer of the map is only possible on map
301
- // events.
302
- if (object instanceof maplibregl.Map) {
303
- object.on(
304
- eventName as keyof MapLayerEventType,
305
- (listener as WebObjectListenerOnMapLayer<any>).layerId,
306
- sendEventToReactNative,
307
- )
308
- }
309
- }
310
- // Attach the listener to the HTML element of the object
311
- if (isWebObjectListenerOnHTMLElement(listener)) {
312
- // Listening to the HTML element events is not possible on the map
313
- // object.
314
- if (!(object instanceof maplibregl.Map)) {
315
- object
316
- .getElement()
317
- .addEventListener(eventName, sendEventToReactNative)
318
- }
319
- }
320
- })
321
- }
322
- }