reflex 0.8.11a1__py3-none-any.whl → 0.8.12a2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of reflex might be problematic. Click here for more details.

reflex/state.py CHANGED
@@ -41,7 +41,7 @@ from reflex.event import (
41
41
  from reflex.istate import HANDLED_PICKLE_ERRORS, debug_failed_pickles
42
42
  from reflex.istate.data import RouterData
43
43
  from reflex.istate.proxy import ImmutableMutableProxy as ImmutableMutableProxy
44
- from reflex.istate.proxy import MutableProxy, StateProxy
44
+ from reflex.istate.proxy import MutableProxy, StateProxy, is_mutable_type
45
45
  from reflex.istate.storage import ClientStorageBase
46
46
  from reflex.model import Model
47
47
  from reflex.utils import console, format, prerequisites, types
@@ -1359,7 +1359,7 @@ class BaseState(EvenMoreBasicBaseState):
1359
1359
  if parent_state is not None:
1360
1360
  return getattr(parent_state, name)
1361
1361
 
1362
- if MutableProxy._is_mutable_type(value) and (
1362
+ if is_mutable_type(type(value)) and (
1363
1363
  name in super().__getattribute__("base_vars") or name in backend_vars
1364
1364
  ):
1365
1365
  # track changes in mutable containers (list, dict, set, etc)
reflex/style.py CHANGED
@@ -120,9 +120,11 @@ def convert_item(
120
120
  Raises:
121
121
  ReflexError: If an EventHandler is used as a style value
122
122
  """
123
- if isinstance(style_item, EventHandler):
123
+ from reflex.components.component import BaseComponent
124
+
125
+ if isinstance(style_item, (EventHandler, BaseComponent)):
124
126
  msg = (
125
- "EventHandlers cannot be used as style values. "
127
+ f"{type(style_item)} cannot be used as style values. "
126
128
  "Please use a Var or a literal value."
127
129
  )
128
130
  raise ReflexError(msg)
reflex/testing.py CHANGED
@@ -47,6 +47,7 @@ from reflex.state import (
47
47
  )
48
48
  from reflex.utils import console, js_runtimes
49
49
  from reflex.utils.export import export
50
+ from reflex.utils.token_manager import TokenManager
50
51
  from reflex.utils.types import ASGIApp
51
52
 
52
53
  try:
@@ -774,6 +775,19 @@ class AppHarness:
774
775
  self.app_instance._state_manager = app_state_manager
775
776
  await self.state_manager.close()
776
777
 
778
+ def token_manager(self) -> TokenManager:
779
+ """Get the token manager for the app instance.
780
+
781
+ Returns:
782
+ The current token_manager attached to the app's EventNamespace.
783
+ """
784
+ assert self.app_instance is not None
785
+ app_event_namespace = self.app_instance.event_namespace
786
+ assert app_event_namespace is not None
787
+ app_token_manager = app_event_namespace._token_manager
788
+ assert app_token_manager is not None
789
+ return app_token_manager
790
+
777
791
  def poll_for_content(
778
792
  self,
779
793
  element: WebElement,
reflex/utils/build.py CHANGED
@@ -26,14 +26,14 @@ def set_env_json():
26
26
 
27
27
 
28
28
  def _zip(
29
+ *,
29
30
  component_name: constants.ComponentName,
30
- target: str | Path,
31
- root_dir: str | Path,
32
- exclude_venv_dirs: bool,
33
- upload_db_file: bool = False,
34
- dirs_to_exclude: set[str] | None = None,
35
- files_to_exclude: set[str] | None = None,
36
- top_level_dirs_to_exclude: set[str] | None = None,
31
+ target: Path,
32
+ root_directory: Path,
33
+ exclude_venv_directories: bool,
34
+ include_db_file: bool = False,
35
+ directory_names_to_exclude: set[str] | None = None,
36
+ files_to_exclude: set[Path] | None = None,
37
37
  globs_to_include: list[str] | None = None,
38
38
  ) -> None:
39
39
  """Zip utility function.
@@ -41,49 +41,62 @@ def _zip(
41
41
  Args:
42
42
  component_name: The name of the component: backend or frontend.
43
43
  target: The target zip file.
44
- root_dir: The root directory to zip.
45
- exclude_venv_dirs: Whether to exclude venv directories.
46
- upload_db_file: Whether to include local sqlite db files.
47
- dirs_to_exclude: The directories to exclude.
44
+ root_directory: The root directory to zip.
45
+ exclude_venv_directories: Whether to exclude venv directories.
46
+ include_db_file: Whether to include local sqlite db files.
47
+ directory_names_to_exclude: The directory names to exclude.
48
48
  files_to_exclude: The files to exclude.
49
- top_level_dirs_to_exclude: The top level directory names immediately under root_dir to exclude. Do not exclude folders by these names further in the sub-directories.
50
- globs_to_include: Apply these globs from the root_dir and always include them in the zip.
49
+ globs_to_include: Apply these globs from the root_directory and always include them in the zip.
51
50
 
52
51
  """
53
52
  target = Path(target)
54
- root_dir = Path(root_dir)
55
- dirs_to_exclude = dirs_to_exclude or set()
53
+ root_directory = Path(root_directory).resolve()
54
+ directory_names_to_exclude = directory_names_to_exclude or set()
56
55
  files_to_exclude = files_to_exclude or set()
57
- files_to_zip: list[str] = []
56
+ files_to_zip: list[Path] = []
58
57
  # Traverse the root directory in a top-down manner. In this traversal order,
59
58
  # we can modify the dirs list in-place to remove directories we don't want to include.
60
- for root, dirs, files in os.walk(root_dir, topdown=True, followlinks=True):
61
- root = Path(root)
59
+ for directory_path, subdirectories_names, subfiles_names in os.walk(
60
+ root_directory, topdown=True, followlinks=True
61
+ ):
62
+ directory_path = Path(directory_path).resolve()
62
63
  # Modify the dirs in-place so excluded and hidden directories are skipped in next traversal.
63
- dirs[:] = [
64
- d
65
- for d in dirs
66
- if (basename := Path(d).resolve().name) not in dirs_to_exclude
67
- and not basename.startswith(".")
68
- and (not exclude_venv_dirs or not _looks_like_venv_dir(root / d))
64
+ subdirectories_names[:] = [
65
+ subdirectory_name
66
+ for subdirectory_name in subdirectories_names
67
+ if subdirectory_name not in directory_names_to_exclude
68
+ and not any(
69
+ (directory_path / subdirectory_name).samefile(exclude)
70
+ for exclude in files_to_exclude
71
+ if exclude.exists()
72
+ )
73
+ and not subdirectory_name.startswith(".")
74
+ and (
75
+ not exclude_venv_directories
76
+ or not _looks_like_venv_directory(directory_path / subdirectory_name)
77
+ )
69
78
  ]
70
- # If we are at the top level with root_dir, exclude the top level dirs.
71
- if top_level_dirs_to_exclude and root == root_dir:
72
- dirs[:] = [d for d in dirs if d not in top_level_dirs_to_exclude]
73
79
  # Modify the files in-place so the hidden files and db files are excluded.
74
- files[:] = [
75
- f
76
- for f in files
77
- if not f.startswith(".") and (upload_db_file or not f.endswith(".db"))
80
+ subfiles_names[:] = [
81
+ subfile_name
82
+ for subfile_name in subfiles_names
83
+ if not subfile_name.startswith(".")
84
+ and (include_db_file or not subfile_name.endswith(".db"))
78
85
  ]
79
86
  files_to_zip += [
80
- str(root / file) for file in files if file not in files_to_exclude
87
+ directory_path / subfile_name
88
+ for subfile_name in subfiles_names
89
+ if not any(
90
+ (directory_path / subfile_name).samefile(excluded_file)
91
+ for excluded_file in files_to_exclude
92
+ if excluded_file.exists()
93
+ )
81
94
  ]
82
95
  if globs_to_include:
83
96
  for glob in globs_to_include:
84
97
  files_to_zip += [
85
- str(file)
86
- for file in root_dir.glob(glob)
98
+ file
99
+ for file in root_directory.glob(glob)
87
100
  if file.name not in files_to_exclude
88
101
  ]
89
102
  # Create a progress bar for zipping the component.
@@ -100,14 +113,15 @@ def _zip(
100
113
  for file in files_to_zip:
101
114
  console.debug(f"{target}: {file}", progress=progress)
102
115
  progress.advance(task)
103
- zipf.write(file, Path(file).relative_to(root_dir))
116
+ zipf.write(file, Path(file).relative_to(root_directory))
104
117
 
105
118
 
106
119
  def zip_app(
107
120
  frontend: bool = True,
108
121
  backend: bool = True,
109
122
  zip_dest_dir: str | Path | None = None,
110
- upload_db_file: bool = False,
123
+ include_db_file: bool = False,
124
+ backend_excluded_dirs: tuple[Path, ...] = (),
111
125
  ):
112
126
  """Zip up the app.
113
127
 
@@ -115,41 +129,41 @@ def zip_app(
115
129
  frontend: Whether to zip up the frontend app.
116
130
  backend: Whether to zip up the backend app.
117
131
  zip_dest_dir: The directory to export the zip file to.
118
- upload_db_file: Whether to upload the database file.
132
+ include_db_file: Whether to include the database file.
133
+ backend_excluded_dirs: A tuple of files or directories to exclude from the backend zip. Defaults to ().
119
134
  """
120
135
  zip_dest_dir = zip_dest_dir or Path.cwd()
121
136
  zip_dest_dir = Path(zip_dest_dir)
122
137
  files_to_exclude = {
123
- constants.ComponentName.FRONTEND.zip(),
124
- constants.ComponentName.BACKEND.zip(),
138
+ Path(constants.ComponentName.FRONTEND.zip()).resolve(),
139
+ Path(constants.ComponentName.BACKEND.zip()).resolve(),
125
140
  }
126
141
 
127
142
  if frontend:
128
143
  _zip(
129
144
  component_name=constants.ComponentName.FRONTEND,
130
145
  target=zip_dest_dir / constants.ComponentName.FRONTEND.zip(),
131
- root_dir=prerequisites.get_web_dir() / constants.Dirs.STATIC,
146
+ root_directory=prerequisites.get_web_dir() / constants.Dirs.STATIC,
132
147
  files_to_exclude=files_to_exclude,
133
- exclude_venv_dirs=False,
148
+ exclude_venv_directories=False,
134
149
  )
135
150
 
136
151
  if backend:
137
152
  _zip(
138
153
  component_name=constants.ComponentName.BACKEND,
139
154
  target=zip_dest_dir / constants.ComponentName.BACKEND.zip(),
140
- root_dir=Path.cwd(),
141
- dirs_to_exclude={"__pycache__"},
142
- files_to_exclude=files_to_exclude,
143
- top_level_dirs_to_exclude={"assets"},
144
- exclude_venv_dirs=True,
145
- upload_db_file=upload_db_file,
155
+ root_directory=Path.cwd(),
156
+ directory_names_to_exclude={"__pycache__"},
157
+ files_to_exclude=files_to_exclude | set(backend_excluded_dirs),
158
+ exclude_venv_directories=True,
159
+ include_db_file=include_db_file,
146
160
  globs_to_include=[
147
161
  str(Path(constants.Dirs.WEB) / constants.Dirs.BACKEND / "*")
148
162
  ],
149
163
  )
150
164
 
151
165
 
152
- def _duplicate_index_html_to_parent_dir(directory: Path):
166
+ def _duplicate_index_html_to_parent_directory(directory: Path):
153
167
  """Duplicate index.html in the child directories to the given directory.
154
168
 
155
169
  This makes accessing /route and /route/ work in production.
@@ -169,7 +183,7 @@ def _duplicate_index_html_to_parent_dir(directory: Path):
169
183
  else:
170
184
  console.debug(f"Skipping {index_html}, already exists at {target}")
171
185
  # Recursively call this function for the child directory.
172
- _duplicate_index_html_to_parent_dir(child)
186
+ _duplicate_index_html_to_parent_directory(child)
173
187
 
174
188
 
175
189
  def build():
@@ -200,7 +214,7 @@ def build():
200
214
  },
201
215
  )
202
216
  processes.show_progress("Creating Production Build", process, checkpoints)
203
- _duplicate_index_html_to_parent_dir(wdir / constants.Dirs.STATIC)
217
+ _duplicate_index_html_to_parent_directory(wdir / constants.Dirs.STATIC)
204
218
  path_ops.cp(
205
219
  wdir / constants.Dirs.STATIC / constants.ReactRouter.SPA_FALLBACK,
206
220
  wdir / constants.Dirs.STATIC / "404.html",
@@ -247,6 +261,6 @@ def setup_frontend_prod(
247
261
  build()
248
262
 
249
263
 
250
- def _looks_like_venv_dir(dir_to_check: str | Path) -> bool:
251
- dir_to_check = Path(dir_to_check)
252
- return (dir_to_check / "pyvenv.cfg").exists()
264
+ def _looks_like_venv_directory(directory_to_check: str | Path) -> bool:
265
+ directory_to_check = Path(directory_to_check)
266
+ return (directory_to_check / "pyvenv.cfg").exists()
reflex/utils/console.py CHANGED
@@ -22,6 +22,7 @@ from reflex.utils.decorator import once
22
22
 
23
23
  # Console for pretty printing.
24
24
  _console = Console()
25
+ _console_stderr = Console(stderr=True)
25
26
 
26
27
  # The current log level.
27
28
  _LOG_LEVEL = LogLevel.INFO
@@ -96,6 +97,21 @@ def print(msg: str, *, dedupe: bool = False, **kwargs):
96
97
  _console.print(msg, **kwargs)
97
98
 
98
99
 
100
+ def _print_stderr(msg: str, *, dedupe: bool = False, **kwargs):
101
+ """Print a message to stderr.
102
+
103
+ Args:
104
+ msg: The message to print.
105
+ dedupe: If True, suppress multiple console logs of print message.
106
+ kwargs: Keyword arguments to pass to the print function.
107
+ """
108
+ if dedupe:
109
+ if msg in _EMITTED_PRINTS:
110
+ return
111
+ _EMITTED_PRINTS.add(msg)
112
+ _console_stderr.print(msg, **kwargs)
113
+
114
+
99
115
  @once
100
116
  def log_file_console():
101
117
  """Create a console that logs to a file.
@@ -342,7 +358,7 @@ def error(msg: str, *, dedupe: bool = False, **kwargs):
342
358
  if msg in _EMITTED_ERRORS:
343
359
  return
344
360
  _EMITTED_ERRORS.add(msg)
345
- print(f"[red]{msg}[/red]", **kwargs)
361
+ _print_stderr(f"[red]{msg}[/red]", **kwargs)
346
362
  if should_use_log_file_console():
347
363
  print_to_log_file(f"[red]{msg}[/red]", **kwargs)
348
364
 
reflex/utils/exec.py CHANGED
@@ -497,6 +497,7 @@ HOTRELOAD_IGNORE_EXTENSIONS = (
497
497
  "sh",
498
498
  "bash",
499
499
  "log",
500
+ "db",
500
501
  )
501
502
 
502
503
  HOTRELOAD_IGNORE_PATTERNS = (
@@ -524,7 +525,7 @@ def run_granian_backend(host: str, port: int, loglevel: LogLevel):
524
525
  from granian.log import LogLevels
525
526
  from granian.server import Server as Granian
526
527
 
527
- from reflex.environment import _paths_from_environment
528
+ from reflex.environment import _load_dotenv_from_env
528
529
 
529
530
  granian_app = Granian(
530
531
  target=get_app_instance_from_file(),
@@ -538,10 +539,11 @@ def run_granian_backend(host: str, port: int, loglevel: LogLevel):
538
539
  reload_ignore_worker_failure=True,
539
540
  reload_ignore_patterns=HOTRELOAD_IGNORE_PATTERNS,
540
541
  reload_tick=100,
541
- env_files=_paths_from_environment() or None,
542
542
  workers_kill_timeout=2,
543
543
  )
544
544
 
545
+ granian_app.on_reload(_load_dotenv_from_env)
546
+
545
547
  granian_app.serve()
546
548
 
547
549
 
reflex/utils/export.py CHANGED
@@ -18,6 +18,7 @@ def export(
18
18
  deploy_url: str | None = None,
19
19
  env: constants.Env = constants.Env.PROD,
20
20
  loglevel: constants.LogLevel = console._LOG_LEVEL,
21
+ backend_excluded_dirs: tuple[Path, ...] = (),
21
22
  ):
22
23
  """Export the app to a zip file.
23
24
 
@@ -31,6 +32,7 @@ def export(
31
32
  deploy_url: The deploy URL to use. Defaults to None.
32
33
  env: The environment to use. Defaults to constants.Env.PROD.
33
34
  loglevel: The log level to use. Defaults to console._LOG_LEVEL.
35
+ backend_excluded_dirs: A tuple of files or directories to exclude from the backend zip. Defaults to ().
34
36
  """
35
37
  config = get_config()
36
38
 
@@ -70,7 +72,8 @@ def export(
70
72
  frontend=frontend,
71
73
  backend=backend,
72
74
  zip_dest_dir=zip_dest_dir,
73
- upload_db_file=upload_db_file,
75
+ include_db_file=upload_db_file,
76
+ backend_excluded_dirs=backend_excluded_dirs,
74
77
  )
75
78
 
76
79
  # Post a telemetry event.
@@ -66,6 +66,16 @@ class TokenManager(ABC):
66
66
 
67
67
  return LocalTokenManager()
68
68
 
69
+ async def disconnect_all(self):
70
+ """Disconnect all tracked tokens when the server is going down."""
71
+ token_sid_pairs: set[tuple[str, str]] = set(self.token_to_sid.items())
72
+ token_sid_pairs.update(
73
+ ((token, sid) for sid, token in self.sid_to_token.items())
74
+ )
75
+ # Perform the disconnection logic here
76
+ for token, sid in token_sid_pairs:
77
+ await self.disconnect_token(token, sid)
78
+
69
79
 
70
80
  class LocalTokenManager(TokenManager):
71
81
  """Token manager using local in-memory dictionaries (single worker)."""
reflex/utils/types.py CHANGED
@@ -6,6 +6,7 @@ import dataclasses
6
6
  import sys
7
7
  import types
8
8
  from collections.abc import Callable, Iterable, Mapping, Sequence
9
+ from enum import Enum
9
10
  from functools import cached_property, lru_cache
10
11
  from types import GenericAlias
11
12
  from typing import ( # noqa: UP035
@@ -1241,6 +1242,7 @@ IMMUTABLE_TYPES = (
1241
1242
  frozenset,
1242
1243
  tuple,
1243
1244
  type(None),
1245
+ Enum,
1244
1246
  )
1245
1247
 
1246
1248
 
reflex/vars/base.py CHANGED
@@ -2345,7 +2345,7 @@ class ComputedVar(Var[RETURN_TYPE]):
2345
2345
  def _check_deprecated_return_type(self, instance: BaseState, value: Any) -> None:
2346
2346
  if not _isinstance(value, self._var_type, nested=1, treat_var_as_type=False):
2347
2347
  console.error(
2348
- f"Computed var '{type(instance).__name__}.{self._js_expr}' must return"
2348
+ f"Computed var '{type(instance).__name__}.{self._name}' must return"
2349
2349
  f" a value of type '{escape(str(self._var_type))}', got '{value!s}' of type {type(value)}."
2350
2350
  )
2351
2351
 
@@ -2395,7 +2395,7 @@ class ComputedVar(Var[RETURN_TYPE]):
2395
2395
  except Exception as e:
2396
2396
  console.warn(
2397
2397
  "Failed to automatically determine dependencies for computed var "
2398
- f"{objclass.__name__}.{self._js_expr}: {e}. "
2398
+ f"{objclass.__name__}.{self._name}: {e}. "
2399
2399
  "Provide static_deps and set auto_deps=False to suppress this warning."
2400
2400
  )
2401
2401
  return d
reflex/vars/object.py CHANGED
@@ -479,14 +479,9 @@ def object_keys_operation(value: ObjectVar):
479
479
  Returns:
480
480
  The keys of the object.
481
481
  """
482
- if not types.is_optional(value._var_type):
483
- return var_operation_return(
484
- js_expression=f"Object.keys({value})",
485
- var_type=list[str],
486
- )
487
482
  return var_operation_return(
488
- js_expression=f"((value) => value ?? undefined === undefined ? undefined : Object.keys(value))({value})",
489
- var_type=(list[str] | None),
483
+ js_expression=f"Object.keys({value} ?? {{}})",
484
+ var_type=list[str],
490
485
  )
491
486
 
492
487
 
@@ -500,14 +495,9 @@ def object_values_operation(value: ObjectVar):
500
495
  Returns:
501
496
  The values of the object.
502
497
  """
503
- if not types.is_optional(value._var_type):
504
- return var_operation_return(
505
- js_expression=f"Object.values({value})",
506
- var_type=list[value._value_type()],
507
- )
508
498
  return var_operation_return(
509
- js_expression=f"((value) => value ?? undefined === undefined ? undefined : Object.values(value))({value})",
510
- var_type=(list[value._value_type()] | None),
499
+ js_expression=f"Object.values({value} ?? {{}})",
500
+ var_type=list[value._value_type()],
511
501
  )
512
502
 
513
503
 
@@ -521,14 +511,9 @@ def object_entries_operation(value: ObjectVar):
521
511
  Returns:
522
512
  The entries of the object.
523
513
  """
524
- if not types.is_optional(value._var_type):
525
- return var_operation_return(
526
- js_expression=f"Object.entries({value})",
527
- var_type=list[tuple[str, value._value_type()]],
528
- )
529
514
  return var_operation_return(
530
- js_expression=f"((value) => value ?? undefined === undefined ? undefined : Object.entries(value))({value})",
531
- var_type=(list[tuple[str, value._value_type()]] | None),
515
+ js_expression=f"Object.entries({value} ?? {{}})",
516
+ var_type=list[tuple[str, value._value_type()]],
532
517
  )
533
518
 
534
519
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: reflex
3
- Version: 0.8.11a1
3
+ Version: 0.8.12a2
4
4
  Summary: Web apps in pure Python.
5
5
  Project-URL: homepage, https://reflex.dev
6
6
  Project-URL: repository, https://github.com/reflex-dev/reflex
@@ -2,20 +2,20 @@ reflex/__init__.py,sha256=_1PVYjDeA6_JyfXvL6OuKjjO6AX2oMiNcAq8AEHf6xw,10161
2
2
  reflex/__init__.pyi,sha256=0D46kHVUJPE_kgYL-BjraERu-MXNCPsQTZQShrijmeQ,10148
3
3
  reflex/__main__.py,sha256=6cVrGEyT3j3tEvlEVUatpaYfbB5EF3UVY-6vc_Z7-hw,108
4
4
  reflex/admin.py,sha256=Nbc38y-M8iaRBvh1W6DQu_D3kEhO8JFvxrog4q2cB_E,434
5
- reflex/app.py,sha256=6twI1PM0obKXFylomi-AXqr1zdaK9aZzYH3yh6zO2M8,78122
5
+ reflex/app.py,sha256=LCIj6hU3AbJJpVipG3AIBJfNK1eKGjn_SRTtg5MH2vw,78526
6
6
  reflex/assets.py,sha256=l5O_mlrTprC0lF7Rc_McOe3a0OtSLnRdNl_PqCpDCBA,3431
7
7
  reflex/base.py,sha256=Oh664QL3fZEHErhUasFqP7fE4olYf1y-9Oj6uZI2FCU,1173
8
8
  reflex/config.py,sha256=LsHAtdH4nkSn3q_Ie-KNdOGdflLXrFICUQov29oFjVk,21229
9
9
  reflex/environment.py,sha256=BRIePrhFKTZajYlyl-KhjGsqR4_hc7KxfNCoape6Jjw,23590
10
- reflex/event.py,sha256=C4b_gj8FLQx5HKWp_G5nFsCO-H0z08tx_LYc-e3vwlo,76239
10
+ reflex/event.py,sha256=e2EIBmLF63KRw4GXSbuiQ6yDp1-YQHHIxJKenTra9vk,76223
11
11
  reflex/model.py,sha256=2QhU1TJlcDeRA23pv8usLjyDaA6FhbQRYdzsjOHzvUI,19665
12
12
  reflex/page.py,sha256=ssCbMVFuIy60vH-YhJUzN0OxzUwXFCCD3ej56dVjp3g,3525
13
13
  reflex/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
- reflex/reflex.py,sha256=qKpWvXuA55y519MWckr6oxKSf3pCQfRCrvzsyXSuAqk,22729
14
+ reflex/reflex.py,sha256=5R-NYJCrlmZoOdIGnO1NyBdNLQjfpqiJNaPuLXaxvzY,23459
15
15
  reflex/route.py,sha256=TnS4m6Hm-b3LfGFpm37iAMEd-_JISAouPW5FqUxTAfU,7858
16
- reflex/state.py,sha256=gqQNmLGdrG9sxivfbyE1bHrLSlYZarbQCt6PtPaWO2w,94991
17
- reflex/style.py,sha256=JxbXXA4MTnXrk0XHEoMBoNC7J-M2oL5Hl3W_QmXvmBg,13222
18
- reflex/testing.py,sha256=wLhvUdvTa6jPDkfdWLOYt69piX1KFhYxZfEjQzWfJo0,39902
16
+ reflex/state.py,sha256=wQ4ozzgeTQHVeX4-zHhQfyHHDaykHdka6B5xGvo-5UQ,95000
17
+ reflex/style.py,sha256=Jc7hZyH9CSFDbweoRCrkVtSu8tZq5aIggSoAYAh-w1M,13304
18
+ reflex/testing.py,sha256=Wt1qdmqT3Yo9CKWZzHXiytizZJ5KjqxVzuoGPjI_Vfk,40458
19
19
  reflex/.templates/apps/blank/assets/favicon.ico,sha256=baxxgDAQ2V4-G5Q4S2yK5uUJTUGkv-AOWBQ0xd6myUo,4286
20
20
  reflex/.templates/apps/blank/code/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
21
21
  reflex/.templates/apps/blank/code/blank.py,sha256=wry9E3VjC7qtt_gzqNOyo4KZAAlzVyNp3uhFkcLZmM0,898
@@ -30,7 +30,7 @@ reflex/.templates/web/components/reflex/radix_themes_color_mode_provider.js,sha2
30
30
  reflex/.templates/web/components/shiki/code.js,sha256=4Es1pxsr-lX4hTQ5mglrwwC6O_SI-z-O60k03z8VFzQ,1144
31
31
  reflex/.templates/web/styles/__reflex_style_reset.css,sha256=qbC6JIT643YEsvSQ0D7xBmWE5vXy94JGrKNihRuEjnA,8913
32
32
  reflex/.templates/web/utils/react-theme.js,sha256=Aa-RND3ooGCXW6Zavzitc-v0ciKlcQDTFlDtE4mPkFI,2713
33
- reflex/.templates/web/utils/state.js,sha256=sf8v15y5FXGeuQg1spDRe88pl3Kdv7n4_338tqu_xkY,31894
33
+ reflex/.templates/web/utils/state.js,sha256=RdNHwQzS_iP0Z_fx-H4pjVjl-qUoz31JLvwPwcp0F-s,33046
34
34
  reflex/.templates/web/utils/helpers/dataeditor.js,sha256=pG6MgsHuStDR7-qPipzfiK32j9bKDBa-4hZ0JSUo4JM,1623
35
35
  reflex/.templates/web/utils/helpers/debounce.js,sha256=xGhtTRtS_xIcaeqnYVvYJNseLgQVk-DW-eFiHJYO9As,528
36
36
  reflex/.templates/web/utils/helpers/paste.js,sha256=ef30HsR83jRzzvZnl8yV79yqFP8TC_u8SlN99cCS_OM,1799
@@ -38,12 +38,12 @@ reflex/.templates/web/utils/helpers/range.js,sha256=Bjr7Ex1Mghpsopjfrcp__IVFw8F8
38
38
  reflex/.templates/web/utils/helpers/throttle.js,sha256=qxeyaEojaTeX36FPGftzVWrzDsRQU4iqg3U9RJz9Vj4,566
39
39
  reflex/.templates/web/utils/helpers/upload.js,sha256=YiAv-KC-LijTsEmzG_o6YxUprgSN7Pbyd__xu8HTX6s,4814
40
40
  reflex/app_mixins/__init__.py,sha256=Oegz3-gZLP9p2OAN5ALNbsgxuNQfS6lGZgQA8cc-9mQ,137
41
- reflex/app_mixins/lifespan.py,sha256=a156ZUYVo2bN1Tv-4WmWSjojo90PP_2-V12BX0q8YNw,3543
41
+ reflex/app_mixins/lifespan.py,sha256=_JMloSOpmpPpAPpVMYO42LW3-6DxPbx0fcRsC2VVyM8,4028
42
42
  reflex/app_mixins/middleware.py,sha256=BKhe0jUFO1_TylEC48LUZyaeYyPmAYW-NV4H5Rw221k,2848
43
43
  reflex/app_mixins/mixin.py,sha256=R1YncalqDrbdPZvpKVbm72ZKmQZxYAWfuFq9JknzTqQ,305
44
44
  reflex/compiler/__init__.py,sha256=r8jqmDSFf09iV2lHlNhfc9XrTLjNxfDNwPYlxS4cmHE,27
45
- reflex/compiler/compiler.py,sha256=rE0aMl_xwq-qvPd6fgvUV_F4qaMiNKo_82LfCKbX258,29114
46
- reflex/compiler/templates.py,sha256=k4Z-vftCk1W_dBweQtHt7UExPkS-jgaBhUtbMhzg02w,20518
45
+ reflex/compiler/compiler.py,sha256=-MnavauFrb9xmePf0VsFB0vLlE6Nr5zY8x7kne2Uzvg,29156
46
+ reflex/compiler/templates.py,sha256=ucfkEMOGA49ceUnL1KXDP_oHKxPrELSKWtRgtXUVHjk,20547
47
47
  reflex/compiler/utils.py,sha256=RmeUoZMHdIfnqPl-p0ToPgwd0FEFO5u0Xbb-J20UYdQ,19621
48
48
  reflex/components/__init__.py,sha256=eWpgWFbSQDj2TpGp6StEbxU7roQgzY7ZM0XIcIc5RE8,588
49
49
  reflex/components/__init__.pyi,sha256=7VFHtJGIjvGtD3IiPk848IPWYSCcPRT1EyPGljLhYlU,736
@@ -95,7 +95,7 @@ reflex/components/core/match.py,sha256=xBB9vtWgVlotPHq6ssng8lzxwXDDQLp9k6Ew5RPPd
95
95
  reflex/components/core/responsive.py,sha256=ACZdtJ4a4F8B3dm1k8h6J2_UJx0Z5LDB7XHQ2ty4wAc,1911
96
96
  reflex/components/core/sticky.py,sha256=2B3TxrwG2Rtp_lv1VkMOIF2bqSiT7qYGbqbiZiMKxKY,3856
97
97
  reflex/components/core/sticky.pyi,sha256=5D-yT0LYs0ewOlUlInU7KCpuz49yKK7dirysUs1C2VI,32908
98
- reflex/components/core/upload.py,sha256=OEjXq4O06YSoRlJvYs-hyFJgo7GzQJByO9RqPI1RUzc,13585
98
+ reflex/components/core/upload.py,sha256=V0vIYig6XoOstQY2KDH88OYmLYPuSzkQopEYm3GZ81E,15195
99
99
  reflex/components/core/upload.pyi,sha256=UqfcPGUs8xmnKHKuvqYV7CtOXeF_D1s9ooRe49w6C3E,15757
100
100
  reflex/components/core/window_events.py,sha256=opbuO20zVxt252kQLk49V7cltb_Um2oh7iePeGNJ538,3355
101
101
  reflex/components/core/window_events.pyi,sha256=aTkBiAy-e9LqkQm6_apRsXXfJRdawA11cE1tQQSIy3c,3206
@@ -139,8 +139,8 @@ reflex/components/gridjs/__init__.py,sha256=xJwDm1AZ70L5-t9LLqZwGUtDpijbf1KuMYDT
139
139
  reflex/components/gridjs/datatable.py,sha256=7JKrRw1zkpFB0_wwoaIhrVrldsm7-dyi3PASgqLq8Hc,4224
140
140
  reflex/components/gridjs/datatable.pyi,sha256=kFgv82vCgfdWZaUq4bZ73G8X3mkw6ecvSRkZ9G9-28E,5185
141
141
  reflex/components/lucide/__init__.py,sha256=EggTK2MuQKQeOBLKW-mF0VaDK9zdWBImu1HO2dvHZbE,73
142
- reflex/components/lucide/icon.py,sha256=GYF1VPrKjXU8RQxBe0CZaM209Br6uw1Z2sc79bvdj3U,35340
143
- reflex/components/lucide/icon.pyi,sha256=MjWdRIf7t5hcWoUaxor5Lzh4yuWcES75cEUjLOXvmP8,38134
142
+ reflex/components/lucide/icon.py,sha256=oyTpIx5bJ-7D3VrXMrMpZ4aIKnv1GADBM97eSROnzZU,35358
143
+ reflex/components/lucide/icon.pyi,sha256=BAVUCJYalfn0nBpwglPiJNO_EfRdzM2eWHtaBy2Fa-o,38152
144
144
  reflex/components/markdown/__init__.py,sha256=Dfl1At5uYoY7H4ufZU_RY2KOGQDLtj75dsZ2BTqqAns,87
145
145
  reflex/components/markdown/markdown.py,sha256=kzvO2VnfCbxV7AcIMBJbxLtAlQ6U5T_QB_JTh8l-HJ4,15450
146
146
  reflex/components/markdown/markdown.pyi,sha256=oOlXZItHB0TPWsFz1Qjvr3KzG8sssthBp40UO_KkRIA,4322
@@ -317,7 +317,7 @@ reflex/constants/compiler.py,sha256=1FXPYQNotaSrTwWcOspA1gCVmEdoiWkNMbbrz_qU0YU,
317
317
  reflex/constants/config.py,sha256=8OIjiBdZZJrRVHsNBheMwopE9AwBFFzau0SXqXKcrPg,1715
318
318
  reflex/constants/custom_components.py,sha256=joJt4CEt1yKy7wsBH6vYo7_QRW0O_fWXrrTf0VY2q14,1317
319
319
  reflex/constants/event.py,sha256=tgoynWQi2L0_Kqc3XhXo7XXL76A-OKhJGHRrNjm7gFw,2885
320
- reflex/constants/installer.py,sha256=VC20iXTYue0GXqwlJIAwDuFrNM-eSzhHs3CsM_KQMwA,4191
320
+ reflex/constants/installer.py,sha256=gFX2gdhtm_frfs0cHxfEqSZbeokYaeBRJhSJOrxLmto,4191
321
321
  reflex/constants/route.py,sha256=UBjqaAOxiUxlDZCSY4O2JJChKvA4MZrhUU0E5rNvKbM,2682
322
322
  reflex/constants/state.py,sha256=VrEeYxXfE9ss8RmOHIXD4T6EGsV9PDqbtMCQMmZxW3I,383
323
323
  reflex/constants/utils.py,sha256=e1ChEvbHfmE_V2UJvCSUhD_qTVAIhEGPpRJSqdSd6PA,780
@@ -329,8 +329,8 @@ reflex/experimental/hooks.py,sha256=CHYGrAE5t8riltrJmDFgJ4D2Vhmhw-y3B3MSGNlOQow,
329
329
  reflex/istate/__init__.py,sha256=afq_pCS5B_REC-Kl3Rbaa538uWi59xNz4INeuENcWnk,2039
330
330
  reflex/istate/data.py,sha256=8RydiarP7f5ET5a3dfGpuuXdYZ7KHEWS6aENVoxRxGc,7918
331
331
  reflex/istate/dynamic.py,sha256=xOQ9upZVPf6ngqcLQZ9HdAAYmoWwJ8kRFPH34Q5HTiM,91
332
- reflex/istate/manager.py,sha256=xQhvpTqnsVI5DmnZOq39IiQ-g1d-gtihQdEGKKM6-oQ,30531
333
- reflex/istate/proxy.py,sha256=Q8JrV1m6drVcTNJL9JuN-nKUXclazs96OHl_fhR0UBk,25928
332
+ reflex/istate/manager.py,sha256=WyBBhDuq3cVuno3H-axeT8sqF0EqHR3MNZJw-B76cZs,30517
333
+ reflex/istate/proxy.py,sha256=4SE3-W6OpHA51JlLdz5Kbslpusp5xOUQI91nmzpH8Xo,25825
334
334
  reflex/istate/storage.py,sha256=gCPoiZxuG-Rw0y-Pz3OC7rv4o08dQ_jK1fE2u8Jhxqg,4339
335
335
  reflex/istate/wrappers.py,sha256=p8uuioXRbR5hperwbOJHUcWdu7hukLikQdoR7qrnKsI,909
336
336
  reflex/middleware/__init__.py,sha256=x7xTeDuc73Hjj43k1J63naC9x8vzFxl4sq7cCFBX7sk,111
@@ -344,14 +344,14 @@ reflex/plugins/sitemap.py,sha256=X_CtH5B1w3CZno-gdPj1rp63WjOuNjFnX4B3fx_-VFQ,613
344
344
  reflex/plugins/tailwind_v3.py,sha256=jCEZ5UYdr706Mw48L-WSHOUB6O55o1C3uG6AMwXqZoI,4810
345
345
  reflex/plugins/tailwind_v4.py,sha256=fcNaFtikSIu1LhF94DcBs1xR2CjbQRB5o1_KYeThUF0,5230
346
346
  reflex/utils/__init__.py,sha256=y-AHKiRQAhk2oAkvn7W8cRVTZVK625ff8tTwvZtO7S4,24
347
- reflex/utils/build.py,sha256=GLT2ycqgAe1cw__MFbfdlYrkzcTnY1oJ8cAv80jEcnQ,8641
347
+ reflex/utils/build.py,sha256=wwpG1K5WZGbMSsX9iF8hA5kJCbawtJizRlkotgovzQs,9287
348
348
  reflex/utils/codespaces.py,sha256=kEQ-j-jclTukFpXDlYgNp95kYMGDrQmP3VNEoYGZ1u4,3052
349
349
  reflex/utils/compat.py,sha256=aSJH_M6iomgHPQ4onQ153xh1MWqPi3HSYDzE68N6gZM,2635
350
- reflex/utils/console.py,sha256=RkTNfOVozsuGmq9GFSUDzBvL80twBYLRIcOxh0zK-q0,13185
350
+ reflex/utils/console.py,sha256=W41Ogj1Jk8tEOhXXy9dy4KCLYp5rn0NZQwbBqXbkwSI,13668
351
351
  reflex/utils/decorator.py,sha256=QUZntENupeW5FA5mNRTx0I1GzGKFQXhMjVg24_IIM5o,3957
352
352
  reflex/utils/exceptions.py,sha256=Wwu7Ji2xgq521bJKtU2NgjwhmFfnG8erirEVN2h8S-g,8884
353
- reflex/utils/exec.py,sha256=o0u81B6pHv5Yt982V1vFYEJDxgM-HxmM5KRUBbTYmZI,21965
354
- reflex/utils/export.py,sha256=Z2AHuhkxGQzOi9I90BejQ4qEcD0URr2i-ZU5qTJt7eQ,2562
353
+ reflex/utils/exec.py,sha256=RsUpJsXLoQKMF4tMWPKP2xjvKcDP1OyNXU0gC__7RSU,21970
354
+ reflex/utils/export.py,sha256=jQvOP09LVlCpznsOWqZ9AQzBHwyhZPcDqZ5iuAvrVNM,2783
355
355
  reflex/utils/format.py,sha256=-EC0tfx7VCIijcuJx9l-ArRnRnPKrrrW8RgsKwXIoBc,21115
356
356
  reflex/utils/frontend_skeleton.py,sha256=8sXRmVsKUiWf6O5rA1RRR_E4YjEsqDdIQlkUByp3aOI,8774
357
357
  reflex/utils/imports.py,sha256=SlQfMTbJasXHxrpcHdWKPWiIZ1Kn2-tulMF32_YA2ek,4262
@@ -370,19 +370,19 @@ reflex/utils/rename.py,sha256=qdE4SXHOaNs-TDGrnJz-h_nvLWA1C5osVrWb4wLSfyI,5262
370
370
  reflex/utils/serializers.py,sha256=ZqQ2xrBIyOXaN0RIRZwy2oU5O0Y1R0SEGWx-kf5rXMs,13938
371
371
  reflex/utils/telemetry.py,sha256=KY54NmGWyJVSf9TMTcXw2V6gIbEqut1JkAXmmtIlRfw,10776
372
372
  reflex/utils/templates.py,sha256=tWo3jO6laQX8b0gUsqHkio_hUQGIvFbmXC-lxiGcdRo,14251
373
- reflex/utils/token_manager.py,sha256=o_HGbqT9WfYRmek2iY9nem4vDZMz8Q4Dra-eW1lKmuA,6999
374
- reflex/utils/types.py,sha256=Xh9jXSMBgwrR-Whn_5qAnjqQWzHiIJbm1b8qwMG4QmY,38511
373
+ reflex/utils/token_manager.py,sha256=ZtrYR0X8tTs8FpQHtMb09-H2V1xSoLWwVH8jW8OCrU8,7445
374
+ reflex/utils/types.py,sha256=v2shXUDPqsgrxXDwrP9JYYgSTwZht0YjAo5c1mDDI8M,38543
375
375
  reflex/vars/__init__.py,sha256=85eXMt32bFoKtMdH3KxYRMD8mtnKyYiQcThPxJLoW1k,1359
376
- reflex/vars/base.py,sha256=CJT6SVtFDcBBpOtLw6jtszgZYifqeS3UJVsZ5y-BJQQ,113350
376
+ reflex/vars/base.py,sha256=LKnjDvg7_XKzPZlDD9WfYbWzyMoSjiZ7Bdt4sICjW60,113344
377
377
  reflex/vars/datetime.py,sha256=F2Jv_bfydipFSkIQ1F6x5MnSgFEyES9Vq5RG_uGH81E,5118
378
378
  reflex/vars/dep_tracking.py,sha256=LfDGgAGlqfC0DeiVcitRBcA1uCe1C3fNRARRekLgCz4,13738
379
379
  reflex/vars/function.py,sha256=0i-VkxHkDJmZtfQUwUfaF0rlS6WM8azjwQ8k7rEOkyk,13944
380
380
  reflex/vars/number.py,sha256=tO7pnvFaBsedq1HWT4skytnSqHWMluGEhUbjAUMx8XQ,28190
381
- reflex/vars/object.py,sha256=YblDxQYMajR19a7qjavXcM7-9A6MweAH1giw5fjPci4,17349
381
+ reflex/vars/object.py,sha256=p7dyn9rD6rVJlHQ_RcDTBgsU_AlbwYklGjx1HK3XxZg,16565
382
382
  reflex/vars/sequence.py,sha256=1kBrqihspyjyQ1XDqFPC8OpVGtZs_EVkOdIKBro5ilA,55249
383
383
  scripts/hatch_build.py,sha256=-4pxcLSFmirmujGpQX9UUxjhIC03tQ_fIQwVbHu9kc0,1861
384
- reflex-0.8.11a1.dist-info/METADATA,sha256=TU38HCaA1xc0QEXBM-FsqYvAvYtoVNDPbuI6J6GLTf0,12336
385
- reflex-0.8.11a1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
386
- reflex-0.8.11a1.dist-info/entry_points.txt,sha256=Rxt4dXc7MLBNt5CSHTehVPuSe9Xqow4HLX55nD9tQQ0,45
387
- reflex-0.8.11a1.dist-info/licenses/LICENSE,sha256=dw3zLrp9f5ObD7kqS32vWfhcImfO52PMmRqvtxq_YEE,11358
388
- reflex-0.8.11a1.dist-info/RECORD,,
384
+ reflex-0.8.12a2.dist-info/METADATA,sha256=6T1DqZw5zqu08qGQf6voKyO5NSIrhbMkzsvHPa7SaT8,12336
385
+ reflex-0.8.12a2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
386
+ reflex-0.8.12a2.dist-info/entry_points.txt,sha256=Rxt4dXc7MLBNt5CSHTehVPuSe9Xqow4HLX55nD9tQQ0,45
387
+ reflex-0.8.12a2.dist-info/licenses/LICENSE,sha256=dw3zLrp9f5ObD7kqS32vWfhcImfO52PMmRqvtxq_YEE,11358
388
+ reflex-0.8.12a2.dist-info/RECORD,,