mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-09-30 12:39:42 +02:00
fix(web): cache-bust same-origin module scripts + stylesheets
Static assets are served Cache-Control: max-age=1y, immutable, but the script and link tags in index.html carried no version — so any edit to a frontend module (panels-ui.js, styles.css, …) stayed cached until a manual hard refresh. renderIndexHtml now appends ?v=<mtime> to every same-origin .js/.css ref (generalizing the existing gesture-bundle cache-bust), re-stat'd per render so a changed file is picked up with no server restart. External URLs, already- versioned refs, and refs with no file on disk are left untouched. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -997,6 +997,9 @@ export class WebServer extends EventEmitter {
|
||||
'<title>Codeman</title>',
|
||||
`<title>${escapeHtmlText(this.windowTitle)}</title>`
|
||||
);
|
||||
// Cache-bust same-origin module scripts + stylesheets so a normal reload
|
||||
// always serves the latest (static assets carry a 1-year immutable cache).
|
||||
html = this.cacheBustAssets(html);
|
||||
// Detached single-session ("solo") window: inject the target session id so
|
||||
// the client can enter solo mode even if a (network-first) service worker
|
||||
// later serves a cached shell. The client primarily detects solo mode from
|
||||
@@ -1032,6 +1035,26 @@ export class WebServer extends EventEmitter {
|
||||
}
|
||||
}
|
||||
|
||||
/** Append ?v=<mtime> to every same-origin .js/.css reference in the page so a
|
||||
* normal reload always serves the latest. Codeman's static assets are sent
|
||||
* with `Cache-Control: max-age=1y, immutable` and the script/link tags carry
|
||||
* no version, so without this an edited module (panels-ui.js, styles.css, …)
|
||||
* stays cached until a manual hard refresh. mtime is re-stat'd per render, so
|
||||
* a changed file is picked up with no server restart. External URLs (have a
|
||||
* `:` scheme), already-versioned refs (have a `?`), and refs with no matching
|
||||
* file on disk are left untouched. */
|
||||
private cacheBustAssets(html: string): string {
|
||||
const publicDir = join(__dirname, 'public');
|
||||
return html.replace(/(\s(?:src|href)=")([^"?:]+\.(?:js|css))(")/g, (full, pre, ref, post) => {
|
||||
try {
|
||||
const v = Math.floor(statSync(join(publicDir, ref)).mtimeMs);
|
||||
return `${pre}${ref}?v=${v}${post}`;
|
||||
} catch {
|
||||
return full;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private async setupSessionListeners(session: Session): Promise<void> {
|
||||
// Create run summary tracker for this session
|
||||
const summaryTracker = new RunSummaryTracker(session.id, session.name);
|
||||
|
||||
Reference in New Issue
Block a user