diff --git a/apps/web/src/routes/dashboard.ts b/apps/web/src/routes/dashboard.ts index c92a842..5436cdf 100644 --- a/apps/web/src/routes/dashboard.ts +++ b/apps/web/src/routes/dashboard.ts @@ -4,15 +4,20 @@ import { resolve } from "path"; import { resolveKey } from "./auth"; import sql from "../db"; import { sparklineFromPings, pickBestRegion } from "../utils/sparkline"; -import { createHash } from "crypto"; import { PLAN_LABELS, REGION_COLORS, REGION_LABELS, REGIONS } from "../../../shared/plans"; -const cssFile = Bun.file(resolve(import.meta.dir, "../dashboard/tailwind.css")); -const cssHash = createHash("md5").update(await cssFile.bytes()).digest("hex").slice(0, 8); -const jsFile = Bun.file(resolve(import.meta.dir, "../dashboard/app.js")); -const jsHash = createHash("md5").update(await jsFile.bytes()).digest("hex").slice(0, 8); -const qbFile = Bun.file(resolve(import.meta.dir, "../dashboard/query-builder.js")); -const qbHash = createHash("md5").update(await qbFile.bytes()).digest("hex").slice(0, 8); +async function hashFile(path: string): Promise { + const bytes = await Bun.file(path).bytes(); + return Bun.hash(bytes).toString(36); +} + +const dashDir = resolve(import.meta.dir, "../dashboard"); +const assetHash = { + css: await hashFile(`${dashDir}/tailwind.css`), + appCss: await hashFile(`${dashDir}/app.css`), + js: await hashFile(`${dashDir}/app.js`), + qb: await hashFile(`${dashDir}/query-builder.js`), +}; const eta = new Eta({ views: resolve(import.meta.dir, "../views"), cache: true, defaultExtension: ".ejs" }); @@ -133,7 +138,7 @@ function redirect(to: string) { export function html(template: string, data: Record = {}) { return new Response(eta.render(template, { - ...data, timeAgoSSR, sparklineSSR, pickBestRegion, latencyChartSSR, escapeHtmlSSR, cssHash, jsHash, qbHash, + ...data, timeAgoSSR, sparklineSSR, pickBestRegion, latencyChartSSR, escapeHtmlSSR, h: assetHash, regionColors: REGION_COLORS, regionLabels: REGION_LABELS, regions: REGIONS, planLabels: PLAN_LABELS, }), { headers: { "content-type": "text/html; charset=utf-8" }, @@ -207,8 +212,6 @@ function parseStatusPageForm(b: any): { return { groupsForApi, monitorsForApi }; } -const dashDir = resolve(import.meta.dir, "../dashboard"); - export const dashboard = new Elysia() .get("/", () => html("landing", {})) diff --git a/apps/web/src/tailwind.css b/apps/web/src/tailwind.css index e6046fd..6c58b34 100644 --- a/apps/web/src/tailwind.css +++ b/apps/web/src/tailwind.css @@ -90,3 +90,4 @@ border-color: #1e1e24; } } +/* cache bust */ diff --git a/apps/web/src/views/detail.ejs b/apps/web/src/views/detail.ejs index 847ad7e..0748dc6 100644 --- a/apps/web/src/views/detail.ejs +++ b/apps/web/src/views/detail.ejs @@ -1,4 +1,4 @@ -<%~ include('./partials/head', { title: 'Monitor', scripts: ['/dashboard/query-builder.js?v=' + it.qbHash] }) %> +<%~ include('./partials/head', { title: 'Monitor', scripts: ['/dashboard/query-builder.js?v=' + it.h.qb] }) %> <%~ include('./partials/nav', { nav: 'monitors' }) %> <% diff --git a/apps/web/src/views/new.ejs b/apps/web/src/views/new.ejs index 1d2a96e..c0d3367 100644 --- a/apps/web/src/views/new.ejs +++ b/apps/web/src/views/new.ejs @@ -1,4 +1,4 @@ -<%~ include('./partials/head', { title: 'New Monitor', scripts: ['/dashboard/query-builder.js?v=' + it.qbHash] }) %> +<%~ include('./partials/head', { title: 'New Monitor', scripts: ['/dashboard/query-builder.js?v=' + it.h.qb] }) %> <%~ include('./partials/nav', { nav: 'monitors' }) %>
diff --git a/apps/web/src/views/partials/head.ejs b/apps/web/src/views/partials/head.ejs index ee61808..724cdc8 100644 --- a/apps/web/src/views/partials/head.ejs +++ b/apps/web/src/views/partials/head.ejs @@ -5,9 +5,9 @@ PingQL<%= it.title ? ` - ${it.title}` : '' %> - - - + + + <% if (it.scripts) { it.scripts.forEach(function(s) { %> <% }) } %>