mirror of
https://github.com/koala73/worldmonitor.git
synced 2026-05-14 19:16:20 +02:00
Egress optimization: - Add s-maxage + stale-while-revalidate to all API endpoints for Vercel CDN caching - Add vercel.json with immutable caching for hashed assets - Add gzip compression to sidecar responses >1KB - Add gzip to Railway RSS responses (4 paths previously uncompressed) - Increase polling intervals: markets/crypto 60s→120s, ETF/macro/stablecoins 60s→180s - Remove hardcoded Railway URL from theater-posture.js (now env-var only) PWA / Service Worker: - Add vite-plugin-pwa with autoUpdate strategy - Cache map tiles (CacheFirst), fonts (StaleWhileRevalidate), static assets - NetworkOnly for all /api/* routes (real-time data must be fresh) - Manual SW registration (web only, skip Tauri) - Add offline fallback page - Replace manual manifest with plugin-generated manifest Polymarket fix: - Route dev proxy through production Vercel (bypasses JA3 blocking) - Add 4th fallback tier: production URL as absolute fallback Desktop/Sidecar: - Dual-backend cache (_upstash-cache.js): Redis cloud + in-memory+file desktop - Settings window OK/Cancel redesign - Runtime config and secret injection improvements
68 lines
2.0 KiB
JavaScript
68 lines
2.0 KiB
JavaScript
// OpenSky Network API proxy - v3
|
|
// Note: OpenSky seems to block some cloud provider IPs
|
|
export const config = { runtime: 'edge' };
|
|
|
|
export default async function handler(req) {
|
|
const url = new URL(req.url);
|
|
|
|
// Build OpenSky API URL with bounding box params
|
|
const params = new URLSearchParams();
|
|
['lamin', 'lomin', 'lamax', 'lomax'].forEach(key => {
|
|
const val = url.searchParams.get(key);
|
|
if (val) params.set(key, val);
|
|
});
|
|
|
|
const openskyUrl = `https://opensky-network.org/api/states/all${params.toString() ? '?' + params.toString() : ''}`;
|
|
|
|
try {
|
|
// Try fetching with different headers to avoid blocks
|
|
const response = await fetch(openskyUrl, {
|
|
headers: {
|
|
'Accept': 'application/json',
|
|
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
|
|
'Accept-Language': 'en-US,en;q=0.9',
|
|
'Accept-Encoding': 'gzip, deflate, br',
|
|
'Connection': 'keep-alive',
|
|
},
|
|
});
|
|
|
|
if (response.status === 429) {
|
|
return Response.json({ error: 'Rate limited', time: Date.now(), states: null }, {
|
|
status: 429,
|
|
headers: { 'Access-Control-Allow-Origin': '*' },
|
|
});
|
|
}
|
|
|
|
// Check if response is OK
|
|
if (!response.ok) {
|
|
const text = await response.text();
|
|
return Response.json({
|
|
error: `OpenSky HTTP ${response.status}: ${text.substring(0, 200)}`,
|
|
time: Date.now(),
|
|
states: null
|
|
}, {
|
|
status: response.status,
|
|
headers: { 'Access-Control-Allow-Origin': '*' },
|
|
});
|
|
}
|
|
|
|
const data = await response.json();
|
|
return Response.json(data, {
|
|
status: response.status,
|
|
headers: {
|
|
'Access-Control-Allow-Origin': '*',
|
|
'Cache-Control': 'public, max-age=30, s-maxage=30, stale-while-revalidate=15',
|
|
},
|
|
});
|
|
} catch (error) {
|
|
return Response.json({
|
|
error: `Fetch failed: ${error.name} - ${error.message}`,
|
|
time: Date.now(),
|
|
states: null
|
|
}, {
|
|
status: 500,
|
|
headers: { 'Access-Control-Allow-Origin': '*' },
|
|
});
|
|
}
|
|
}
|