diff --git a/reflex/constants/installer.py b/reflex/constants/installer.py index fbee4cd5a..4a7027ee8 100644 --- a/reflex/constants/installer.py +++ b/reflex/constants/installer.py @@ -51,6 +51,8 @@ class Bun(SimpleNamespace): WINDOWS_INSTALL_URL = ( "https://raw.githubusercontent.com/reflex-dev/reflex/main/scripts/install.ps1" ) + # Path of the bunfig file + CONFIG_PATH = "bunfig.toml" # FNM config. diff --git a/reflex/utils/prerequisites.py b/reflex/utils/prerequisites.py index 72eb75b90..a80bcd814 100644 --- a/reflex/utils/prerequisites.py +++ b/reflex/utils/prerequisites.py @@ -38,6 +38,7 @@ from reflex.compiler import templates from reflex.config import Config, get_config from reflex.utils import console, path_ops, processes from reflex.utils.format import format_library_name +from reflex.utils.registry import _get_best_registry CURRENTLY_INSTALLING_NODE = False @@ -577,6 +578,15 @@ def initialize_package_json(): code = _compile_package_json() output_path.write_text(code) + best_registry = _get_best_registry() + bun_config_path = get_web_dir() / constants.Bun.CONFIG_PATH + bun_config_path.write_text( + f""" +[install] +registry = "{best_registry}" +""" + ) + def init_reflex_json(project_hash: int | None): """Write the hash of the Reflex project to a REFLEX_JSON. diff --git a/reflex/utils/registry.py b/reflex/utils/registry.py new file mode 100644 index 000000000..551292f2d --- /dev/null +++ b/reflex/utils/registry.py @@ -0,0 +1,48 @@ +"""Utilities for working with registries.""" + +import httpx + +from reflex.utils import console + + +def latency(registry: str) -> int: + """Get the latency of a registry. + + Args: + registry (str): The URL of the registry. + + Returns: + int: The latency of the registry in microseconds. + """ + try: + return httpx.get(registry).elapsed.microseconds + except httpx.HTTPError: + console.info(f"Failed to connect to {registry}.") + return 10_000_000 + + +def average_latency(registry, attempts: int = 3) -> int: + """Get the average latency of a registry. + + Args: + registry (str): The URL of the registry. + attempts (int): The number of attempts to make. Defaults to 10. + + Returns: + int: The average latency of the registry in microseconds. + """ + return sum(latency(registry) for _ in range(attempts)) // attempts + + +def _get_best_registry() -> str: + """Get the best registry based on latency. + + Returns: + str: The best registry. + """ + registries = [ + "https://registry.npmjs.org", + "https://r.cnpmjs.org", + ] + + return min(registries, key=average_latency)