wip minified state names

This commit is contained in:
Benedikt Bartscher 2024-05-04 12:53:16 +02:00 committed by Masen Furer
parent 4a6c16e9dc
commit 673c488dc0
No known key found for this signature in database
GPG Key ID: B0008AD22B3B3A95
2 changed files with 98 additions and 3 deletions
reflex

View File

@ -1,6 +1,7 @@
"""Compiler variables."""
import enum
import os
from enum import Enum
from types import SimpleNamespace
@ -61,18 +62,35 @@ class CompileVars(SimpleNamespace):
CONNECT_ERROR = "connectErrors"
# The name of the function for converting a dict to an event.
TO_EVENT = "Event"
# The env var to toggle minification of states.
ENV_MINIFY_STATES = "REFLEX_MINIFY_STATES"
# Whether to minify states.
MINIFY_STATES = os.environ.get(ENV_MINIFY_STATES, False)
# The name of the internal on_load event.
ON_LOAD_INTERNAL = "reflex___state____on_load_internal_state.on_load_internal"
ON_LOAD_INTERNAL = (
"l"
if MINIFY_STATES
else "reflex___state____on_load_internal_state.on_load_internal"
)
# The name of the internal event to update generic state vars.
UPDATE_VARS_INTERNAL = (
"reflex___state____update_vars_internal_state.update_vars_internal"
"u"
if MINIFY_STATES
else ("reflex___state____update_vars_internal_state.update_vars_internal")
)
# The name of the frontend event exception state
FRONTEND_EXCEPTION_STATE = "reflex___state____frontend_event_exception_state"
FRONTEND_EXCEPTION_STATE = (
"e" if MINIFY_STATES else "reflex___state____frontend_event_exception_state"
)
# The full name of the frontend exception state
FRONTEND_EXCEPTION_STATE_FULL = (
f"reflex___state____state.{FRONTEND_EXCEPTION_STATE}"
)
INTERNAL_STATE_NAMES = {
ON_LOAD_INTERNAL,
UPDATE_VARS_INTERNAL,
FRONTEND_EXCEPTION_STATE_FULL,
}
class PageNames(SimpleNamespace):

View File

@ -285,6 +285,61 @@ def get_var_for_field(cls: Type[BaseState], f: ModelField):
)
# Keep track of all state instances to calculate minified state names
state_count = 0
all_state_names: Set[str] = set()
def next_minified_state_name() -> str:
"""Get the next minified state name.
Returns:
The next minified state name.
Raises:
RuntimeError: If the minified state name already exists.
"""
global state_count
global all_state_names
num = state_count
# All possible chars for minified state name
chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_"
base = len(chars)
state_name = ""
if num == 0:
state_name = chars[0]
while num > 0:
state_name = chars[num % base] + state_name
num = num // base
state_count += 1
if state_name in all_state_names:
raise RuntimeError(f"Minified state name {state_name} already exists")
all_state_names.add(state_name)
return state_name
def generate_state_name() -> str:
"""Generate a minified state name.
Returns:
The minified state name.
Raises:
ValueError: If no more minified state names are available
"""
while name := next_minified_state_name():
if name not in constants.CompileVars.INTERNAL_STATE_NAMES:
return name
raise ValueError("No more minified state names available")
class BaseState(Base, ABC, extra=pydantic.Extra.allow):
"""The state of the app."""
@ -354,6 +409,9 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
# A special event handler for setting base vars.
setvar: ClassVar[EventHandler]
# Minified state name
_state_name: ClassVar[Optional[str]] = None
def __init__(
self,
parent_state: BaseState | None = None,
@ -459,6 +517,10 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
if "<locals>" in cls.__qualname__:
cls._handle_local_def()
# Generate a minified state name by converting state count to string
if not cls._state_name:
cls._state_name = generate_state_name()
# Validate the module name.
cls._validate_module_name()
@ -874,7 +936,16 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
Returns:
The name of the state.
Raises:
RuntimeError: If the state name is not set.
"""
if constants.CompileVars.MINIFY_STATES:
if not cls._state_name:
raise RuntimeError(
"State name minification is enabled, but state name is not set."
)
return cls._state_name
module = cls.__module__.replace(".", "___")
return format.to_snake_case(f"{module}___{cls.__name__}")
@ -2218,6 +2289,8 @@ def dynamic(func: Callable[[T], Component]):
class FrontendEventExceptionState(State):
"""Substate for handling frontend exceptions."""
_state_name: Optional[str] = constants.CompileVars.FRONTEND_EXCEPTION_STATE
@event
def handle_frontend_exception(self, stack: str, component_stack: str) -> None:
"""Handle frontend exceptions.
@ -2237,6 +2310,8 @@ class FrontendEventExceptionState(State):
class UpdateVarsInternalState(State):
"""Substate for handling internal state var updates."""
_state_name: Optional[str] = constants.CompileVars.UPDATE_VARS_INTERNAL
async def update_vars_internal(self, vars: dict[str, Any]) -> None:
"""Apply updates to fully qualified state vars.
@ -2262,6 +2337,8 @@ class OnLoadInternalState(State):
This is a separate substate to avoid deserializing the entire state tree for every page navigation.
"""
_state_name: Optional[str] = constants.CompileVars.ON_LOAD_INTERNAL
def on_load_internal(self) -> list[Event | EventSpec] | None:
"""Queue on_load handlers for the current page.