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,261 +0,0 @@
1
- import { atom, useSetAtom } from 'jotai'
2
- import type { WebView } from 'react-native-webview'
3
- import { useAtom } from 'jotai'
4
- import type {
5
- MessageFromRNToWeb,
6
- WebObjectId,
7
- } from 'react-native-maplibre-gl-js/communication/messages.types'
8
- import { stableStringify } from 'react-native-maplibre-gl-js/react-native/hooks/atoms/useMapAtoms.utils'
9
- import type { WebObjectListeners } from 'react-native-maplibre-gl-js/react-native/components-factory/createWebObjectAsComponent.types'
10
-
11
- /**
12
- * The WebView used to render MapLibre GL JS views (the web world).
13
- */
14
- const webViewAtom = atom<WebView | null>(null)
15
-
16
- /**
17
- * True if the WebView is ready to be used.
18
- */
19
- const isWebWorldReadyAtom = atom(false)
20
-
21
- /**
22
- * True if the mount message of the map component is ready to be sent to the web
23
- * world.
24
- */
25
- const isMapMountMessageReadyAtom = atom(false)
26
-
27
- /**
28
- * True if the mount message of the map component was sent to the web world.
29
- */
30
- const isMapMountMessageDispatchedAtom = atom(false)
31
-
32
- /**
33
- * The queue of messages to be sent to the web world.
34
- */
35
- const messageQueueAtom = atom<MessageFromRNToWeb[]>([])
36
-
37
- /**
38
- * When a method is invoked on a RN object, the call is forwarded to the native
39
- * method within the web world. The pending responses are stored within this
40
- * Map.
41
- */
42
- const webObjectPendingMethodResponses = atom<
43
- Map<string, (result: any) => void>
44
- >(new Map())
45
-
46
- /**
47
- * The callbacks registered to react to web objects events.
48
- */
49
- export const webObjectsListenersAtom = atom<Map<string, WebObjectListeners>>(
50
- new Map(),
51
- )
52
-
53
- /**
54
- * Enqueue message to be sent to the web world.
55
- */
56
- const enqueueMessageAtom = atom(
57
- null,
58
- (get, set, message: MessageFromRNToWeb) => {
59
- const q = get(messageQueueAtom)
60
- set(messageQueueAtom, [...q, message])
61
- },
62
- )
63
-
64
- /**
65
- * Dispatch the given message to the web world immediately (if possible),
66
- * otherwise queue it.
67
- */
68
- const dispatchMessageAtom = atom(
69
- null,
70
- (get, set, message: MessageFromRNToWeb) => {
71
- const isWebWorldReady = get(isWebWorldReadyAtom)
72
- const isMapMountMessageReady = get(isMapMountMessageReadyAtom)
73
- const isMapMountMessageDispatched = get(isMapMountMessageDispatchedAtom)
74
- const webView = get(webViewAtom)
75
-
76
- const isMapMountMessage =
77
- message.type === 'webObjectMount' && message.payload.objectType === 'map'
78
-
79
- if (
80
- !isWebWorldReady ||
81
- !isMapMountMessageReady ||
82
- !isMapMountMessageDispatched ||
83
- !webView
84
- ) {
85
- const q = get(messageQueueAtom)
86
- if (isMapMountMessage) {
87
- // Map mount message must be sent before any other message.
88
- set(messageQueueAtom, [message, ...q])
89
- // If the map mount message was queued in priority, then others messages
90
- // are allowed to be sent.
91
- set(isMapMountMessageReadyAtom, true)
92
- } else {
93
- set(messageQueueAtom, [...q, message])
94
- }
95
- return
96
- }
97
-
98
- webView.postMessage(stableStringify(message))
99
- },
100
- )
101
-
102
- /**
103
- * Flush the queue of messages to the web world (if possible).
104
- */
105
- const flushMessagesAtom = atom(null, (get, set) => {
106
- const isWebWorldReady = get(isWebWorldReadyAtom)
107
- const isMapMountMessageReady = get(isMapMountMessageReadyAtom)
108
- const isMapMountMessageDispatched = get(isMapMountMessageDispatchedAtom)
109
- const webView = get(webViewAtom)
110
- const messageQueue = get(messageQueueAtom)
111
-
112
- if (
113
- !isWebWorldReady ||
114
- !isMapMountMessageReady ||
115
- !webView ||
116
- messageQueue.length === 0
117
- ) {
118
- return
119
- }
120
-
121
- messageQueue.forEach((message) => {
122
- webView.postMessage(stableStringify(message))
123
- })
124
-
125
- set(messageQueueAtom, [])
126
-
127
- // Mark the map mount message as dispatched if it was not.
128
- if (!isMapMountMessageDispatched) {
129
- set(isMapMountMessageDispatchedAtom, true)
130
- }
131
- })
132
-
133
- /**
134
- * Register a promise resolver associated with a pending response to a web world
135
- * native object method call.
136
- */
137
- const setWebObjectPendingMethodResponseAtom = atom(
138
- null,
139
- (
140
- get,
141
- set,
142
- {
143
- requestId,
144
- resolve,
145
- }: { requestId: string; resolve: (result: any) => void },
146
- ) => {
147
- const map = new Map(get(webObjectPendingMethodResponses))
148
- map.set(requestId, resolve)
149
- set(webObjectPendingMethodResponses, map)
150
- },
151
- )
152
-
153
- /**
154
- * Resolve a pending response to a method call on a web object.
155
- */
156
- const resolveWebObjectPendingMethodResponseAtom = atom(
157
- null,
158
- (get, set, { requestId, result }: { requestId: string; result: any }) => {
159
- const map = new Map(get(webObjectPendingMethodResponses))
160
- const resolver = map.get(requestId)
161
- if (resolver) {
162
- resolver(result)
163
- map.delete(requestId)
164
- set(webObjectPendingMethodResponses, map)
165
- }
166
- },
167
- )
168
-
169
- /**
170
- * Delete a pending call to a web object method.
171
- */
172
- const deleteWebObjectPendingMethodResponseAtom = atom(
173
- null,
174
- (get, set, requestId: string) => {
175
- const map = new Map(get(webObjectPendingMethodResponses))
176
- map.delete(requestId)
177
- set(webObjectPendingMethodResponses, map)
178
- },
179
- )
180
-
181
- /**
182
- * Set the callbacks to be executed when receiving an event of a specific native
183
- * web object.
184
- */
185
- const setWebObjectListenersAtom = atom(
186
- null,
187
- (
188
- get,
189
- set,
190
- {
191
- objectId,
192
- listeners,
193
- }: { objectId: WebObjectId; listeners: WebObjectListeners },
194
- ) => {
195
- const map = new Map(get(webObjectsListenersAtom))
196
- map.set(objectId, listeners)
197
- set(webObjectsListenersAtom, map)
198
- },
199
- )
200
-
201
- /**
202
- * Get the callbacks on a specific web object.
203
- */
204
- const getWebObjectListenersAtom = atom(
205
- null,
206
- (
207
- get,
208
- _set,
209
- { objectId }: { objectId: WebObjectId },
210
- ): WebObjectListeners | undefined => {
211
- const map = get(webObjectsListenersAtom)
212
- return map.get(objectId)
213
- },
214
- )
215
-
216
- /**
217
- * Delete callbacks associated with a web object.
218
- */
219
- const deleteWebObjectListenersAtom = atom(
220
- null,
221
- (get, set, { objectId }: { objectId: WebObjectId }) => {
222
- const map = new Map(get(webObjectsListenersAtom))
223
- map.delete(objectId)
224
- set(webObjectsListenersAtom, map)
225
- },
226
- )
227
-
228
- const useMapAtoms = () => {
229
- const [webView, setWebView] = useAtom(webViewAtom)
230
- const [isWebWorldReady, setIsWebWorldReady] = useAtom(isWebWorldReadyAtom)
231
- const [isMapMountMessageReady] = useAtom(isMapMountMessageReadyAtom)
232
-
233
- return {
234
- // Raw atoms.
235
- webView,
236
- setWebView,
237
- isWebWorldReady,
238
- setIsWebWorldReady,
239
- isMapMountMessageReady,
240
- // Messages for the web world.
241
- enqueueMessage: useSetAtom(enqueueMessageAtom),
242
- dispatchMessage: useSetAtom(dispatchMessageAtom),
243
- flushMessages: useSetAtom(flushMessagesAtom),
244
- // Pending responses from the web world on object method calls.
245
- setWebObjectPendingMethodResponse: useSetAtom(
246
- setWebObjectPendingMethodResponseAtom,
247
- ),
248
- resolveWebObjectPendingMethodResponse: useSetAtom(
249
- resolveWebObjectPendingMethodResponseAtom,
250
- ),
251
- deleteWebObjectPendingMethodResponse: useSetAtom(
252
- deleteWebObjectPendingMethodResponseAtom,
253
- ),
254
- // Callbacks to be executed on web world event issued by an object.
255
- setWebObjectListeners: useSetAtom(setWebObjectListenersAtom),
256
- getWebObjectListeners: useSetAtom(getWebObjectListenersAtom),
257
- deleteWebObjectListeners: useSetAtom(deleteWebObjectListenersAtom),
258
- }
259
- }
260
-
261
- export default useMapAtoms
@@ -1,15 +0,0 @@
1
- /**
2
- * Stable stringify for messages that may contain functions. Keep the function
3
- * members as '...' to allow identification of the object type (by default a
4
- * function cannot be stringified and is removed from the final string).
5
- * @param message - The message to be stringified.
6
- * @returns - The stringified message.
7
- */
8
- export const stableStringify = (message: any): string => {
9
- return JSON.stringify(message, (_, value) => {
10
- if (typeof value === 'function') {
11
- return '...'
12
- }
13
- return value
14
- })
15
- }
@@ -1,51 +0,0 @@
1
- import { consoleTransport, logger } from 'react-native-logs'
2
- import pkg from '../../../package.json'
3
-
4
- type LogOrigin = 'RN' | 'Web'
5
-
6
- const BASE_LOGGER = logger.createLogger({
7
- severity: __DEV__ ? 'debug' : 'none',
8
- transport: __DEV__ ? consoleTransport : () => {},
9
- transportOptions: {
10
- colors: {
11
- debug: 'grey',
12
- info: 'greenBright',
13
- error: 'redBright',
14
- },
15
- },
16
- formatFunc: (level, _, args) => {
17
- const timeColumn = new Date().toLocaleTimeString().padEnd(8)
18
- const levelColumn = level.toUpperCase().padEnd(5)
19
- const packageColumn = pkg.name
20
- const fromColumn =
21
- args[0].padEnd(3) + ' ' + (args[0] === 'Web' ? '🌐' : '⚛️')
22
- const funcColumn = args[1].padEnd(20)
23
- const text = args.slice(2).join(' ')
24
- return `${timeColumn} | ${levelColumn} | ${packageColumn} | ${fromColumn} | ${funcColumn} : ${text}`
25
- },
26
- })
27
-
28
- const createLoggerMethod = (level: keyof typeof BASE_LOGGER) => {
29
- return (from: LogOrigin, func: string, ...args: any[]) => {
30
- const stringifiedArgs = args.map((item) =>
31
- typeof item === 'string' ? item : JSON.stringify(item, null, 2),
32
- )
33
- return (BASE_LOGGER[level] as (...args: any[]) => void)(
34
- from,
35
- func !== '' ? func : 'Anonymous function',
36
- ...stringifiedArgs,
37
- )
38
- }
39
- }
40
-
41
- /**
42
- * Logger to be used from the React Native world. Will log to the default
43
- * output. Works only in __DEV__.
44
- */
45
- const RNLogger = {
46
- debug: createLoggerMethod('debug'),
47
- info: createLoggerMethod('info'),
48
- error: createLoggerMethod('error'),
49
- }
50
-
51
- export default RNLogger
package/src/typedoc.ts DELETED
@@ -1,35 +0,0 @@
1
- /**
2
- * Internal types exposed for the documentation, but not by the public API.
3
- * @module Internal types
4
- * @packageDocumentation
5
- */
6
-
7
- import type {
8
- WebObjectComponent,
9
- WebObjectRef,
10
- WebObjectProps,
11
- WebObjectListeners,
12
- WebObjectListenersDefault,
13
- WebObjectListenersWeb,
14
- WebObjectListenerOnRN,
15
- WebObjectListenerOnObject,
16
- WebObjectListenerOnMapLayer,
17
- WebObjectListenerOnHTMLElement,
18
- WebObjectOptionsInferred,
19
- WebObjectMethodsInferred,
20
- } from 'react-native-maplibre-gl-js/react-native/components-factory/createWebObjectAsComponent.types'
21
-
22
- export type {
23
- WebObjectComponent,
24
- WebObjectRef,
25
- WebObjectProps,
26
- WebObjectListeners,
27
- WebObjectListenersDefault,
28
- WebObjectListenersWeb,
29
- WebObjectListenerOnRN,
30
- WebObjectListenerOnObject,
31
- WebObjectListenerOnMapLayer,
32
- WebObjectListenerOnHTMLElement,
33
- WebObjectOptionsInferred,
34
- WebObjectMethodsInferred,
35
- }
@@ -1,44 +0,0 @@
1
- import type MapController from 'react-native-maplibre-gl-js/web/maplibre-gl-js/MapController'
2
- import type {
3
- MessageFromRNToWeb,
4
- MessageFromWebToRN,
5
- } from 'react-native-maplibre-gl-js/communication/messages.types'
6
- import WebLogger from 'react-native-maplibre-gl-js/web/logger/web-logger'
7
-
8
- /**
9
- * From the web world, manage bidirectional communication with the React Native
10
- * one by receiving and sending messages.
11
- */
12
- export default class ReactNativeBridge {
13
- #mapController?: MapController
14
-
15
- constructor() {
16
- const messageHandler = (raw: any) => {
17
- try {
18
- WebLogger.debug(this.constructor.name, raw?.data)
19
- const data = typeof raw?.data === 'string' ? raw.data : raw
20
- const message = JSON.parse(data) as MessageFromRNToWeb
21
- this.mapController?.handleMessage(message)
22
- } catch (error: any) {
23
- WebLogger.error(this.constructor.name, error.message)
24
- }
25
- }
26
- // Listen to React Native messages and forward them to the map controller.
27
- document.addEventListener?.('message', messageHandler)
28
- window.addEventListener?.('message', messageHandler)
29
- }
30
-
31
- set mapController(controller: MapController) {
32
- this.#mapController = controller
33
- }
34
-
35
- get mapController(): MapController | undefined {
36
- return this.#mapController
37
- }
38
-
39
- postMessage(message: MessageFromWebToRN) {
40
- WebLogger.debug(this.postMessage.name, message)
41
- // @ts-ignore
42
- window.ReactNativeWebView?.postMessage(JSON.stringify(message))
43
- }
44
- }
@@ -1,18 +0,0 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta
6
- name="viewport"
7
- content="width=device-width, initial-scale=1, maximum-scale=1, viewport-fit=cover"
8
- />
9
- <style>
10
- html, body, #app { margin:0; padding:0; width:100%; height:100%; }
11
- </style>
12
- <!-- maplibre-gl.css will be inlined by the build step -->
13
- </head>
14
- <body>
15
- <div id="app"></div>
16
- <!-- index.js will be inlined by the build step -->
17
- </body>
18
- </html>
@@ -1,17 +0,0 @@
1
- import 'maplibre-gl/dist/maplibre-gl.css'
2
- import ReactNativeBridge from 'react-native-maplibre-gl-js/web/bridge/ReactNativeBridge'
3
- import MapController from 'react-native-maplibre-gl-js/web/maplibre-gl-js/MapController'
4
-
5
- /**
6
- * Main entry point for the web app to be bundled. Initialize the map controller
7
- * and the bridge to communicate with React Native, then send a ready message.
8
- */
9
- const main = () => {
10
- const controller = new MapController()
11
- const bridge = new ReactNativeBridge()
12
- controller.reactNativeBridge = bridge
13
- bridge.mapController = controller
14
- bridge.postMessage({ type: 'ready' })
15
- }
16
-
17
- main()