Upgrade @maplibre/maplibre-react-native from 10 to 11
v11 is a breaking API rework (renamed components, restructured props, event payloads on nativeEvent) and requires React Native's new architecture. Doing it as a manual migration instead of taking dependabot's #268 because the renames need code changes. Changes in apps/mobile: - RouteMap.tsx — switch to named imports; rename MapView→Map, ShapeSource→GeoJSONSource (with shape→data), LineLayer→Layer (with type="line" and paint instead of style), MarkerView→ ViewAnnotation (with coordinate→lngLat); Camera uses initialViewState with bounds as [w,s,e,n] and a separate padding object; onLongPress reads lngLat from event.nativeEvent. - app.config.ts — set `newArchEnabled: true`. MapLibre RN v11 supports only the new architecture, so Fabric/TurboModules must be on for the Expo prebuild. Cast the config type since Expo SDK 55's ExpoConfig typings don't yet include the field (the runtime does). - package.json — `^10.4.2` → `^11.0.0`. Supersedes dependabot #268; it'll auto-close once this merges. Runtime verification requires an EAS dev build (native deps changed + new arch flipped). JS-only surface typechecks + lints + unit tests clean locally. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
c3d9514f4d
commit
7e302b1fbe
4 changed files with 104 additions and 53 deletions
|
|
@ -1,11 +1,16 @@
|
|||
import { ExpoConfig, ConfigContext } from "expo/config";
|
||||
|
||||
export default ({ config }: ConfigContext): ExpoConfig => ({
|
||||
// `newArchEnabled` isn't in the Expo SDK 55 typings yet but is an
|
||||
// accepted runtime flag. MapLibre RN v11 requires the new architecture.
|
||||
type ExpoConfigWithNewArch = ExpoConfig & { newArchEnabled?: boolean };
|
||||
|
||||
export default ({ config }: ConfigContext): ExpoConfigWithNewArch => ({
|
||||
...config,
|
||||
name: "trails.cool",
|
||||
slug: "mobile",
|
||||
version: "0.0.1",
|
||||
scheme: "trailscool",
|
||||
newArchEnabled: true,
|
||||
orientation: "portrait",
|
||||
icon: "./assets/icon.png",
|
||||
userInterfaceStyle: "light",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,13 @@
|
|||
import { useRef, useCallback } from "react";
|
||||
import { StyleSheet, View, Text } from "react-native";
|
||||
import MapLibreGL from "@maplibre/maplibre-react-native";
|
||||
import {
|
||||
Camera,
|
||||
GeoJSONSource,
|
||||
Layer,
|
||||
Map,
|
||||
ViewAnnotation,
|
||||
type CameraRef,
|
||||
} from "@maplibre/maplibre-react-native";
|
||||
import type { Waypoint } from "@trails-cool/types";
|
||||
import type { RouteSegment } from "./use-route-editor";
|
||||
|
||||
|
|
@ -40,7 +47,10 @@ export function RouteMap({
|
|||
onWaypointDragEnd: _onWaypointDragEnd,
|
||||
onWaypointPress,
|
||||
}: RouteMapProps) {
|
||||
if (!MapLibreGL) {
|
||||
// `Map` is undefined when the native module isn't linked (e.g. running
|
||||
// in Expo Go). Same safety net as before the v11 upgrade, just against
|
||||
// a named import instead of the removed default export.
|
||||
if (!Map) {
|
||||
return (
|
||||
<View style={styles.fallback}>
|
||||
<Text style={styles.fallbackText}>Map</Text>
|
||||
|
|
@ -64,15 +74,16 @@ function RouteMapInner({
|
|||
onWaypointDragEnd: _onWaypointDragEnd,
|
||||
onWaypointPress,
|
||||
}: RouteMapProps) {
|
||||
const ML = MapLibreGL!;
|
||||
const cameraRef = useRef<MapLibreGL.CameraRef>(null);
|
||||
const cameraRef = useRef<CameraRef>(null);
|
||||
|
||||
const handleLongPress = useCallback(
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(event: any) => {
|
||||
const coords = event?.geometry?.coordinates;
|
||||
if (Array.isArray(coords) && coords.length >= 2) {
|
||||
onLongPress(coords[1] as number, coords[0] as number);
|
||||
// v11 event shape: payload lives on `event.nativeEvent.lngLat`
|
||||
// (the old `event.geometry.coordinates` is gone).
|
||||
const lngLat = event?.nativeEvent?.lngLat;
|
||||
if (Array.isArray(lngLat) && lngLat.length >= 2) {
|
||||
onLongPress(lngLat[1] as number, lngLat[0] as number);
|
||||
}
|
||||
},
|
||||
[onLongPress],
|
||||
|
|
@ -96,64 +107,59 @@ function RouteMapInner({
|
|||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<ML.MapView
|
||||
<Map
|
||||
style={styles.map}
|
||||
mapStyle={OSM_STYLE}
|
||||
onLongPress={handleLongPress}
|
||||
attributionEnabled={false}
|
||||
logoEnabled={false}
|
||||
attribution={false}
|
||||
logo={false}
|
||||
>
|
||||
{bounds && (
|
||||
<ML.Camera
|
||||
<Camera
|
||||
ref={cameraRef}
|
||||
defaultSettings={{
|
||||
bounds: {
|
||||
ne: bounds.ne,
|
||||
sw: bounds.sw,
|
||||
paddingTop: 40,
|
||||
paddingBottom: 40,
|
||||
paddingLeft: 40,
|
||||
paddingRight: 40,
|
||||
},
|
||||
initialViewState={{
|
||||
bounds: [bounds.sw[0], bounds.sw[1], bounds.ne[0], bounds.ne[1]],
|
||||
padding: { top: 40, right: 40, bottom: 40, left: 40 },
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{!bounds && (
|
||||
<ML.Camera
|
||||
defaultSettings={{
|
||||
centerCoordinate: [10.0, 50.1],
|
||||
zoomLevel: 6,
|
||||
<Camera
|
||||
initialViewState={{
|
||||
center: [10.0, 50.1],
|
||||
zoom: 6,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Route line */}
|
||||
<ML.ShapeSource id="route" shape={routeGeojson}>
|
||||
<ML.LineLayer
|
||||
<GeoJSONSource id="route" data={routeGeojson}>
|
||||
<Layer
|
||||
id="route-line"
|
||||
style={{
|
||||
lineColor: "#2563eb",
|
||||
lineWidth: 4,
|
||||
lineOpacity: computing ? 0.4 : 1,
|
||||
type="line"
|
||||
paint={{
|
||||
"line-color": "#2563eb",
|
||||
"line-width": 4,
|
||||
"line-opacity": computing ? 0.4 : 1,
|
||||
}}
|
||||
/>
|
||||
</ML.ShapeSource>
|
||||
</GeoJSONSource>
|
||||
|
||||
{/* Waypoint markers */}
|
||||
{waypoints.map((wp, i) => (
|
||||
<ML.MarkerView
|
||||
<ViewAnnotation
|
||||
key={`wp-${i}`}
|
||||
coordinate={[wp.lon, wp.lat]}
|
||||
lngLat={[wp.lon, wp.lat]}
|
||||
>
|
||||
<WaypointMarker
|
||||
index={i}
|
||||
isDayBreak={wp.isDayBreak}
|
||||
onPress={() => onWaypointPress(i)}
|
||||
/>
|
||||
</ML.MarkerView>
|
||||
</ViewAnnotation>
|
||||
))}
|
||||
</ML.MapView>
|
||||
</Map>
|
||||
|
||||
{computing && (
|
||||
<View style={styles.computingBanner}>
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
"dependencies": {
|
||||
"@expo/metro-runtime": "^55.0.9",
|
||||
"@gorhom/bottom-sheet": "^5.2.9",
|
||||
"@maplibre/maplibre-react-native": "^10.4.2",
|
||||
"@maplibre/maplibre-react-native": "^11.0.0",
|
||||
"@sentry/cli": "^3.3.5",
|
||||
"@sentry/react-native": "~7.11.0",
|
||||
"@trails-cool/api": "workspace:*",
|
||||
|
|
|
|||
72
pnpm-lock.yaml
generated
72
pnpm-lock.yaml
generated
|
|
@ -313,8 +313,8 @@ importers:
|
|||
specifier: ^5.2.9
|
||||
version: 5.2.9(@types/react@19.2.14)(react-native-gesture-handler@2.31.1(react-native@0.83.4(@babel/core@7.29.0)(@react-native/metro-config@0.85.1(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.5))(react@19.2.5))(react-native-reanimated@4.3.0(react-native-worklets@0.8.1(@babel/core@7.29.0)(@react-native/metro-config@0.85.1(@babel/core@7.29.0))(react-native@0.83.4(@babel/core@7.29.0)(@react-native/metro-config@0.85.1(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.5))(react@19.2.5))(react-native@0.83.4(@babel/core@7.29.0)(@react-native/metro-config@0.85.1(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.5))(react@19.2.5))(react-native@0.83.4(@babel/core@7.29.0)(@react-native/metro-config@0.85.1(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.5))(react@19.2.5)
|
||||
'@maplibre/maplibre-react-native':
|
||||
specifier: ^10.4.2
|
||||
version: 10.4.2(@expo/config-plugins@55.0.8)(@types/geojson@7946.0.16)(@types/react@19.2.14)(react-native@0.83.4(@babel/core@7.29.0)(@react-native/metro-config@0.85.1(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.5))(react@19.2.5)
|
||||
specifier: ^11.0.0
|
||||
version: 11.0.0(@expo/config-plugins@55.0.8)(@types/geojson@7946.0.16)(@types/react@19.2.14)(react-native@0.83.4(@babel/core@7.29.0)(@react-native/metro-config@0.85.1(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.5))(react@19.2.5)
|
||||
'@sentry/cli':
|
||||
specifier: ^3.3.5
|
||||
version: 3.3.5
|
||||
|
|
@ -2099,14 +2099,25 @@ packages:
|
|||
'@lezer/lr@1.4.8':
|
||||
resolution: {integrity: sha512-bPWa0Pgx69ylNlMlPvBPryqeLYQjyJjqPx+Aupm5zydLIF3NE+6MMLT8Yi23Bd9cif9VS00aUebn+6fDIGBcDA==}
|
||||
|
||||
'@maplibre/maplibre-react-native@10.4.2':
|
||||
resolution: {integrity: sha512-5qAfaEe66eMXyILklm2DMHwyaXwXxsZWVop4BqfU7AyTg13LHAcaMmLJNJ3jPkMtiJvjH2m8ywGnobdIg2I0lg==}
|
||||
'@mapbox/jsonlint-lines-primitives@2.0.2':
|
||||
resolution: {integrity: sha512-rY0o9A5ECsTQRVhv7tL/OyDpGAoUB4tTvLiW1DSzQGq4bvTPhNw1VpSNjDJc5GFZ2XuyOtSWSVN05qOtcD71qQ==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
'@mapbox/unitbezier@0.0.1':
|
||||
resolution: {integrity: sha512-nMkuDXFv60aBr9soUG5q+GvZYL+2KZHVvsqFCzqnkGEf46U2fvmytHaEVc1/YZbiLn8X+eR3QzX1+dwDO1lxlw==}
|
||||
|
||||
'@maplibre/maplibre-gl-style-spec@24.8.1':
|
||||
resolution: {integrity: sha512-zxa92qF96ZNojLxeAjnaRpjVCy+swoUNJvDhtpC90k7u5F0TMr4GmvNqMKvYrMoPB8d7gRSXbMG1hBbmgESIsw==}
|
||||
hasBin: true
|
||||
|
||||
'@maplibre/maplibre-react-native@11.0.0':
|
||||
resolution: {integrity: sha512-OCds0j9+1kKkx0B5DikMpYvrzCwYv3ti5j9K0eQadq/M0RjQ40CFUdVpi4N0DtZXZxThmnMI5huqArN6G9GmHw==}
|
||||
peerDependencies:
|
||||
'@expo/config-plugins': '>=7'
|
||||
'@expo/config-plugins': '>=54.0.0'
|
||||
'@types/geojson': ^7946.0.0
|
||||
'@types/react': '>=16.6.1'
|
||||
'@types/react': '>=19.1.0'
|
||||
react: ^19.2.5
|
||||
react-native: '>=0.59.9'
|
||||
react-native: '>=0.80.0'
|
||||
peerDependenciesMeta:
|
||||
'@expo/config-plugins':
|
||||
optional: true
|
||||
|
|
@ -3794,6 +3805,7 @@ packages:
|
|||
'@xmldom/xmldom@0.8.12':
|
||||
resolution: {integrity: sha512-9k/gHF6n/pAi/9tqr3m3aqkuiNosYTurLLUtc7xQ9sxB/wm7WPygCv8GYa6mS0fLJEHhqMC1ATYhz++U/lRHqg==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
deprecated: this version has critical issues, please update to the latest version
|
||||
|
||||
abab@2.0.6:
|
||||
resolution: {integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==}
|
||||
|
|
@ -4329,10 +4341,6 @@ packages:
|
|||
dateformat@4.6.3:
|
||||
resolution: {integrity: sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==}
|
||||
|
||||
debounce@2.2.0:
|
||||
resolution: {integrity: sha512-Xks6RUDLZFdz8LIdR6q0MTH44k7FikOmnh5xkSjMig6ch45afc8sjTjRQf3P6ax8dMgcQrYO/AR2RGWURrruqw==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
debug@2.6.9:
|
||||
resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==}
|
||||
peerDependencies:
|
||||
|
|
@ -5647,6 +5655,9 @@ packages:
|
|||
json-stable-stringify-without-jsonify@1.0.1:
|
||||
resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
|
||||
|
||||
json-stringify-pretty-compact@4.0.0:
|
||||
resolution: {integrity: sha512-3CNZ2DnrpByG9Nqj6Xo8vqbjT4F6N+tb4Gb28ESAZjYZ5yqvmc56J+/kuIwkaAMOyblTQhUW7PxMkUb8Q36N3Q==}
|
||||
|
||||
json5@2.2.3:
|
||||
resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==}
|
||||
engines: {node: '>=6'}
|
||||
|
|
@ -6511,6 +6522,9 @@ packages:
|
|||
quickselect@2.0.0:
|
||||
resolution: {integrity: sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw==}
|
||||
|
||||
quickselect@3.0.0:
|
||||
resolution: {integrity: sha512-XdjUArbK4Bm5fLLvlm5KpTFOiOThgfWWI4axAZDWg4E/0mKdZyI9tNEfds27qCi1ze/vwTR16kvmmGhRra3c2g==}
|
||||
|
||||
range-parser@1.2.1:
|
||||
resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
|
@ -6781,6 +6795,9 @@ packages:
|
|||
rtl-detect@1.1.2:
|
||||
resolution: {integrity: sha512-PGMBq03+TTG/p/cRB7HCLKJ1MgDIi07+QU1faSjiYRfmY5UsAttV9Hs08jDAHVwcOwmVLcSJkpwyfXszVjWfIQ==}
|
||||
|
||||
rw@1.3.3:
|
||||
resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==}
|
||||
|
||||
safe-buffer@5.1.2:
|
||||
resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==}
|
||||
|
||||
|
|
@ -7110,6 +7127,9 @@ packages:
|
|||
tinyqueue@2.0.3:
|
||||
resolution: {integrity: sha512-ppJZNDuKGgxzkHihX8v9v9G5f+18gzaTfrukGrq6ueg0lmH4nqVnA2IPG0AEH3jKEk2GRJCUhDoqpoiw3PHLBA==}
|
||||
|
||||
tinyqueue@3.0.0:
|
||||
resolution: {integrity: sha512-gRa9gwYU3ECmQYv3lslts5hxuIa90veaEcxDYuu3QGOIAEM2mOZkVHp48ANJuu1CURtRdHKUBY5Lm1tHV+sD4g==}
|
||||
|
||||
tinyrainbow@3.1.0:
|
||||
resolution: {integrity: sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
|
|
@ -7728,7 +7748,7 @@ snapshots:
|
|||
'@babel/types': 7.29.0
|
||||
'@jridgewell/gen-mapping': 0.3.13
|
||||
'@jridgewell/trace-mapping': 0.3.31
|
||||
jsesc: 3.0.2
|
||||
jsesc: 3.1.0
|
||||
|
||||
'@babel/helper-annotate-as-pure@7.27.3':
|
||||
dependencies:
|
||||
|
|
@ -9278,13 +9298,27 @@ snapshots:
|
|||
dependencies:
|
||||
'@lezer/common': 1.5.2
|
||||
|
||||
'@maplibre/maplibre-react-native@10.4.2(@expo/config-plugins@55.0.8)(@types/geojson@7946.0.16)(@types/react@19.2.14)(react-native@0.83.4(@babel/core@7.29.0)(@react-native/metro-config@0.85.1(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.5))(react@19.2.5)':
|
||||
'@mapbox/jsonlint-lines-primitives@2.0.2': {}
|
||||
|
||||
'@mapbox/unitbezier@0.0.1': {}
|
||||
|
||||
'@maplibre/maplibre-gl-style-spec@24.8.1':
|
||||
dependencies:
|
||||
'@mapbox/jsonlint-lines-primitives': 2.0.2
|
||||
'@mapbox/unitbezier': 0.0.1
|
||||
json-stringify-pretty-compact: 4.0.0
|
||||
minimist: 1.2.8
|
||||
quickselect: 3.0.0
|
||||
rw: 1.3.3
|
||||
tinyqueue: 3.0.0
|
||||
|
||||
'@maplibre/maplibre-react-native@11.0.0(@expo/config-plugins@55.0.8)(@types/geojson@7946.0.16)(@types/react@19.2.14)(react-native@0.83.4(@babel/core@7.29.0)(@react-native/metro-config@0.85.1(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.5))(react@19.2.5)':
|
||||
dependencies:
|
||||
'@maplibre/maplibre-gl-style-spec': 24.8.1
|
||||
'@turf/distance': 7.3.4
|
||||
'@turf/helpers': 7.3.4
|
||||
'@turf/length': 7.3.4
|
||||
'@turf/nearest-point-on-line': 7.3.4
|
||||
debounce: 2.2.0
|
||||
react: 19.2.5
|
||||
react-native: 0.83.4(@babel/core@7.29.0)(@react-native/metro-config@0.85.1(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.5)
|
||||
optionalDependencies:
|
||||
|
|
@ -11836,8 +11870,6 @@ snapshots:
|
|||
|
||||
dateformat@4.6.3: {}
|
||||
|
||||
debounce@2.2.0: {}
|
||||
|
||||
debug@2.6.9:
|
||||
dependencies:
|
||||
ms: 2.0.0
|
||||
|
|
@ -13441,6 +13473,8 @@ snapshots:
|
|||
|
||||
json-stable-stringify-without-jsonify@1.0.1: {}
|
||||
|
||||
json-stringify-pretty-compact@4.0.0: {}
|
||||
|
||||
json5@2.2.3: {}
|
||||
|
||||
keyv@4.5.4:
|
||||
|
|
@ -14584,6 +14618,8 @@ snapshots:
|
|||
|
||||
quickselect@2.0.0: {}
|
||||
|
||||
quickselect@3.0.0: {}
|
||||
|
||||
range-parser@1.2.1: {}
|
||||
|
||||
raw-body@2.5.3:
|
||||
|
|
@ -14927,6 +14963,8 @@ snapshots:
|
|||
|
||||
rtl-detect@1.1.2: {}
|
||||
|
||||
rw@1.3.3: {}
|
||||
|
||||
safe-buffer@5.1.2: {}
|
||||
|
||||
safe-buffer@5.2.1: {}
|
||||
|
|
@ -15231,6 +15269,8 @@ snapshots:
|
|||
|
||||
tinyqueue@2.0.3: {}
|
||||
|
||||
tinyqueue@3.0.0: {}
|
||||
|
||||
tinyrainbow@3.1.0: {}
|
||||
|
||||
tldts-core@7.0.28: {}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue