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

1""" 

2Vite integration helper for Flask 

3Handles development and production asset loading 

4""" 

5 

6import json 

7from pathlib import Path 

8from markupsafe import Markup 

9 

10 

11class ViteHelper: 

12 """Helper class for Vite integration with Flask""" 

13 

14 def __init__(self, app=None): 

15 self.app = app 

16 self.manifest = None 

17 self.is_dev = False 

18 

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) 

21 

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) 

26 

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() 

30 

31 # Register template functions 

32 app.jinja_env.globals["vite_asset"] = self.vite_asset 

33 app.jinja_env.globals["vite_hmr"] = self.vite_hmr 

34 

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" 

39 

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 = {} 

46 

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 "" 

54 

55 def vite_asset(self, entry_point="js/app.js"): 

56 """ 

57 Return appropriate script tags for the entry point 

58 

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 ) 

67 

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() 

72 

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']}" 

77 

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' 

83 

84 # Include the main JS file 

85 js_tag = f'<script type="module" src="{file_path}"></script>' 

86 

87 return Markup(css_tags + js_tag) 

88 

89 return self._fallback_assets() 

90 

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 """) 

98 

99 

100# Create global instance 

101vite = ViteHelper()