This commit is contained in:
Andras Schmelczer 2026-05-14 20:42:48 +01:00
parent 273d7a83ee
commit 084117cea8
48 changed files with 2283 additions and 890 deletions

View file

@ -0,0 +1,22 @@
import assert from 'node:assert/strict';
import test from 'node:test';
import { NetworkCache } from './network-cache.js';
test('NetworkCache skips mutable webpack dev bundles', () => {
const cache = new NetworkCache();
assert.equal(cache.shouldCache('http://frontend:3001/bundle.js'), false);
assert.equal(
cache.shouldCache('http://frontend:3001/src_components_map_MapPage_tsx.bundle.js'),
false,
);
});
test('NetworkCache keeps fingerprinted production assets cacheable', () => {
const cache = new NetworkCache();
assert.equal(cache.shouldCache('https://example.com/main.abcdef12.js'), true);
assert.equal(cache.shouldCache('https://example.com/main.abcdef12.css'), true);
assert.equal(cache.shouldCache('https://example.com/assets/sprites/light.json'), true);
});

View file

@ -5,6 +5,7 @@ interface CacheEntry {
}
const MAX_ENTRIES = 2000;
const FINGERPRINTED_JS_OR_CSS_RE = /(?:^|\/)[^/?]+\.[a-f0-9]{8,}\.(?:js|css)$/i;
/**
* In-memory cache for network responses (tiles, JS/CSS bundles, font glyphs).
@ -19,12 +20,17 @@ export class NetworkCache {
misses = 0;
shouldCache(url: string): boolean {
const pathname = new URL(url).pathname;
// Vector map tiles (protobuf)
if (url.includes('/api/tiles/')) return true;
if (pathname.includes('/api/tiles/')) return true;
// Webpack dev assets are mutable at stable URLs (`bundle.js`, chunk
// `.bundle.js` files), so only cache fingerprinted production JS/CSS.
if (/\.(js|css)$/i.test(pathname)) return FINGERPRINTED_JS_OR_CSS_RE.test(pathname);
// Static assets by extension
if (/\.(js|css|woff2?|ttf|png|jpe?g|svg|ico|pbf|json)(\?|$)/i.test(url)) return true;
if (/\.(woff2?|ttf|png|jpe?g|svg|ico|pbf|json)$/i.test(pathname)) return true;
// Font glyphs and emoji sprites under /assets/
if (url.includes('/assets/')) return true;
if (pathname.includes('/assets/')) return true;
return false;
}