fixing deployment errors

This commit is contained in:
Julio Cesar
2025-08-20 16:14:36 +02:00
parent 9773484f12
commit cede717994
5 changed files with 58 additions and 26 deletions

View File

@@ -34,6 +34,8 @@ const emit = defineEmits<{
const mapContainer = useTemplateRef("mapContainer") const mapContainer = useTemplateRef("mapContainer")
let map: Map | null = null let map: Map | null = null
// Hold geojson updates that arrive before the source is available.
let pendingGeojson: GeoJSON.FeatureCollection | null = null
// A simple function to generate a large dummy GeoJSON dataset in Saudi Arabia for demonstration. // A simple function to generate a large dummy GeoJSON dataset in Saudi Arabia for demonstration.
// In a real application, this data would be passed in via props, likely streamed // In a real application, this data would be passed in via props, likely streamed
@@ -77,14 +79,30 @@ const addLayersAndSources = () => {
} }
// Add a new source from the GeoJSON data with clustering enabled. // Add a new source from the GeoJSON data with clustering enabled.
// Use latest available data: prefer the incoming prop, then any pending update,
// then the initial mapData fallback.
const initialData = props.geojson || pendingGeojson || mapData
map.addSource("meters", { map.addSource("meters", {
type: "geojson", type: "geojson",
data: mapData, data: initialData,
cluster: true, cluster: true,
clusterMaxZoom: 14, // Max zoom to cluster points on clusterMaxZoom: 14, // Max zoom to cluster points on
clusterRadius: 50, // Radius of each cluster in pixels clusterRadius: 50, // Radius of each cluster in pixels
}) })
// If updates arrived before the source existed, apply them now.
if (pendingGeojson) {
const src = map.getSource("meters") as GeoJSONSource
try {
src.setData(pendingGeojson)
pendingGeojson = null
} catch (e) {
// ignore if source isn't ready for some reason; watcher will retry
console.warn("Failed to apply pending geojson to source:", e)
}
}
// Add the 'clusters' layer for the cluster circles. // Add the 'clusters' layer for the cluster circles.
map.addLayer({ map.addLayer({
id: "clusters", id: "clusters",
@@ -224,19 +242,19 @@ onMounted(() => {
if (!map?.hasImage("meter-icon")) { if (!map?.hasImage("meter-icon")) {
map?.addImage("meter-icon", image) map?.addImage("meter-icon", image)
} }
// Wait for the map to load before adding the source and layers.
map?.on("load", () => {
addLayersAndSources()
// Emit center updates to support v-model:center when the map finishes moving.
map?.on("moveend", () => {
if (!map) return
const centerArray = map.getCenter().toArray() as LngLatLike
emit("update:center", centerArray)
})
})
} }
// Wait for the map to load before adding the source and layers.
map.on("load", () => {
addLayersAndSources()
// Emit center updates to support v-model:center when the map finishes moving.
map?.on("moveend", () => {
if (!map) return
const centerArray = map.getCenter().toArray() as LngLatLike
emit("update:center", centerArray)
})
})
}) })
onUnmounted(() => { onUnmounted(() => {
@@ -250,11 +268,26 @@ onUnmounted(() => {
watch( watch(
() => props.geojson, () => props.geojson,
(newGeojson) => { (newGeojson) => {
if (map && map.isSourceLoaded("meters") && newGeojson) { if (!newGeojson) return
// If the map isn't ready or the source doesn't exist yet, store it as pending
// so it can be applied once the source is added.
if (!map || !map.getSource("meters")) {
pendingGeojson = newGeojson
return
}
// Safe update when the source exists.
try {
const source = map.getSource("meters") as GeoJSONSource const source = map.getSource("meters") as GeoJSONSource
if (source) { source.setData(newGeojson)
source.setData(newGeojson) } catch (e) {
} // Fallback to pending if setData fails for timing reasons.
console.warn(
"Failed to set data on 'meters' source, queuing pending update:",
e
)
pendingGeojson = newGeojson
} }
}, },
{ deep: true } { deep: true }

View File

@@ -1,8 +1,7 @@
import { ref, type Ref } from "vue" import { ref, type Ref } from "vue"
import { type MetersCollection, type MeterFeature } from "shared-types/meters" import { type MetersCollection, type MeterFeature } from "shared-types/meters"
const API_BASE_URL = const API_BASE_URL = import.meta.env.VITE_API_URL || "http://localhost:3001/api"
import.meta.env.VITE_API_BASE_URL || "http://localhost:3001/api"
/** /**
* Composable for managing meter data from the backend API * Composable for managing meter data from the backend API

View File

@@ -28,10 +28,10 @@ const zoom = ref(8) // Default zoom level
// Use the meters composable // Use the meters composable
const { const {
metersData, metersData,
isLoading: metersLoading, // isLoading: metersLoading,
error: metersError, // error: metersError,
fetchMeters, fetchMeters,
currentMeter, // currentMeter,
} = useMeters() } = useMeters()
function getLocation() { function getLocation() {

View File

@@ -5,11 +5,10 @@
"description": "Express server for serving saudi_meters.json", "description": "Express server for serving saudi_meters.json",
"main": "app.ts", "main": "app.ts",
"scripts": { "scripts": {
"start": "node dist/app.js", "start": "node dist/test-backend/app.js",
"dev": "tsx app.ts", "dev": "tsx app.ts",
"build": "tsc", "build": "tsc",
"generate": "node generate_meters.js", "generate": "node generate_meters.js"
"validate": "node validate_borders.js"
}, },
"dependencies": { "dependencies": {
"cors": "2.8.5", "cors": "2.8.5",

View File

@@ -25,7 +25,8 @@
}, },
"include": [ "include": [
"*.ts", "*.ts",
"../types/**/*.ts" "../types/**/*.ts",
"saudi_meters.json"
], ],
"exclude": [ "exclude": [
"node_modules", "node_modules",