|
@@ -1,4 +1,5 @@
|
|
|
import json
|
|
|
+import logging
|
|
|
from pathlib import Path
|
|
|
from typing import Any, Dict, List, Set, Tuple
|
|
|
|
|
@@ -12,14 +13,22 @@ js_components: Dict[str, Any] = {}
|
|
|
libraries: Dict[str, Any] = {}
|
|
|
|
|
|
|
|
|
-def register_vue_component(name: str, path: Path) -> None:
|
|
|
+def register_vue_component(location: Path,
|
|
|
+ base_path: Path = Path(__file__).parent / 'elements', *, expose: bool = False
|
|
|
+ ) -> str:
|
|
|
"""Register a .vue or .js Vue component.
|
|
|
|
|
|
- :param name: unique machine-name (used in element's `use_library`): no space, no special characters
|
|
|
- :param path: local path
|
|
|
+ :param location: the location to the library you want to register relative to the base_path. This is also used as the resource identifier and must therefore be url-safe.
|
|
|
+ :param base_path: the base path where your libraries are located
|
|
|
+ :return: the resource identifier library name to be used in element's `use_component`
|
|
|
"""
|
|
|
- suffix = path.suffix.lower()
|
|
|
+ if isinstance(location, str):
|
|
|
+ logging.warning('register_vue_component: location is a string, did you mean to use register_library?')
|
|
|
+ return
|
|
|
+ suffix = location.suffix.lower()
|
|
|
assert suffix in {'.vue', '.js', '.mjs'}, 'Only VUE and JS components are supported.'
|
|
|
+ name = location.stem
|
|
|
+ path = base_path / location
|
|
|
if suffix == '.vue':
|
|
|
assert name not in vue_components, f'Duplicate VUE component name {name}'
|
|
|
# The component (in case of .vue) is built right away to:
|
|
@@ -28,14 +37,16 @@ def register_vue_component(name: str, path: Path) -> None:
|
|
|
vue_components[name] = vbuild.VBuild(name, path.read_text())
|
|
|
elif suffix == '.js':
|
|
|
assert name not in js_components, f'Duplicate JS component name {name}'
|
|
|
- js_components[name] = {'name': name, 'path': path}
|
|
|
+ js_components[str(location)] = {'name': name, 'path': path}
|
|
|
+ return str(location)
|
|
|
|
|
|
|
|
|
-def register_library(
|
|
|
- location: Path, base_path: Path = Path(__file__).parent / 'elements' / 'lib', *, expose: bool = False) -> str:
|
|
|
+def register_library(location: Path,
|
|
|
+ base_path: Path = Path(__file__).parent / 'elements' / 'lib', *, expose: bool = False
|
|
|
+ ) -> str:
|
|
|
"""Register a new external library.
|
|
|
|
|
|
- :param location: the location to the library you want to register relative to the base_path. This is also used as the resource identifier (used in element's `use_library`) and must therefore be url-safe.
|
|
|
+ :param location: the location to the library you want to register relative to the base_path. This is also used as the resource identifier and must therefore be url-safe.
|
|
|
:param base_path: the base path where your libraries are located
|
|
|
:param expose: if True, this will be exposed as an ESM module but NOT imported
|
|
|
:return: the resource identifier library name to be used in element's `use_library`
|
|
@@ -44,6 +55,7 @@ def register_library(
|
|
|
return
|
|
|
assert location.suffix == '.js' or location.suffix == '.mjs', 'Only JS dependencies are supported.'
|
|
|
name = str(location)
|
|
|
+ assert name not in libraries, f'Duplicate js library name {name}'
|
|
|
libraries[name] = {'name': name, 'path': base_path / location, 'expose': expose}
|
|
|
return name
|
|
|
|
|
@@ -58,33 +70,33 @@ def generate_resources(prefix: str, elements: List[Element]) -> Tuple[str, str,
|
|
|
import_maps = {'imports': {}}
|
|
|
|
|
|
# Build the importmap structure for exposed libraries.
|
|
|
- for key in libraries:
|
|
|
- if key not in done_libraries and libraries[key]['expose']:
|
|
|
- name = libraries[key]['name']
|
|
|
- import_maps['imports'][name] = f'{prefix}/_nicegui/{__version__}/library/{key}'
|
|
|
- done_libraries.add(key)
|
|
|
+ for resource in libraries:
|
|
|
+ if resource not in done_libraries and libraries[resource]['expose']:
|
|
|
+ name = libraries[resource]['name']
|
|
|
+ import_maps['imports'][name] = f'{prefix}/_nicegui/{__version__}/library/{resource}'
|
|
|
+ done_libraries.add(resource)
|
|
|
# Build the none optimized component (ie, the vue component).
|
|
|
- for key in vue_components:
|
|
|
- if key not in done_components:
|
|
|
- vue_html += f'{vue_components[key].html}\n'
|
|
|
- vue_scripts += f'{vue_components[key].script.replace("Vue.component", "app.component", 1)}\n'
|
|
|
- vue_styles += f'{vue_components[key].style}\n'
|
|
|
- done_components.add(key)
|
|
|
+ for resource in vue_components:
|
|
|
+ if resource not in done_components:
|
|
|
+ vue_html += f'{vue_components[resource].html}\n'
|
|
|
+ vue_scripts += f'{vue_components[resource].script.replace("Vue.component", "app.component", 1)}\n'
|
|
|
+ vue_styles += f'{vue_components[resource].style}\n'
|
|
|
+ done_components.add(resource)
|
|
|
|
|
|
# Build the resources associated with the elements.
|
|
|
for element in elements:
|
|
|
- for key in element.libraries:
|
|
|
- if key in libraries and key not in done_libraries:
|
|
|
- if not libraries[key]['expose']:
|
|
|
- js_imports += f'import "{prefix}/_nicegui/{__version__}/library/{key}";\n'
|
|
|
- done_libraries.add(key)
|
|
|
- for key in element.components:
|
|
|
- if key in js_components and key not in done_components:
|
|
|
- name = js_components[key]['name']
|
|
|
- var = key.replace('-', '_')
|
|
|
- js_imports += f'import {{ default as {var} }} from "{prefix}/_nicegui/{__version__}/components/{key}";\n'
|
|
|
+ for resource in element.libraries:
|
|
|
+ if resource in libraries and resource not in done_libraries:
|
|
|
+ if not libraries[resource]['expose']:
|
|
|
+ js_imports += f'import "{prefix}/_nicegui/{__version__}/library/{resource}";\n'
|
|
|
+ done_libraries.add(resource)
|
|
|
+ for resource in element.components:
|
|
|
+ if resource in js_components and resource not in done_components:
|
|
|
+ name = js_components[resource]['name']
|
|
|
+ var = name.replace('-', '_')
|
|
|
+ js_imports += f'import {{ default as {var} }} from "{prefix}/_nicegui/{__version__}/components/{resource}";\n'
|
|
|
js_imports += f'app.component("{name}", {var});\n'
|
|
|
- done_components.add(key)
|
|
|
+ done_components.add(resource)
|
|
|
vue_styles = f'<style>{vue_styles}</style>'
|
|
|
import_maps = f'<script type="importmap">{json.dumps(import_maps)}</script>'
|
|
|
return vue_html, vue_styles, vue_scripts, import_maps, js_imports
|