
* add module prefix to state names * fix state names in test_app * update state names in test_state * fix state names in test_var * fix state name in test_component * fix state names in test_format * fix state names in test_foreach * fix state names in test_cond * fix state names in test_datatable * fix state names in test_colors * fix state names in test_script * fix state names in test_match * fix state name in event1 fixture * fix pyright and darglint * fix state names in state_tree * fix state names in redis only test * fix state names in test_client_storage * fix state name in js template * add `get_state_name` and `get_full_state_name` helpers for `AppHarness` * fix state names in test_dynamic_routes * use new state name helpers in test_client_storage * fix state names in test_event_actions * fix state names in test_event_chain * fix state names in test_upload * fix state name in test_login_flow * fix state names in test_input * fix state names in test_form_submit * ruff * validate state module names * wtf is going on here? * remove comments leftover from refactoring * adjust new test_add_style_embedded_vars * fix state name in state.js * fix integration/test_client_state.py new SessionStorage feature was added with more full state names that need to be formatted in * fix pre-commit issues in test_client_storage.py * adjust test_computed_vars * adjust safe-guards * fix redis tests with new exception state --------- Co-authored-by: Masen Furer <m_github@0x26.net>
163 lines
4.8 KiB
Python
163 lines
4.8 KiB
Python
"""Compiler variables."""
|
|
|
|
import enum
|
|
from enum import Enum
|
|
from types import SimpleNamespace
|
|
|
|
from reflex.base import Base
|
|
from reflex.constants import Dirs
|
|
from reflex.utils.imports import ImportVar
|
|
|
|
# The prefix used to create setters for state vars.
|
|
SETTER_PREFIX = "set_"
|
|
|
|
# The file used to specify no compilation.
|
|
NOCOMPILE_FILE = "nocompile"
|
|
|
|
|
|
class Ext(SimpleNamespace):
|
|
"""Extension used in Reflex."""
|
|
|
|
# The extension for JS files.
|
|
JS = ".js"
|
|
# The extension for python files.
|
|
PY = ".py"
|
|
# The extension for css files.
|
|
CSS = ".css"
|
|
# The extension for zip files.
|
|
ZIP = ".zip"
|
|
# The extension for executable files on Windows.
|
|
EXE = ".exe"
|
|
|
|
|
|
class CompileVars(SimpleNamespace):
|
|
"""The variables used during compilation."""
|
|
|
|
# The expected variable name where the rx.App is stored.
|
|
APP = "app"
|
|
# The expected variable name where the API object is stored for deployment.
|
|
API = "api"
|
|
# The name of the router variable.
|
|
ROUTER = "router"
|
|
# The name of the socket variable.
|
|
SOCKET = "socket"
|
|
# The name of the variable to hold API results.
|
|
RESULT = "result"
|
|
# The name of the final variable.
|
|
FINAL = "final"
|
|
# The name of the process variable.
|
|
PROCESSING = "processing"
|
|
# The name of the state variable.
|
|
STATE = "state"
|
|
# The name of the events variable.
|
|
EVENTS = "events"
|
|
# The name of the initial hydrate event.
|
|
HYDRATE = "hydrate"
|
|
# The name of the is_hydrated variable.
|
|
IS_HYDRATED = "is_hydrated"
|
|
# The name of the function to add events to the queue.
|
|
ADD_EVENTS = "addEvents"
|
|
# The name of the var storing any connection error.
|
|
CONNECT_ERROR = "connectErrors"
|
|
# The name of the function for converting a dict to an event.
|
|
TO_EVENT = "Event"
|
|
# The name of the internal on_load event.
|
|
ON_LOAD_INTERNAL = "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"
|
|
)
|
|
# The name of the frontend event exception state
|
|
FRONTEND_EXCEPTION_STATE = "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}"
|
|
)
|
|
|
|
|
|
class PageNames(SimpleNamespace):
|
|
"""The name of basic pages deployed in NextJS."""
|
|
|
|
# The name of the index page.
|
|
INDEX_ROUTE = "index"
|
|
# The name of the app root page.
|
|
APP_ROOT = "_app"
|
|
# The root stylesheet filename.
|
|
STYLESHEET_ROOT = "styles"
|
|
# The name of the document root page.
|
|
DOCUMENT_ROOT = "_document"
|
|
# The name of the theme page.
|
|
THEME = "theme"
|
|
# The module containing components.
|
|
COMPONENTS = "components"
|
|
# The module containing shared stateful components
|
|
STATEFUL_COMPONENTS = "stateful_components"
|
|
|
|
|
|
class ComponentName(Enum):
|
|
"""Component names."""
|
|
|
|
BACKEND = "Backend"
|
|
FRONTEND = "Frontend"
|
|
|
|
def zip(self):
|
|
"""Give the zip filename for the component.
|
|
|
|
Returns:
|
|
The lower-case filename with zip extension.
|
|
"""
|
|
return self.value.lower() + Ext.ZIP
|
|
|
|
|
|
class Imports(SimpleNamespace):
|
|
"""Common sets of import vars."""
|
|
|
|
EVENTS = {
|
|
"react": [ImportVar(tag="useContext")],
|
|
f"/{Dirs.CONTEXTS_PATH}": [ImportVar(tag="EventLoopContext")],
|
|
f"/{Dirs.STATE_PATH}": [ImportVar(tag=CompileVars.TO_EVENT)],
|
|
}
|
|
|
|
|
|
class Hooks(SimpleNamespace):
|
|
"""Common sets of hook declarations."""
|
|
|
|
EVENTS = f"const [{CompileVars.ADD_EVENTS}, {CompileVars.CONNECT_ERROR}] = useContext(EventLoopContext);"
|
|
AUTOFOCUS = """
|
|
// Set focus to the specified element.
|
|
const focusRef = useRef(null)
|
|
useEffect(() => {
|
|
if (focusRef.current) {
|
|
focusRef.current.focus();
|
|
}
|
|
})"""
|
|
|
|
FRONTEND_ERRORS = f"""
|
|
const logFrontendError = (error, info) => {{
|
|
if (process.env.NODE_ENV === "production") {{
|
|
addEvents([Event("{CompileVars.FRONTEND_EXCEPTION_STATE_FULL}.handle_frontend_exception", {{
|
|
stack: error.stack,
|
|
}})])
|
|
}}
|
|
}}
|
|
"""
|
|
|
|
|
|
class MemoizationDisposition(enum.Enum):
|
|
"""The conditions under which a component should be memoized."""
|
|
|
|
# If the component uses state or events, it should be memoized.
|
|
STATEFUL = "stateful"
|
|
ALWAYS = "always"
|
|
NEVER = "never"
|
|
|
|
|
|
class MemoizationMode(Base):
|
|
"""The mode for memoizing a Component."""
|
|
|
|
# The conditions under which the component should be memoized.
|
|
disposition: MemoizationDisposition = MemoizationDisposition.STATEFUL
|
|
|
|
# Whether children of this component should be memoized first.
|
|
recursive: bool = True
|