Coverage for src / local_deep_research / web / utils / vite_helper.py: 58%
46 statements
« prev ^ index » next coverage.py v7.12.0, created at 2026-01-11 00:51 +0000
« prev ^ index » next coverage.py v7.12.0, created at 2026-01-11 00:51 +0000
1"""
2Vite integration helper for Flask
3Handles development and production asset loading
4"""
6import json
7from pathlib import Path
8from markupsafe import Markup
11class ViteHelper:
12 """Helper class for Vite integration with Flask"""
14 def __init__(self, app=None):
15 self.app = app
16 self.manifest = None
17 self.is_dev = False
19 if app: 19 ↛ 20line 19 didn't jump to line 20 because the condition on line 19 was never true
20 self.init_app(app)
22 def init_app(self, app):
23 """Initialize the helper with Flask app"""
24 self.app = app
25 self.is_dev = app.debug or app.config.get("VITE_DEV_MODE", False)
27 if not self.is_dev: 27 ↛ 32line 27 didn't jump to line 32 because the condition on line 27 was always true
28 # Load manifest in production
29 self._load_manifest()
31 # Register template functions
32 app.jinja_env.globals["vite_asset"] = self.vite_asset
33 app.jinja_env.globals["vite_hmr"] = self.vite_hmr
35 def _load_manifest(self):
36 """Load Vite manifest file"""
37 static_dir = self.app.config.get("STATIC_DIR", "static")
38 manifest_path = Path(static_dir) / "dist" / ".vite" / "manifest.json"
40 if manifest_path.exists(): 40 ↛ 41line 40 didn't jump to line 41 because the condition on line 40 was never true
41 with open(manifest_path, "r") as f:
42 self.manifest = json.load(f)
43 else:
44 # Fallback if manifest doesn't exist yet
45 self.manifest = {}
47 def vite_hmr(self):
48 """Return HMR client script for development"""
49 if self.is_dev: 49 ↛ 50line 49 didn't jump to line 50 because the condition on line 49 was never true
50 return Markup(
51 '<script type="module" src="http://localhost:5173/@vite/client"></script>'
52 )
53 return ""
55 def vite_asset(self, entry_point="js/app.js"):
56 """
57 Return appropriate script tags for the entry point
59 In development: Points to Vite dev server
60 In production: Uses manifest to get hashed filenames
61 """
62 if self.is_dev: 62 ↛ 64line 62 didn't jump to line 64 because the condition on line 62 was never true
63 # Development mode - use Vite dev server
64 return Markup(
65 f'<script type="module" src="http://localhost:5173/{entry_point}"></script>'
66 )
68 # Production mode - use manifest
69 if not self.manifest: 69 ↛ 74line 69 didn't jump to line 74 because the condition on line 69 was always true
70 # Fallback to CDN references if build hasn't run yet
71 return self._fallback_assets()
73 # Get the built file from manifest
74 if entry_point in self.manifest:
75 file_info = self.manifest[entry_point]
76 file_path = f"/static/dist/{file_info['file']}"
78 # Include CSS if present
79 css_tags = ""
80 if "css" in file_info:
81 for css_file in file_info["css"]:
82 css_tags += f'<link rel="stylesheet" href="/static/dist/{css_file}">\n'
84 # Include the main JS file
85 js_tag = f'<script type="module" src="{file_path}"></script>'
87 return Markup(css_tags + js_tag)
89 return self._fallback_assets()
91 def _fallback_assets(self):
92 """Fallback to existing script tags if build hasn't run"""
93 # This will be replaced once npm build is run
94 return Markup("""
95<!-- Vite build not found - run 'npm run build' to generate production assets -->
96<!-- Using existing static files as fallback -->
97 """)
100# Create global instance
101vite = ViteHelper()