diff --git a/.gitignore b/.gitignore index 0f7d9e5ffa0..8bd92964c57 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ assets/external/* dist/* examples/ .web +.states .idea .vscode .coverage diff --git a/reflex/config.py b/reflex/config.py index 2daf8ef1da1..c3c5e4cf5df 100644 --- a/reflex/config.py +++ b/reflex/config.py @@ -490,6 +490,9 @@ class EnvironmentVariables: # The working directory for the next.js commands. REFLEX_WEB_WORKDIR: EnvVar[Path] = env_var(Path(constants.Dirs.WEB)) + # The working directory for the states directory. + REFLEX_STATES_WORKDIR: EnvVar[Path] = env_var(Path(constants.Dirs.STATES)) + # Path to the alembic config file ALEMBIC_CONFIG: EnvVar[ExistingPath] = env_var(Path(constants.ALEMBIC_CONFIG)) diff --git a/reflex/constants/base.py b/reflex/constants/base.py index f737858c008..11f3e3c0552 100644 --- a/reflex/constants/base.py +++ b/reflex/constants/base.py @@ -52,7 +52,7 @@ class Dirs(SimpleNamespace): # The name of the postcss config file. POSTCSS_JS = "postcss.config.js" # The name of the states directory. - STATES = "states" + STATES = ".states" class Reflex(SimpleNamespace): diff --git a/reflex/constants/config.py b/reflex/constants/config.py index 7425fd86486..a49216c00cf 100644 --- a/reflex/constants/config.py +++ b/reflex/constants/config.py @@ -39,7 +39,14 @@ class GitIgnore(SimpleNamespace): # The gitignore file. FILE = Path(".gitignore") # Files to gitignore. - DEFAULTS = {Dirs.WEB, "*.db", "__pycache__/", "*.py[cod]", "assets/external/"} + DEFAULTS = { + Dirs.WEB, + Dirs.STATES, + "*.db", + "__pycache__/", + "*.py[cod]", + "assets/external/", + } class RequirementsTxt(SimpleNamespace): diff --git a/reflex/state.py b/reflex/state.py index 8085a92ec81..40afcbc7959 100644 --- a/reflex/state.py +++ b/reflex/state.py @@ -3046,7 +3046,7 @@ def is_serializable(value: Any) -> bool: def reset_disk_state_manager(): """Reset the disk state manager.""" - states_directory = prerequisites.get_web_dir() / constants.Dirs.STATES + states_directory = prerequisites.get_states_dir() if states_directory.exists(): for path in states_directory.iterdir(): path.unlink() @@ -3094,7 +3094,7 @@ def states_directory(self) -> Path: Returns: The states directory. """ - return prerequisites.get_web_dir() / constants.Dirs.STATES + return prerequisites.get_states_dir() def _purge_expired_states(self): """Purge expired states from the disk.""" diff --git a/reflex/utils/exec.py b/reflex/utils/exec.py index 9a5b7011262..88603da6431 100644 --- a/reflex/utils/exec.py +++ b/reflex/utils/exec.py @@ -307,7 +307,7 @@ def run_granian_backend(host, port, loglevel: LogLevel): log_level=LogLevels(loglevel.value), reload=True, reload_paths=get_reload_dirs(), - reload_ignore_dirs=[".web"], + reload_ignore_dirs=[".web", ".states"], ).serve() except ImportError: console.error( diff --git a/reflex/utils/path_ops.py b/reflex/utils/path_ops.py index b447718d2ab..e3256bb454c 100644 --- a/reflex/utils/path_ops.py +++ b/reflex/utils/path_ops.py @@ -196,6 +196,9 @@ def update_json_file(file_path: str | Path, update_dict: dict[str, int | str]): """ fp = Path(file_path) + # Create the parent directory if it doesn't exist. + fp.parent.mkdir(parents=True, exist_ok=True) + # Create the file if it doesn't exist. fp.touch(exist_ok=True) diff --git a/reflex/utils/prerequisites.py b/reflex/utils/prerequisites.py index 94d8f8fbd1a..2a890f82112 100644 --- a/reflex/utils/prerequisites.py +++ b/reflex/utils/prerequisites.py @@ -87,6 +87,17 @@ def get_web_dir() -> Path: return environment.REFLEX_WEB_WORKDIR.get() +def get_states_dir() -> Path: + """Get the working directory for the states. + + Can be overridden with REFLEX_STATES_WORKDIR. + + Returns: + The working directory. + """ + return environment.REFLEX_STATES_WORKDIR.get() + + def check_latest_package_version(package_name: str): """Check if the latest version of the package is installed.