import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; import { resolve } from 'path'; import { VitePWA } from 'vite-plugin-pwa'; export default defineConfig({ plugins: [ react(), VitePWA({ registerType: 'autoUpdate', includeAssets: ['favicon.ico', 'apple-touch-icon.png'], manifest: { name: 'Grok Drive', short_name: 'GrokDrive', description: 'AI-assisted Tesla road trip planner', theme_color: '#0a0a0c', background_color: '#0a0a0c', display: 'standalone', orientation: 'any', start_url: '/', scope: '/', icons: [ { src: '/favicon.svg', sizes: 'any', type: 'image/svg+xml' }, ], }, workbox: { globPatterns: ['**/*.{js,css,html,svg,ico,woff,woff2}'], globIgnores: ['**/*.map'], navigateFallback: '/index.html', navigateFallbackDenylist: [/^\/api\//, /^\/\.well-known\//], maximumFileSizeToCacheInBytes: 3 * 1024 * 1024, runtimeCaching: [ // Map tiles — cache-first for offline viewing of the planned route. { urlPattern: ({ url }: { url: URL }) => url.hostname.endsWith('tile.openstreetmap.org') || url.hostname.endsWith('basemaps.cartocdn.com') || /tile/i.test(url.hostname), handler: 'CacheFirst', options: { cacheName: 'map-tiles', expiration: { maxEntries: 800, maxAgeSeconds: 60 * 60 * 24 * 30 }, cacheableResponse: { statuses: [0, 200] }, }, }, // Geocoding + routing APIs — network-first, with cached fallback. { urlPattern: ({ url }: { url: URL }) => url.hostname.endsWith('nominatim.openstreetmap.org') || url.hostname.endsWith('router.project-osrm.org'), handler: 'NetworkFirst', options: { cacheName: 'geo-api', networkTimeoutSeconds: 4, expiration: { maxEntries: 200, maxAgeSeconds: 60 * 60 * 24 * 7 }, cacheableResponse: { statuses: [0, 200] }, }, }, // Our own API — network-first, cached short-term so the last good // response stays visible when LTE drops. { urlPattern: ({ url }: { url: URL }) => url.pathname.startsWith('/api/'), handler: 'NetworkFirst', options: { cacheName: 'app-api', networkTimeoutSeconds: 3, expiration: { maxEntries: 50, maxAgeSeconds: 60 * 60 }, cacheableResponse: { statuses: [0, 200] }, }, }, ], }, devOptions: { enabled: false }, }), ], resolve: { alias: { '@': resolve(__dirname, './src'), }, }, server: { port: 5173, host: true, proxy: { '/api': { target: 'http://localhost:3000', changeOrigin: true, }, '/auth': { target: 'http://localhost:3000', changeOrigin: true, }, }, }, build: { outDir: 'dist', sourcemap: true, }, });