|
@@ -18,6 +18,7 @@ from typing import (
|
|
|
|
|
|
from fastapi import FastAPI, UploadFile
|
|
from fastapi import FastAPI, UploadFile
|
|
from fastapi.middleware import cors
|
|
from fastapi.middleware import cors
|
|
|
|
+from rich.progress import MofNCompleteColumn, Progress, TimeElapsedColumn
|
|
from socketio import ASGIApp, AsyncNamespace, AsyncServer
|
|
from socketio import ASGIApp, AsyncNamespace, AsyncServer
|
|
from starlette_admin.contrib.sqla.admin import Admin
|
|
from starlette_admin.contrib.sqla.admin import Admin
|
|
from starlette_admin.contrib.sqla.view import ModelView
|
|
from starlette_admin.contrib.sqla.view import ModelView
|
|
@@ -437,6 +438,14 @@ class App(Base):
|
|
|
|
|
|
def compile(self):
|
|
def compile(self):
|
|
"""Compile the app and output it to the pages folder."""
|
|
"""Compile the app and output it to the pages folder."""
|
|
|
|
+ # Create a progress bar.
|
|
|
|
+ progress = Progress(
|
|
|
|
+ *Progress.get_default_columns()[:-1],
|
|
|
|
+ MofNCompleteColumn(),
|
|
|
|
+ TimeElapsedColumn(),
|
|
|
|
+ )
|
|
|
|
+ task = progress.add_task("Compiling: ", total=len(self.pages))
|
|
|
|
+
|
|
for render, kwargs in DECORATED_ROUTES:
|
|
for render, kwargs in DECORATED_ROUTES:
|
|
self.add_page(render, **kwargs)
|
|
self.add_page(render, **kwargs)
|
|
|
|
|
|
@@ -450,48 +459,61 @@ class App(Base):
|
|
# Empty the .web pages directory
|
|
# Empty the .web pages directory
|
|
compiler.purge_web_pages_dir()
|
|
compiler.purge_web_pages_dir()
|
|
|
|
|
|
|
|
+ # Store the compile results.
|
|
|
|
+ compile_results = []
|
|
|
|
+
|
|
|
|
+ # Compile the pages in parallel.
|
|
|
|
+ custom_components = set()
|
|
|
|
+ thread_pool = ThreadPool()
|
|
|
|
+ with progress:
|
|
|
|
+ for route, component in self.pages.items():
|
|
|
|
+ progress.advance(task)
|
|
|
|
+ component.add_style(self.style)
|
|
|
|
+ compile_results.append(
|
|
|
|
+ thread_pool.apply_async(
|
|
|
|
+ compiler.compile_page,
|
|
|
|
+ args=(
|
|
|
|
+ route,
|
|
|
|
+ component,
|
|
|
|
+ self.state,
|
|
|
|
+ self.connect_error_component,
|
|
|
|
+ ),
|
|
|
|
+ )
|
|
|
|
+ )
|
|
|
|
+ # Add the custom components from the page to the set.
|
|
|
|
+ custom_components |= component.get_custom_components()
|
|
|
|
+ thread_pool.close()
|
|
|
|
+ thread_pool.join()
|
|
|
|
+
|
|
|
|
+ # Get the results.
|
|
|
|
+ compile_results = [result.get() for result in compile_results]
|
|
|
|
+
|
|
|
|
+ # Compile the custom components.
|
|
|
|
+ compile_results.append(compiler.compile_components(custom_components))
|
|
|
|
+
|
|
# Compile the root document with base styles and fonts.
|
|
# Compile the root document with base styles and fonts.
|
|
- compiler.compile_document_root(self.stylesheets)
|
|
|
|
|
|
+ compile_results.append(compiler.compile_document_root(self.stylesheets))
|
|
|
|
|
|
# Compile the theme.
|
|
# Compile the theme.
|
|
- compiler.compile_theme(self.style)
|
|
|
|
|
|
+ compile_results.append(compiler.compile_theme(self.style))
|
|
|
|
|
|
# Compile the Tailwind config.
|
|
# Compile the Tailwind config.
|
|
- compiler.compile_tailwind(
|
|
|
|
- dict(**config.tailwind, content=constants.TAILWIND_CONTENT)
|
|
|
|
- if config.tailwind is not None
|
|
|
|
- else {}
|
|
|
|
|
|
+ compile_results.append(
|
|
|
|
+ compiler.compile_tailwind(
|
|
|
|
+ dict(**config.tailwind, content=constants.TAILWIND_CONTENT)
|
|
|
|
+ if config.tailwind is not None
|
|
|
|
+ else {}
|
|
|
|
+ )
|
|
)
|
|
)
|
|
|
|
|
|
- # Compile the pages.
|
|
|
|
- custom_components = set()
|
|
|
|
|
|
+ # Write the pages at the end to trigger the NextJS hot reload only once.
|
|
thread_pool = ThreadPool()
|
|
thread_pool = ThreadPool()
|
|
- compile_results = []
|
|
|
|
- for route, component in self.pages.items():
|
|
|
|
- component.add_style(self.style)
|
|
|
|
- compile_results.append(
|
|
|
|
- thread_pool.apply_async(
|
|
|
|
- compiler.compile_page,
|
|
|
|
- args=(
|
|
|
|
- route,
|
|
|
|
- component,
|
|
|
|
- self.state,
|
|
|
|
- self.connect_error_component,
|
|
|
|
- ),
|
|
|
|
- )
|
|
|
|
- )
|
|
|
|
- # Add the custom components from the page to the set.
|
|
|
|
- custom_components |= component.get_custom_components()
|
|
|
|
|
|
+ for output_path, code in compile_results:
|
|
|
|
+ compiler_utils.write_page(output_path, code)
|
|
|
|
+ thread_pool.apply_async(compiler_utils.write_page, args=(output_path, code))
|
|
thread_pool.close()
|
|
thread_pool.close()
|
|
thread_pool.join()
|
|
thread_pool.join()
|
|
|
|
|
|
- # check the results of all the threads in case an exception was raised.
|
|
|
|
- for r in compile_results:
|
|
|
|
- r.get()
|
|
|
|
-
|
|
|
|
- # Compile the custom components.
|
|
|
|
- compiler.compile_components(custom_components)
|
|
|
|
-
|
|
|
|
|
|
|
|
async def process(
|
|
async def process(
|
|
app: App, event: Event, sid: str, headers: Dict, client_ip: str
|
|
app: App, event: Event, sid: str, headers: Dict, client_ip: str
|