Reduce egress costs, add PWA support, fix Polymarket and Railway relay

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
This commit is contained in:
Elie Habib
2026-02-14 19:52:57 +04:00
parent 427d9c1f3f
commit c353cf2070
91 changed files with 7204 additions and 1757 deletions

View File

@@ -99,7 +99,7 @@ async function setupResourceDirWithUpApi(files) {
};
}
test('falls back to cloud when local handler returns a 500', async () => {
test('returns local error directly when cloudFallback is off (default)', async () => {
const remote = await setupRemoteServer();
const localApi = await setupApiDir({
'fred-data.js': `
@@ -120,6 +120,41 @@ test('falls back to cloud when local handler returns a 500', async () => {
});
const { port } = await app.start();
try {
const response = await fetch(`http://127.0.0.1:${port}/api/fred-data`);
assert.equal(response.status, 500);
const body = await response.json();
assert.equal(body.source, 'local-error');
assert.equal(remote.hits.length, 0);
} finally {
await app.close();
await localApi.cleanup();
await remote.close();
}
});
test('falls back to cloud when cloudFallback is enabled and local handler returns 500', async () => {
const remote = await setupRemoteServer();
const localApi = await setupApiDir({
'fred-data.js': `
export default async function handler() {
return new Response(JSON.stringify({ source: 'local-error' }), {
status: 500,
headers: { 'content-type': 'application/json' }
});
}
`,
});
const app = await createLocalApiServer({
port: 0,
apiDir: localApi.apiDir,
remoteBase: remote.remoteBase,
cloudFallback: 'true',
logger: { log() {}, warn() {}, error() {} },
});
const { port } = await app.start();
try {
const response = await fetch(`http://127.0.0.1:${port}/api/fred-data`);
assert.equal(response.status, 200);
@@ -167,7 +202,7 @@ test('uses local handler response when local handler succeeds', async () => {
}
});
test('falls back to cloud when local route does not exist', async () => {
test('returns 404 when local route does not exist and cloudFallback is off', async () => {
const remote = await setupRemoteServer();
const localApi = await setupApiDir({});
@@ -181,10 +216,10 @@ test('falls back to cloud when local route does not exist', async () => {
try {
const response = await fetch(`http://127.0.0.1:${port}/api/not-found`);
assert.equal(response.status, 200);
assert.equal(response.status, 404);
const body = await response.json();
assert.equal(body.source, 'remote');
assert.equal(remote.hits.includes('/api/not-found'), true);
assert.equal(body.error, 'No local handler for this endpoint');
assert.equal(remote.hits.length, 0);
} finally {
await app.close();
await localApi.cleanup();
@@ -233,7 +268,7 @@ test('strips browser origin headers before invoking local handlers', async () =>
}
});
test('strips browser origin headers when proxying to cloud fallback', async () => {
test('strips browser origin headers when proxying to cloud fallback (cloudFallback enabled)', async () => {
const remote = await setupRemoteServer();
const localApi = await setupApiDir({});
@@ -241,6 +276,7 @@ test('strips browser origin headers when proxying to cloud fallback', async () =
port: 0,
apiDir: localApi.apiDir,
remoteBase: remote.remoteBase,
cloudFallback: 'true',
logger: { log() {}, warn() {}, error() {} },
});
const { port } = await app.start();
@@ -261,6 +297,32 @@ test('strips browser origin headers when proxying to cloud fallback', async () =
}
});
test('responds to OPTIONS preflight with CORS headers', async () => {
const localApi = await setupApiDir({
'data.js': `
export default async function handler() {
return new Response('{}', { status: 200, headers: { 'content-type': 'application/json' } });
}
`,
});
const app = await createLocalApiServer({
port: 0,
apiDir: localApi.apiDir,
logger: { log() {}, warn() {}, error() {} },
});
const { port } = await app.start();
try {
const response = await fetch(`http://127.0.0.1:${port}/api/data`, { method: 'OPTIONS' });
assert.equal(response.status, 204);
assert.equal(response.headers.get('access-control-allow-methods'), 'GET, POST, PUT, DELETE, OPTIONS');
} finally {
await app.close();
await localApi.cleanup();
}
});
test('resolves packaged tauri resource layout under _up_/api', async () => {
const remote = await setupRemoteServer();
const localResource = await setupResourceDirWithUpApi({