mirror of
https://github.com/koala73/worldmonitor.git
synced 2026-04-25 17:14:57 +02:00
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:
@@ -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({
|
||||
|
||||
Reference in New Issue
Block a user