|
@@ -1,3 +1,6 @@
|
|
|
|
+from __future__ import annotations
|
|
|
|
+
|
|
|
|
+from dataclasses import dataclass
|
|
from pathlib import Path
|
|
from pathlib import Path
|
|
from typing import Dict, List, Tuple
|
|
from typing import Dict, List, Tuple
|
|
|
|
|
|
@@ -5,16 +8,27 @@ import vbuild
|
|
from starlette.responses import FileResponse
|
|
from starlette.responses import FileResponse
|
|
from starlette.routing import Route
|
|
from starlette.routing import Route
|
|
|
|
|
|
-components: Dict[str, Path] = {}
|
|
|
|
|
|
+components: Dict[str, Component] = {}
|
|
|
|
+
|
|
|
|
|
|
|
|
+@dataclass
|
|
|
|
+class Component:
|
|
|
|
+ name: str
|
|
|
|
+ path: Path
|
|
|
|
+ dependencies: List[str]
|
|
|
|
|
|
-def register_component(name: str, py_filepath: str, component_filepath: str) -> None:
|
|
|
|
|
|
+
|
|
|
|
+def register_component(name: str, py_filepath: str, component_filepath: str, dependencies: List[str] = []) -> None:
|
|
assert name not in components
|
|
assert name not in components
|
|
- components[name] = Path(py_filepath).parent / component_filepath
|
|
|
|
|
|
+ components[name] = Component(
|
|
|
|
+ name=name,
|
|
|
|
+ path=Path(py_filepath).parent / component_filepath,
|
|
|
|
+ dependencies=[Path(py_filepath).parent / dependency for dependency in dependencies],
|
|
|
|
+ )
|
|
|
|
|
|
|
|
|
|
def generate_vue_content() -> Tuple[str]:
|
|
def generate_vue_content() -> Tuple[str]:
|
|
- builds = [vbuild.VBuild(p.name, p.read_text()) for p in components.values() if p.suffix == '.vue']
|
|
|
|
|
|
+ builds = [vbuild.VBuild(c.name, c.path.read_text()) for c in components.values() if c.path.suffix == '.vue']
|
|
return (
|
|
return (
|
|
'\n'.join(v.html for v in builds),
|
|
'\n'.join(v.html for v in builds),
|
|
'<style>' + '\n'.join(v.style for v in builds) + '</style>',
|
|
'<style>' + '\n'.join(v.style for v in builds) + '</style>',
|
|
@@ -22,19 +36,33 @@ def generate_vue_content() -> Tuple[str]:
|
|
)
|
|
)
|
|
|
|
|
|
|
|
|
|
-def get_js_components() -> Dict[str, str]:
|
|
|
|
- return {name: filepath for name, filepath in components.items() if filepath.suffix == '.js'}
|
|
|
|
|
|
+def get_js_components() -> List[Component]:
|
|
|
|
+ return [c for c in components.values() if c.path.suffix == '.js']
|
|
|
|
|
|
|
|
|
|
def generate_js_routes() -> List[Route]:
|
|
def generate_js_routes() -> List[Route]:
|
|
- return [
|
|
|
|
- Route(f'/_vue/{name}', lambda _, filepath=filepath: FileResponse(filepath, media_type='text/javascript'))
|
|
|
|
- for name, filepath in get_js_components().items()
|
|
|
|
- ]
|
|
|
|
|
|
+ routes: List[Route] = []
|
|
|
|
+ for component in components.values():
|
|
|
|
+ for dependency in component.dependencies:
|
|
|
|
+ print(dependency, flush=True)
|
|
|
|
+ routes.append(Route(f'/_vue/{component.name}/{dependency}',
|
|
|
|
+ lambda _, path=dependency: FileResponse(path, media_type='text/javascript')))
|
|
|
|
+ for component in get_js_components():
|
|
|
|
+ routes.append(Route(f'/_vue/{component.name}',
|
|
|
|
+ lambda _, path=component.path: FileResponse(path, media_type='text/javascript')))
|
|
|
|
+ return routes
|
|
|
|
|
|
|
|
|
|
def generate_js_imports() -> str:
|
|
def generate_js_imports() -> str:
|
|
- return '\n'.join(f'''
|
|
|
|
- import {{ default as {name} }} from "/_vue/{name}";
|
|
|
|
- app.component("{name}", {name});
|
|
|
|
- ''' for name in get_js_components().keys())
|
|
|
|
|
|
+ result = ''
|
|
|
|
+ for component in components.values():
|
|
|
|
+ for dependency in component.dependencies:
|
|
|
|
+ result += f'''
|
|
|
|
+ import "/_vue/{component.name}/{dependency}";
|
|
|
|
+ '''
|
|
|
|
+ for component in get_js_components():
|
|
|
|
+ result += f'''
|
|
|
|
+ import {{ default as {component.name} }} from "/_vue/{component.name}";
|
|
|
|
+ app.component("{component.name}", {component.name});
|
|
|
|
+ '''
|
|
|
|
+ return result
|