diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a704cac..b3fd1639 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Optimized Nostr login speed. (PR #2153 by PR0M3TH3AN) - Updated `nostr-tools`, `floating-ui`, and `crypto-helpers` dependencies. (PR #2153 by PR0M3TH3AN) - Major repository update and synchronization (Commit `b429b1c` by thePR0M3TH3AN) +- Removed runtime `ASSET_VERSION` query-string cache busting for static assets. Deployment freshness is now driven by build-time hashed filenames and `asset-manifest.json` rewrites. ### Fixed diff --git a/README.md b/README.md index fa37d528..a1a2e489 100644 --- a/README.md +++ b/README.md @@ -356,6 +356,11 @@ This split is required for safe fast rollouts: HTML needs rapid update pickup, while fingerprinted static assets should remain aggressively cacheable for performance and cost control. +> Migration note: runtime `ASSET_VERSION` query-parameter mutation has been +> removed. Static asset freshness now comes from build-time hashed filenames +> recorded in `dist/asset-manifest.json` and rewritten into `dist/index.html` +> / `dist/embed.html` during `npm run build`. + #### Service worker rollback playbook diff --git a/config/asset-version.js b/config/asset-version.js deleted file mode 100644 index 6d3f28be..00000000 --- a/config/asset-version.js +++ /dev/null @@ -1 +0,0 @@ -export const ASSET_VERSION = "2024.11.09-2"; diff --git a/docs/deployment-notes.md b/docs/deployment-notes.md index cd40b221..affeda90 100644 --- a/docs/deployment-notes.md +++ b/docs/deployment-notes.md @@ -5,3 +5,9 @@ - **Status:** The design system styling is always active. The former `FEATURE_DESIGN_SYSTEM` runtime flag has been removed, so there is no rollback toggle during deployment. - **Template contract:** Every layout, view, and partial must keep `data-ds` on its root element. The entrypoint stamps `data-ds="new"` during bootstrap so controllers inherit the correct primitives. - **Controllers:** UI controllers still receive a `designSystem` context, but `context.isNew()` now always returns `true`. Use the context for consistency, but do not branch on legacy styling paths. + +## Asset freshness and cache invalidation + +- Static CSS/JS asset freshness is now driven by build-time manifest rewriting (`dist/asset-manifest.json`) instead of runtime `ASSET_VERSION` query-string mutation. +- Keep source HTML entry points (`index.html`, `embed.html`) pointing at logical asset paths (for example, `js/index.js` and `css/tailwind.generated.css`). The build pipeline rewrites those references to content-hashed filenames in `dist/`. +- App routing query parameters (such as `?v=` for video pointers) are unchanged and remain part of runtime URL behavior. diff --git a/js/index.js b/js/index.js index 1642eac3..d23dca98 100644 --- a/js/index.js +++ b/js/index.js @@ -1,7 +1,6 @@ // js/index.js import { validateInstanceConfig } from "../config/validate-config.js"; -import { ASSET_VERSION } from "../config/asset-version.js"; import "./bufferPolyfill.js"; import { getApplication, @@ -548,17 +547,8 @@ document.addEventListener("animationend", handleFadeInAnimationComplete, true); document.addEventListener("animationcancel", handleFadeInAnimationComplete, true); // 1) Load modals (login, application, etc.) -const withAssetVersion = (url) => { - if (typeof url !== "string" || url.length === 0) { - return url; - } - - const separator = url.includes("?") ? "&" : "?"; - return `${url}${separator}v=${encodeURIComponent(ASSET_VERSION)}`; -}; - const fetchPartial = async (url) => { - const response = await fetch(withAssetVersion(url), { cache: "no-store" }); + const response = await fetch(url, { cache: "no-store" }); if (!response.ok) { throw new Error("Failed to load " + url); } diff --git a/js/viewManager.js b/js/viewManager.js index fe23b0d5..b3852bd7 100644 --- a/js/viewManager.js +++ b/js/viewManager.js @@ -5,7 +5,6 @@ import { initKidsView } from "./kidsView.js"; import { initExploreView } from "./exploreView.js"; import { subscriptions } from "./subscriptions.js"; import { getApplication } from "./applicationContext.js"; -import { ASSET_VERSION } from "../config/asset-version.js"; import { applyDesignSystemAttributes } from "./designSystem.js"; import { devLogger, userLogger } from "./utils/logger.js"; import { attachFeedInfoPopover } from "./ui/components/FeedInfoPopover.js"; @@ -14,15 +13,6 @@ import { FEED_TYPES } from "./constants.js"; const TRACKING_SCRIPT_PATTERN = /(?:^|\/)tracking\.js(?:$|\?)/; -const withAssetVersion = (url) => { - if (typeof url !== "string" || url.length === 0) { - return url; - } - - const separator = url.includes("?") ? "&" : "?"; - return `${url}${separator}v=${encodeURIComponent(ASSET_VERSION)}`; -}; - /** * Load a partial view by URL into the #viewContainer. */ @@ -33,7 +23,7 @@ export async function loadView(viewUrl) { app.prepareForViewLoad(); } - const res = await fetch(withAssetVersion(viewUrl), { cache: "no-store" }); + const res = await fetch(viewUrl, { cache: "no-store" }); if (!res.ok) { throw new Error(`Failed to load view: ${res.status}`); }