- Introduce cache busting (to circumvent aggressive caching on iOS - but ideal in other contexts as well)
- Change the build process to allow cache busting - Optimisations to the build process - Several improvements of UI geared towards mobile experience -
This commit is contained in:
45
common/utils/asset_manifest.py
Normal file
45
common/utils/asset_manifest.py
Normal file
@@ -0,0 +1,45 @@
|
||||
import json
|
||||
import os
|
||||
from functools import lru_cache
|
||||
from typing import Dict
|
||||
|
||||
# Default manifest path inside app images; override with env
|
||||
DEFAULT_MANIFEST_PATH = os.environ.get(
|
||||
'EVEAI_STATIC_MANIFEST_PATH',
|
||||
'/app/config/static-manifest/manifest.json'
|
||||
)
|
||||
|
||||
|
||||
@lru_cache(maxsize=1)
|
||||
def _load_manifest(manifest_path: str = DEFAULT_MANIFEST_PATH) -> Dict[str, str]:
|
||||
try:
|
||||
with open(manifest_path, 'r', encoding='utf-8') as f:
|
||||
return json.load(f)
|
||||
except Exception:
|
||||
return {}
|
||||
|
||||
|
||||
def resolve_asset(logical_path: str, manifest_path: str = DEFAULT_MANIFEST_PATH) -> str:
|
||||
"""
|
||||
Map a logical asset path (e.g. 'dist/chat-client.js') to the hashed path
|
||||
found in the Parcel manifest. If not found or manifest missing, return the
|
||||
original logical path for graceful fallback.
|
||||
"""
|
||||
if not logical_path:
|
||||
return logical_path
|
||||
|
||||
manifest = _load_manifest(manifest_path)
|
||||
|
||||
# Try several key variants as Parcel manifests may use different keys
|
||||
candidates = [
|
||||
logical_path,
|
||||
logical_path.lstrip('/'),
|
||||
logical_path.replace('static/', ''),
|
||||
logical_path.replace('dist/', ''),
|
||||
]
|
||||
|
||||
for key in candidates:
|
||||
if key in manifest:
|
||||
return manifest[key]
|
||||
|
||||
return logical_path
|
||||
@@ -107,6 +107,33 @@ def get_pagination_html(pagination, endpoint, **kwargs):
|
||||
return Markup(''.join(html))
|
||||
|
||||
|
||||
def asset_url(logical_path: str):
|
||||
"""
|
||||
Resolve an asset logical path to a hashed URL using Parcel manifest when available.
|
||||
Fallback to the original logical path under /static/ if manifest is missing.
|
||||
Examples:
|
||||
- asset_url('dist/chat-client.js') -> '/static/dist/chat-client.abc123.js'
|
||||
- asset_url('dist/chat-client.css') -> '/static/dist/chat-client.def456.css'
|
||||
"""
|
||||
if not logical_path:
|
||||
return logical_path
|
||||
try:
|
||||
from common.utils.asset_manifest import resolve_asset
|
||||
resolved = resolve_asset(logical_path)
|
||||
if not resolved:
|
||||
return f"/static/{logical_path.lstrip('/')}"
|
||||
# If resolved is already an absolute URL starting with /static or http(s), return as is
|
||||
if resolved.startswith('/static/') or resolved.startswith('http://') or resolved.startswith('https://'):
|
||||
return resolved
|
||||
# If it starts with 'dist/', prefix /static/
|
||||
if resolved.startswith('dist/'):
|
||||
return '/static/' + resolved
|
||||
# Otherwise, best effort: ensure it lives under /static/
|
||||
return '/static/' + resolved.lstrip('/')
|
||||
except Exception:
|
||||
return f"/static/{logical_path.lstrip('/')}"
|
||||
|
||||
|
||||
def register_filters(app):
|
||||
"""
|
||||
Registers custom filters with the Flask app.
|
||||
@@ -123,4 +150,5 @@ def register_filters(app):
|
||||
app.jinja_env.globals['prefixed_url_for'] = prefixed_url_for
|
||||
app.jinja_env.globals['get_pagination_html'] = get_pagination_html
|
||||
app.jinja_env.globals['get_base_background_color'] = get_base_background_color
|
||||
app.jinja_env.globals['asset_url'] = asset_url
|
||||
|
||||
|
||||
Reference in New Issue
Block a user