Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ reflex.db
node_modules
package-lock.json
*.pyi
.pre-commit-config.yaml
.pre-commit-config.yaml
uploaded_files/*
13 changes: 7 additions & 6 deletions reflex/.templates/web/utils/state.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import {
onLoadInternalEvent,
state_name,
exception_state_name,
main_state_name,
update_vars_internal,
} from "$/utils/context";
import debounce from "$/utils/helpers/debounce";
import throttle from "$/utils/helpers/throttle";
Expand Down Expand Up @@ -134,7 +136,7 @@ export const isStateful = () => {
if (event_queue.length === 0) {
return false;
}
return event_queue.some((event) => event.name.startsWith("reflex___state"));
return event_queue.some((event) => event.name.startsWith(main_state_name));
};

/**
Expand Down Expand Up @@ -1034,10 +1036,9 @@ export const useEventLoop = (
if (storage_to_state_map[e.key]) {
const vars = {};
vars[storage_to_state_map[e.key]] = e.newValue;
const event = ReflexEvent(
`${state_name}.reflex___state____update_vars_internal_state.update_vars_internal`,
{ vars: vars },
);
const event = ReflexEvent(`${state_name}.${update_vars_internal}`, {
vars: vars,
});
addEvents([event], e);
}
};
Expand Down Expand Up @@ -1072,7 +1073,7 @@ export const useEventLoop = (
}

// Equivalent to routeChangeStart - runs when navigation begins
const main_state_dispatch = dispatch["reflex___state____state"];
const main_state_dispatch = dispatch[main_state_name];
if (main_state_dispatch !== undefined) {
main_state_dispatch({ is_hydrated_rx_state_: false });
}
Expand Down
28 changes: 25 additions & 3 deletions reflex/compiler/templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,20 @@ def context_template(
Returns:
Rendered context file content as string.
"""
# Import state classes to get dynamic names (supports minification)
from reflex.state import (
FrontendEventExceptionState,
OnLoadInternalState,
State,
UpdateVarsInternalState,
)

# Compute dynamic state names that respect minification settings
main_state_name = State.get_name()
on_load_internal = f"{OnLoadInternalState.get_name()}.on_load_internal"
update_vars_internal = f"{UpdateVarsInternalState.get_name()}.update_vars_internal"
exception_state_full = FrontendEventExceptionState.get_full_name()

initial_state = initial_state or {}
state_contexts_str = "".join([
f"{format_state_name(state_name)}: createContext(null),"
Expand All @@ -284,7 +298,11 @@ def context_template(
rf"""
export const state_name = "{state_name}"

export const exception_state_name = "{constants.CompileVars.FRONTEND_EXCEPTION_STATE_FULL}"
export const main_state_name = "{main_state_name}"

export const update_vars_internal = "{update_vars_internal}"

export const exception_state_name = "{exception_state_full}"

// These events are triggered on initial load and each page navigation.
export const onLoadInternalEvent = () => {{
Expand All @@ -296,15 +314,15 @@ def context_template(
if (client_storage_vars && Object.keys(client_storage_vars).length !== 0) {{
internal_events.push(
ReflexEvent(
'{state_name}.{constants.CompileVars.UPDATE_VARS_INTERNAL}',
'{state_name}.{update_vars_internal}',
{{vars: client_storage_vars}},
),
);
}}

// `on_load_internal` triggers the correct on_load event(s) for the current page.
// If the page does not define any on_load event, this will just set `is_hydrated = true`.
internal_events.push(ReflexEvent('{state_name}.{constants.CompileVars.ON_LOAD_INTERNAL}'));
internal_events.push(ReflexEvent('{state_name}.{on_load_internal}'));

return internal_events;
}}
Expand All @@ -319,6 +337,10 @@ def context_template(
else """
export const state_name = undefined

export const main_state_name = undefined

export const update_vars_internal = undefined

export const exception_state_name = undefined

export const onLoadInternalEvent = () => []
Expand Down
12 changes: 0 additions & 12 deletions reflex/constants/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,18 +65,6 @@ class CompileVars(SimpleNamespace):
CONNECT_ERROR = "connectErrors"
# The name of the function for converting a dict to an event.
TO_EVENT = "ReflexEvent"
# 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):
Expand Down
15 changes: 15 additions & 0 deletions reflex/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,15 @@ class PerformanceMode(enum.Enum):
OFF = "off"


@enum.unique
class MinifyMode(enum.Enum):
"""Mode for state/event name minification."""

DISABLED = "disabled" # Never minify names (default)
ENABLED = "enabled" # Minify items that have explicit IDs
ENFORCE = "enforce" # Require all items to have explicit IDs


class ExecutorType(enum.Enum):
"""Executor for compiling the frontend."""

Expand Down Expand Up @@ -688,6 +697,12 @@ class EnvironmentVariables:
# The maximum size of the reflex state in kilobytes.
REFLEX_STATE_SIZE_LIMIT: EnvVar[int] = env_var(1000)

# State name minification mode: disabled, enabled, or enforce.
REFLEX_MINIFY_STATES: EnvVar[MinifyMode] = env_var(MinifyMode.DISABLED)

# Event handler name minification mode: disabled, enabled, or enforce.
REFLEX_MINIFY_EVENTS: EnvVar[MinifyMode] = env_var(MinifyMode.DISABLED)

# Whether to use the turbopack bundler.
REFLEX_USE_TURBOPACK: EnvVar[bool] = env_var(False)

Expand Down
9 changes: 9 additions & 0 deletions reflex/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ def substate_token(self) -> str:
_EVENT_FIELDS: set[str] = {f.name for f in dataclasses.fields(Event)}

BACKGROUND_TASK_MARKER = "_reflex_background_task"
EVENT_ID_MARKER = "_rx_event_id"


@dataclasses.dataclass(
Expand Down Expand Up @@ -2311,6 +2312,7 @@ class EventNamespace:

# Constants
BACKGROUND_TASK_MARKER = BACKGROUND_TASK_MARKER
EVENT_ID_MARKER = EVENT_ID_MARKER
_EVENT_FIELDS = _EVENT_FIELDS
FORM_DATA = FORM_DATA
upload_files = upload_files
Expand All @@ -2334,6 +2336,7 @@ def __new__(
throttle: int | None = None,
debounce: int | None = None,
temporal: bool | None = None,
event_id: int | None = None,
) -> Callable[
[Callable[[BASE_STATE, Unpack[P]], Any]], EventCallback[Unpack[P]] # pyright: ignore [reportInvalidTypeVarUse]
]: ...
Expand All @@ -2349,6 +2352,7 @@ def __new__(
throttle: int | None = None,
debounce: int | None = None,
temporal: bool | None = None,
event_id: int | None = None,
) -> EventCallback[Unpack[P]]: ...

def __new__(
Expand All @@ -2361,6 +2365,7 @@ def __new__(
throttle: int | None = None,
debounce: int | None = None,
temporal: bool | None = None,
event_id: int | None = None,
) -> (
EventCallback[Unpack[P]]
| Callable[[Callable[[BASE_STATE, Unpack[P]], Any]], EventCallback[Unpack[P]]]
Expand All @@ -2375,6 +2380,7 @@ def __new__(
throttle: Throttle the event handler to limit calls (in milliseconds).
debounce: Debounce the event handler to delay calls (in milliseconds).
temporal: Whether the event should be dropped when the backend is down.
event_id: Optional integer ID for deterministic minified event names.

Raises:
TypeError: If background is True and the function is not a coroutine or async generator. # noqa: DAR402
Expand Down Expand Up @@ -2462,6 +2468,9 @@ def wrapper(
event_actions = _build_event_actions()
if event_actions:
func._rx_event_actions = event_actions # pyright: ignore [reportFunctionMemberAccess]
# Store event_id on the function for minification
if event_id is not None:
setattr(func, EVENT_ID_MARKER, event_id)
return func # pyright: ignore [reportReturnType]

if func is not None:
Expand Down
Loading
Loading