reflex 0.8.5a1__py3-none-any.whl → 0.8.6a0__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.

@@ -0,0 +1,180 @@
1
+ """PyLeak integration for monitoring event loop blocking and resource leaks in Reflex applications."""
2
+
3
+ import asyncio
4
+ import contextlib
5
+ import functools
6
+ import inspect
7
+ import threading
8
+ from collections.abc import AsyncGenerator, Awaitable, Callable, Generator
9
+ from typing import TypeVar, overload
10
+
11
+ from reflex.config import get_config
12
+
13
+ try:
14
+ from pyleak import no_event_loop_blocking, no_task_leaks, no_thread_leaks
15
+ from pyleak.base import LeakAction
16
+
17
+ PYLEAK_AVAILABLE = True
18
+ except ImportError:
19
+ PYLEAK_AVAILABLE = False
20
+ no_event_loop_blocking = no_task_leaks = no_thread_leaks = None # pyright: ignore[reportAssignmentType]
21
+ LeakAction = None # pyright: ignore[reportAssignmentType]
22
+
23
+
24
+ # Thread-local storage to track if monitoring is already active
25
+ _thread_local = threading.local()
26
+
27
+
28
+ def is_pyleak_enabled() -> bool:
29
+ """Check if PyLeak monitoring is enabled and available.
30
+
31
+ Returns:
32
+ True if PyLeak monitoring is enabled in config and PyLeak is available.
33
+ """
34
+ if not PYLEAK_AVAILABLE:
35
+ return False
36
+ config = get_config()
37
+ return config.enable_pyleak_monitoring
38
+
39
+
40
+ @contextlib.contextmanager
41
+ def monitor_sync():
42
+ """Sync context manager for PyLeak monitoring.
43
+
44
+ Yields:
45
+ None: Context for monitoring sync operations.
46
+ """
47
+ if not is_pyleak_enabled():
48
+ yield
49
+ return
50
+
51
+ # Check if monitoring is already active in this thread
52
+ if getattr(_thread_local, "monitoring_active", False):
53
+ yield
54
+ return
55
+
56
+ config = get_config()
57
+ action = config.pyleak_action or LeakAction.WARN # pyright: ignore[reportOptionalMemberAccess]
58
+
59
+ # Mark monitoring as active
60
+ _thread_local.monitoring_active = True
61
+ try:
62
+ with contextlib.ExitStack() as stack:
63
+ # Thread leak detection has issues with background tasks (no_thread_leaks)
64
+ stack.enter_context(
65
+ no_event_loop_blocking( # pyright: ignore[reportOptionalCall]
66
+ action=action,
67
+ threshold=config.pyleak_blocking_threshold,
68
+ )
69
+ )
70
+ yield
71
+ finally:
72
+ _thread_local.monitoring_active = False
73
+
74
+
75
+ @contextlib.asynccontextmanager
76
+ async def monitor_async():
77
+ """Async context manager for PyLeak monitoring.
78
+
79
+ Yields:
80
+ None: Context for monitoring async operations.
81
+ """
82
+ if not is_pyleak_enabled():
83
+ yield
84
+ return
85
+
86
+ # Check if monitoring is already active in this thread
87
+ if getattr(_thread_local, "monitoring_active", False):
88
+ yield
89
+ return
90
+
91
+ config = get_config()
92
+ action = config.pyleak_action or LeakAction.WARN # pyright: ignore[reportOptionalMemberAccess]
93
+
94
+ # Mark monitoring as active
95
+ _thread_local.monitoring_active = True
96
+ try:
97
+ async with contextlib.AsyncExitStack() as stack:
98
+ # Thread leak detection has issues with background tasks (no_thread_leaks)
99
+ # Re-add thread leak later.
100
+
101
+ # Block detection for event loops
102
+ stack.enter_context(
103
+ no_event_loop_blocking( # pyright: ignore[reportOptionalCall]
104
+ action=action,
105
+ threshold=config.pyleak_blocking_threshold,
106
+ )
107
+ )
108
+ # Task leak detection has issues with background tasks (no_task_leaks)
109
+
110
+ yield
111
+ finally:
112
+ _thread_local.monitoring_active = False
113
+
114
+
115
+ YieldType = TypeVar("YieldType")
116
+ SendType = TypeVar("SendType")
117
+ ReturnType = TypeVar("ReturnType")
118
+
119
+
120
+ @overload
121
+ def monitor_loopblocks(
122
+ func: Callable[..., AsyncGenerator[YieldType, ReturnType]],
123
+ ) -> Callable[..., AsyncGenerator[YieldType, ReturnType]]: ...
124
+
125
+
126
+ @overload
127
+ def monitor_loopblocks(
128
+ func: Callable[..., Generator[YieldType, SendType, ReturnType]],
129
+ ) -> Callable[..., Generator[YieldType, SendType, ReturnType]]: ...
130
+
131
+
132
+ @overload
133
+ def monitor_loopblocks(
134
+ func: Callable[..., Awaitable[ReturnType]],
135
+ ) -> Callable[..., Awaitable[ReturnType]]: ...
136
+
137
+
138
+ def monitor_loopblocks(func: Callable) -> Callable:
139
+ """Framework decorator using the monitoring module's context manager.
140
+
141
+ Args:
142
+ func: The function to be monitored for leaks.
143
+
144
+ Returns:
145
+ Decorator function that applies PyLeak monitoring to sync/async functions.
146
+ """
147
+ if inspect.isasyncgenfunction(func):
148
+
149
+ @functools.wraps(func)
150
+ async def async_gen_wrapper(*args, **kwargs):
151
+ async with monitor_async():
152
+ async for item in func(*args, **kwargs):
153
+ yield item
154
+
155
+ return async_gen_wrapper
156
+
157
+ if asyncio.iscoroutinefunction(func):
158
+
159
+ @functools.wraps(func)
160
+ async def async_wrapper(*args, **kwargs):
161
+ async with monitor_async():
162
+ return await func(*args, **kwargs)
163
+
164
+ return async_wrapper
165
+
166
+ if inspect.isgeneratorfunction(func):
167
+
168
+ @functools.wraps(func)
169
+ def gen_wrapper(*args, **kwargs):
170
+ with monitor_sync():
171
+ yield from func(*args, **kwargs)
172
+
173
+ return gen_wrapper
174
+
175
+ @functools.wraps(func)
176
+ def sync_wrapper(*args, **kwargs):
177
+ with monitor_sync():
178
+ return func(*args, **kwargs)
179
+
180
+ return sync_wrapper # pyright: ignore[reportReturnType]
@@ -972,6 +972,9 @@ def initialize_web_directory():
972
972
  console.debug("Initializing the react-router.config.js file.")
973
973
  update_react_router_config()
974
974
 
975
+ console.debug("Initializing the vite.config.js file.")
976
+ initialize_vite_config()
977
+
975
978
  console.debug("Initializing the reflex.json file.")
976
979
  # Initialize the reflex json file.
977
980
  init_reflex_json(project_hash=project_hash)
@@ -996,6 +999,20 @@ def initialize_package_json():
996
999
  output_path.write_text(_compile_package_json())
997
1000
 
998
1001
 
1002
+ def _compile_vite_config(config: Config):
1003
+ # base must have exactly one trailing slash
1004
+ base = "/"
1005
+ if frontend_path := config.frontend_path.strip("/"):
1006
+ base += frontend_path + "/"
1007
+ return templates.VITE_CONFIG.render(base=base)
1008
+
1009
+
1010
+ def initialize_vite_config():
1011
+ """Render and write in .web the vite.config.js file using Reflex config."""
1012
+ vite_config_file_path = get_web_dir() / constants.ReactRouter.VITE_CONFIG_FILE
1013
+ vite_config_file_path.write_text(_compile_vite_config(get_config()))
1014
+
1015
+
999
1016
  def initialize_bun_config():
1000
1017
  """Initialize the bun config file."""
1001
1018
  bun_config_path = get_web_dir() / constants.Bun.CONFIG_PATH
@@ -0,0 +1,215 @@
1
+ """Token manager for handling client token to session ID mappings."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import uuid
6
+ from abc import ABC, abstractmethod
7
+ from typing import TYPE_CHECKING
8
+
9
+ from reflex.utils import console, prerequisites
10
+
11
+ if TYPE_CHECKING:
12
+ from redis.asyncio import Redis
13
+
14
+
15
+ def _get_new_token() -> str:
16
+ """Generate a new unique token.
17
+
18
+ Returns:
19
+ A new UUID4 token string.
20
+ """
21
+ return str(uuid.uuid4())
22
+
23
+
24
+ class TokenManager(ABC):
25
+ """Abstract base class for managing client token to session ID mappings."""
26
+
27
+ def __init__(self):
28
+ """Initialize the token manager with local dictionaries."""
29
+ # Keep a mapping between socket ID and client token.
30
+ self.token_to_sid: dict[str, str] = {}
31
+ # Keep a mapping between client token and socket ID.
32
+ self.sid_to_token: dict[str, str] = {}
33
+
34
+ @abstractmethod
35
+ async def link_token_to_sid(self, token: str, sid: str) -> str | None:
36
+ """Link a token to a session ID.
37
+
38
+ Args:
39
+ token: The client token.
40
+ sid: The Socket.IO session ID.
41
+
42
+ Returns:
43
+ New token if duplicate detected and new token generated, None otherwise.
44
+ """
45
+
46
+ @abstractmethod
47
+ async def disconnect_token(self, token: str, sid: str) -> None:
48
+ """Clean up token mapping when client disconnects.
49
+
50
+ Args:
51
+ token: The client token.
52
+ sid: The Socket.IO session ID.
53
+ """
54
+
55
+ @classmethod
56
+ def create(cls) -> TokenManager:
57
+ """Factory method to create appropriate TokenManager implementation.
58
+
59
+ Returns:
60
+ RedisTokenManager if Redis is available, LocalTokenManager otherwise.
61
+ """
62
+ if prerequisites.check_redis_used():
63
+ redis_client = prerequisites.get_redis()
64
+ if redis_client is not None:
65
+ return RedisTokenManager(redis_client)
66
+
67
+ return LocalTokenManager()
68
+
69
+
70
+ class LocalTokenManager(TokenManager):
71
+ """Token manager using local in-memory dictionaries (single worker)."""
72
+
73
+ def __init__(self):
74
+ """Initialize the local token manager."""
75
+ super().__init__()
76
+
77
+ async def link_token_to_sid(self, token: str, sid: str) -> str | None:
78
+ """Link a token to a session ID.
79
+
80
+ Args:
81
+ token: The client token.
82
+ sid: The Socket.IO session ID.
83
+
84
+ Returns:
85
+ New token if duplicate detected and new token generated, None otherwise.
86
+ """
87
+ # Check if token is already mapped to a different SID (duplicate tab)
88
+ if token in self.token_to_sid and sid != self.token_to_sid.get(token):
89
+ new_token = _get_new_token()
90
+ self.token_to_sid[new_token] = sid
91
+ self.sid_to_token[sid] = new_token
92
+ return new_token
93
+
94
+ # Normal case - link token to SID
95
+ self.token_to_sid[token] = sid
96
+ self.sid_to_token[sid] = token
97
+ return None
98
+
99
+ async def disconnect_token(self, token: str, sid: str) -> None:
100
+ """Clean up token mapping when client disconnects.
101
+
102
+ Args:
103
+ token: The client token.
104
+ sid: The Socket.IO session ID.
105
+ """
106
+ # Clean up both mappings
107
+ self.token_to_sid.pop(token, None)
108
+ self.sid_to_token.pop(sid, None)
109
+
110
+
111
+ class RedisTokenManager(LocalTokenManager):
112
+ """Token manager using Redis for distributed multi-worker support.
113
+
114
+ Inherits local dict logic from LocalTokenManager and adds Redis layer
115
+ for cross-worker duplicate detection.
116
+ """
117
+
118
+ def __init__(self, redis: Redis):
119
+ """Initialize the Redis token manager.
120
+
121
+ Args:
122
+ redis: The Redis client instance.
123
+ """
124
+ # Initialize parent's local dicts
125
+ super().__init__()
126
+
127
+ self.redis = redis
128
+
129
+ # Get token expiration from config (default 1 hour)
130
+ from reflex.config import get_config
131
+
132
+ config = get_config()
133
+ self.token_expiration = config.redis_token_expiration
134
+
135
+ def _get_redis_key(self, token: str) -> str:
136
+ """Get Redis key for token mapping.
137
+
138
+ Args:
139
+ token: The client token.
140
+
141
+ Returns:
142
+ Redis key following Reflex conventions: {token}_sid
143
+ """
144
+ return f"{token}_sid"
145
+
146
+ async def link_token_to_sid(self, token: str, sid: str) -> str | None:
147
+ """Link a token to a session ID with Redis-based duplicate detection.
148
+
149
+ Args:
150
+ token: The client token.
151
+ sid: The Socket.IO session ID.
152
+
153
+ Returns:
154
+ New token if duplicate detected and new token generated, None otherwise.
155
+ """
156
+ # Fast local check first (handles reconnections)
157
+ if token in self.token_to_sid and self.token_to_sid[token] == sid:
158
+ return None # Same token, same SID = reconnection, no Redis check needed
159
+
160
+ # Check Redis for cross-worker duplicates
161
+ redis_key = self._get_redis_key(token)
162
+
163
+ try:
164
+ token_exists_in_redis = await self.redis.exists(redis_key)
165
+ except Exception as e:
166
+ console.error(f"Redis error checking token existence: {e}")
167
+ return await super().link_token_to_sid(token, sid)
168
+
169
+ if token_exists_in_redis:
170
+ # Duplicate exists somewhere - generate new token
171
+ new_token = _get_new_token()
172
+ new_redis_key = self._get_redis_key(new_token)
173
+
174
+ try:
175
+ # Store in Redis
176
+ await self.redis.set(new_redis_key, "1", ex=self.token_expiration)
177
+ except Exception as e:
178
+ console.error(f"Redis error storing new token: {e}")
179
+ # Still update local dicts and continue
180
+
181
+ # Store in local dicts (always do this)
182
+ self.token_to_sid[new_token] = sid
183
+ self.sid_to_token[sid] = new_token
184
+ return new_token
185
+
186
+ # Normal case - store in both Redis and local dicts
187
+ try:
188
+ await self.redis.set(redis_key, "1", ex=self.token_expiration)
189
+ except Exception as e:
190
+ console.error(f"Redis error storing token: {e}")
191
+ # Continue with local storage
192
+
193
+ # Store in local dicts (always do this)
194
+ self.token_to_sid[token] = sid
195
+ self.sid_to_token[sid] = token
196
+ return None
197
+
198
+ async def disconnect_token(self, token: str, sid: str) -> None:
199
+ """Clean up token mapping when client disconnects.
200
+
201
+ Args:
202
+ token: The client token.
203
+ sid: The Socket.IO session ID.
204
+ """
205
+ # Only clean up if we own it locally (fast ownership check)
206
+ if self.token_to_sid.get(token) == sid:
207
+ # Clean up Redis
208
+ redis_key = self._get_redis_key(token)
209
+ try:
210
+ await self.redis.delete(redis_key)
211
+ except Exception as e:
212
+ console.error(f"Redis error deleting token: {e}")
213
+
214
+ # Clean up local dicts (always do this)
215
+ await super().disconnect_token(token, sid)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: reflex
3
- Version: 0.8.5a1
3
+ Version: 0.8.6a0
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
@@ -36,6 +36,8 @@ Requires-Dist: sqlmodel<0.1,>=0.0.24
36
36
  Requires-Dist: starlette>=0.47.0
37
37
  Requires-Dist: typing-extensions>=4.13.0
38
38
  Requires-Dist: wrapt<2.0,>=1.17.0
39
+ Provides-Extra: monitoring
40
+ Requires-Dist: pyleak<1.0,>=0.1.14; extra == 'monitoring'
39
41
  Description-Content-Type: text/markdown
40
42
 
41
43
  <div align="center">
@@ -50,6 +52,7 @@ Description-Content-Type: text/markdown
50
52
  [![Documentation](https://img.shields.io/badge/Documentation%20-Introduction%20-%20%23007ec6)](https://reflex.dev/docs/getting-started/introduction)
51
53
  [![PyPI Downloads](https://static.pepy.tech/badge/reflex)](https://pepy.tech/projects/reflex)
52
54
  [![Discord](https://img.shields.io/discord/1029853095527727165?color=%237289da&label=Discord)](https://discord.gg/T5WSbC2YtQ)
55
+ [![Twitter](https://img.shields.io/twitter/follow/getreflex)](https://x.com/getreflex)
53
56
 
54
57
  </div>
55
58
 
@@ -242,7 +245,7 @@ def get_image(self):
242
245
 
243
246
  Within the state, we define functions called event handlers that change the state vars. Event handlers are the way that we can modify the state in Reflex. They can be called in response to user actions, such as clicking a button or typing in a text box. These actions are called events.
244
247
 
245
- Our DALL·E. app has an event handler, `get_image` to which get this image from the OpenAI API. Using `yield` in the middle of an event handler will cause the UI to update. Otherwise the UI will update at the end of the event handler.
248
+ Our DALL·E app has an event handler, `get_image` which gets this image from the OpenAI API. Using `yield` in the middle of an event handler will cause the UI to update. Otherwise the UI will update at the end of the event handler.
246
249
 
247
250
  ### **Routing**
248
251
 
@@ -1,21 +1,21 @@
1
- reflex/__init__.py,sha256=ZQcJeGMYKc0Lx153mc_6HBOqXm73vg1PJfxLHn22AtM,10122
2
- reflex/__init__.pyi,sha256=QvBL5PePQ0SpojfClqAafiI6QetFB-qmDH-S7neQm3c,10091
1
+ reflex/__init__.py,sha256=_1PVYjDeA6_JyfXvL6OuKjjO6AX2oMiNcAq8AEHf6xw,10161
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=Yg4CYS5aHTvScfhqW8jC9-JeYoz-Yjii2nDWz7GFuF0,75310
5
+ reflex/app.py,sha256=2Jay0aocK1_rzR9Gbao2dxugXGdEuo_IoCQgCKQfdgY,77374
6
6
  reflex/assets.py,sha256=l5O_mlrTprC0lF7Rc_McOe3a0OtSLnRdNl_PqCpDCBA,3431
7
7
  reflex/base.py,sha256=Oh664QL3fZEHErhUasFqP7fE4olYf1y-9Oj6uZI2FCU,1173
8
- reflex/config.py,sha256=HgJ57Op-glTro23GoQKmyXwUplvGYgZFKjvClYpD27s,19359
9
- reflex/environment.py,sha256=PQF1QSLgu_tpUUP0vXWdvuC4t3wFts94nw2urt9Id8o,23227
8
+ reflex/config.py,sha256=iL5hbdel04GzTtNiPwoNQ6xACJO1SkuvwzAyodDv028,19875
9
+ reflex/environment.py,sha256=G-s20hBr-7K1_b6992XTgvNnBojcuL9Y33NAIUJLvT8,22940
10
10
  reflex/event.py,sha256=Yv9-tY-NH4q0Up72ljsABfBfnobnC0__DMvSWhFEo6M,74791
11
11
  reflex/model.py,sha256=l1-6fm7NHRFWH-xK9oV9UzAVfvKeUXG1f-tCrF7vmfI,19403
12
12
  reflex/page.py,sha256=ssCbMVFuIy60vH-YhJUzN0OxzUwXFCCD3ej56dVjp3g,3525
13
13
  reflex/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
14
  reflex/reflex.py,sha256=BkHnxKp3uZEllLWBbH8Y_EfSu80L4_0FEbSbZkg7JyQ,22506
15
15
  reflex/route.py,sha256=ZRlXl1HeKWM3W-yFCnRFIA_6I3W9JBqe2CKzCpWX7Vg,7699
16
- reflex/state.py,sha256=mrYV9wEdJ9DdWbAadgdWHbxc6onOU56dT8f4zkbznPo,92127
16
+ reflex/state.py,sha256=BunDGopplAH9qUagCv8j80m-IHnVX2LfF-bYo2aDspg,93055
17
17
  reflex/style.py,sha256=JxbXXA4MTnXrk0XHEoMBoNC7J-M2oL5Hl3W_QmXvmBg,13222
18
- reflex/testing.py,sha256=6EXQN9K0tYfzEDe2aSRh4xLM_Jb_oIrI_qH2F_e0KXc,39423
18
+ reflex/testing.py,sha256=MgYxW3MLjd8TX5Lv7EWW-go3Fu_gL07i9HpxPJpBUDw,39951
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
@@ -26,6 +26,7 @@ reflex/.templates/jinja/custom_components/demo_app.py.jinja2,sha256=ipbKtObNqQLc
26
26
  reflex/.templates/jinja/custom_components/pyproject.toml.jinja2,sha256=HG-k3pruUlMy7xYz339hgFkNMTLqB-C_FTLKkOgfBPM,630
27
27
  reflex/.templates/jinja/custom_components/src.py.jinja2,sha256=e80PwMI6NoeQtGJ0NXWhYrkqUe7jvvJTFuztYQe-R5w,2403
28
28
  reflex/.templates/jinja/web/package.json.jinja2,sha256=cS9M6ADYDoYL2Kc8m5dYhV8eDaehOXb6qK_IOijT3N0,673
29
+ reflex/.templates/jinja/web/vite.config.js.jinja2,sha256=lx7G9abIKzSn0Sz98YWbAMIeLFM1p0iujj8IW_xBDAY,1639
29
30
  reflex/.templates/jinja/web/pages/_app.js.jinja2,sha256=tG-SRR7DCP3SxLoUl_5rIRmL1uBDVnkcenSUxy459hY,1575
30
31
  reflex/.templates/jinja/web/pages/_document.js.jinja2,sha256=v_r79GPGKnw1g9Bg4lK9o_ow5AzBnvKdz0nv3OgJyzU,166
31
32
  reflex/.templates/jinja/web/pages/base_page.js.jinja2,sha256=nteivFZgOhgwxlPvejgaoxKTPGvDRb7_JAXhsZDZeLM,361
@@ -44,7 +45,6 @@ reflex/.templates/web/jsconfig.json,sha256=rhQZZRBYxBWclFYTeU6UakzbGveM4qyRQZUpE
44
45
  reflex/.templates/web/postcss.config.js,sha256=6Hf540Ny078yfmJ_-tniZtmgHW6euyEyxO0zH-Y1EtQ,86
45
46
  reflex/.templates/web/react-router.config.js,sha256=5K1FBryYdPusn1nE513GwB5_5UdPzoyH8ZMANUbpodQ,84
46
47
  reflex/.templates/web/vite-plugin-safari-cachebust.js,sha256=FcyppYYBxUlZtQ-D_iyVaQIT6TBVisBH7DMzWxYm-zA,5300
47
- reflex/.templates/web/vite.config.js,sha256=JkeosM-OI3zwbwE3zON1ws8SrMAORG54nuQsPecU5d4,1429
48
48
  reflex/.templates/web/app/entry.client.js,sha256=2Jv-5SQWHhHmA07BP50f1ew1V-LOsX5VoLtSInnFDj8,264
49
49
  reflex/.templates/web/app/routes.js,sha256=OPPW82B079c4FGq_p5C5OBrkVnTNRFhgG3--WKlJSy0,312
50
50
  reflex/.templates/web/components/reflex/radix_themes_color_mode_provider.js,sha256=dnDHW49imtdalZJQqj7J_u7cj2z8Sve7OlhtOO0FbKE,916
@@ -52,7 +52,7 @@ reflex/.templates/web/components/shiki/code.js,sha256=4Es1pxsr-lX4hTQ5mglrwwC6O_
52
52
  reflex/.templates/web/styles/__reflex_style_reset.css,sha256=qbC6JIT643YEsvSQ0D7xBmWE5vXy94JGrKNihRuEjnA,8913
53
53
  reflex/.templates/web/utils/client_side_routing.js,sha256=lRNgEGCLfTejh8W3aCuBdFuko6UI2vetk64j8wLT5Uk,1650
54
54
  reflex/.templates/web/utils/react-theme.js,sha256=Aa-RND3ooGCXW6Zavzitc-v0ciKlcQDTFlDtE4mPkFI,2713
55
- reflex/.templates/web/utils/state.js,sha256=Z9NeC1sjePtIg03kvxILng-1ri_PNZFAM_t64K4d5Dg,36162
55
+ reflex/.templates/web/utils/state.js,sha256=-RbOSjeggpR4VYffLYN59nTCEw8d9KHEqN_O_Lp33aM,36338
56
56
  reflex/.templates/web/utils/helpers/dataeditor.js,sha256=pG6MgsHuStDR7-qPipzfiK32j9bKDBa-4hZ0JSUo4JM,1623
57
57
  reflex/.templates/web/utils/helpers/debounce.js,sha256=xGhtTRtS_xIcaeqnYVvYJNseLgQVk-DW-eFiHJYO9As,528
58
58
  reflex/.templates/web/utils/helpers/paste.js,sha256=ef30HsR83jRzzvZnl8yV79yqFP8TC_u8SlN99cCS_OM,1799
@@ -64,8 +64,8 @@ reflex/app_mixins/middleware.py,sha256=BKhe0jUFO1_TylEC48LUZyaeYyPmAYW-NV4H5Rw22
64
64
  reflex/app_mixins/mixin.py,sha256=R1YncalqDrbdPZvpKVbm72ZKmQZxYAWfuFq9JknzTqQ,305
65
65
  reflex/compiler/__init__.py,sha256=r8jqmDSFf09iV2lHlNhfc9XrTLjNxfDNwPYlxS4cmHE,27
66
66
  reflex/compiler/compiler.py,sha256=AEGoZRG3PVOUf_5lZxlAt0pwsXg-lYIdOluyzpMuyOI,29088
67
- reflex/compiler/templates.py,sha256=mQifVgvE7cKyzMFL9F5jxdJb9KFxucWJa7nuOp09ZUo,6002
68
- reflex/compiler/utils.py,sha256=Eo0-zLCj4rFhkVZQNWSMoMSGTSAkHIivoNwoAgMBYi8,19266
67
+ reflex/compiler/templates.py,sha256=eWBtJBrriUyb7j4yRCi2X8MVauIVAfz0Ip6NaXLUhIM,6104
68
+ reflex/compiler/utils.py,sha256=587KMP1BDYYigAY6looM9L69Eoq3PEOxCB8k7r9BW5A,18922
69
69
  reflex/components/__init__.py,sha256=eWpgWFbSQDj2TpGp6StEbxU7roQgzY7ZM0XIcIc5RE8,588
70
70
  reflex/components/__init__.pyi,sha256=7VFHtJGIjvGtD3IiPk848IPWYSCcPRT1EyPGljLhYlU,736
71
71
  reflex/components/component.py,sha256=DyeMdHSPkhYUXn18QcVZneJZKV8qzAlPMR9M8kY7_K8,98462
@@ -96,7 +96,7 @@ reflex/components/base/strict_mode.py,sha256=_Rl2uGzL8gXTANOpoSU7uxsUQRH5JeTk2EI
96
96
  reflex/components/base/strict_mode.pyi,sha256=1n6EHlv51hLnkK18t0xHQ23FphSXb8pfSSVn6vDcHZY,2380
97
97
  reflex/components/core/__init__.py,sha256=IRNnqXeQUT_Mhiaca05E3vKldxXzfkHGv5EDz_jAIqk,1418
98
98
  reflex/components/core/__init__.pyi,sha256=Nr68v8pdwvBX93HhV-gHzPPYLAvRJ63kNrdICzBJxPk,1991
99
- reflex/components/core/auto_scroll.py,sha256=3jtFUqMUM1R_YyxWjbNVLiLktw6HHp50EzIFTkFtgto,3616
99
+ reflex/components/core/auto_scroll.py,sha256=zCHP5Mr_sLAmm4zvkC0-rQ1cU5cy35R7FKVo2jsmYaQ,3815
100
100
  reflex/components/core/auto_scroll.pyi,sha256=0R5NvVJ00X42-dSTX23zOGPbwGWGt1lQ_4iV5dn_JxY,8889
101
101
  reflex/components/core/banner.py,sha256=JEutUBT1UfpgnaDJthE2BoSzpIEE-cSHoQZlEvQb0dw,18471
102
102
  reflex/components/core/banner.pyi,sha256=F7LPVH4wkdsBnTaXG3NW3NkULYQSm5wAmvHerEOFdjQ,25480
@@ -127,25 +127,25 @@ reflex/components/datadisplay/__init__.py,sha256=L8pWWKNHWdUD2fbZRoEKjd_8c_hpDdG
127
127
  reflex/components/datadisplay/__init__.pyi,sha256=H3LZkWdrw3RTv_csaIT8qoClgAJTonlGZ5ZMeGMV0Bs,551
128
128
  reflex/components/datadisplay/code.py,sha256=--KKcHTi7mxXDv1-sokZYEwBl735i0fbT6RpWHE-8Dw,12588
129
129
  reflex/components/datadisplay/code.pyi,sha256=-oMJ66LEb3sCJHlUj7rEY3H5aIujjMh1sPKndf1KUIo,41275
130
- reflex/components/datadisplay/dataeditor.py,sha256=SxvIDyKl9TILOlx6Zga9jCcu0LBc4E1WhrUFJGO6lKs,13496
131
- reflex/components/datadisplay/dataeditor.pyi,sha256=K9SjpUlJ-k76Gopo0Slmeq7O5YcmFj56Nqjmxvw5mes,12389
130
+ reflex/components/datadisplay/dataeditor.py,sha256=cGwAKPYknoHMwVhBowHKFtG2Nxr5q-8hIptnf98U7x0,13574
131
+ reflex/components/datadisplay/dataeditor.pyi,sha256=eDI6w6ZrJRXQsThXu3vS-dfI-aKPMntLN5RmGkJOYCQ,12511
132
132
  reflex/components/datadisplay/logo.py,sha256=xvg5TRVRSi2IKn7Kg4oYzWcaFMHfXxUaCp0cQmuKSn0,1993
133
133
  reflex/components/datadisplay/shiki_code_block.py,sha256=qCp4jZO3Ek4mR_1Qs4oxLh-GCEo6VBlpb8B9MDDdw4Y,24503
134
134
  reflex/components/datadisplay/shiki_code_block.pyi,sha256=J6NyOY_RQ9VTu7Psi3Tuctv5EM6FnlPZ2EXEZwHBC9w,56933
135
135
  reflex/components/el/__init__.py,sha256=JJHaCMvCh5_nsuyaWRVQ8d75A13lvaq4cpm6HoxUYuM,607
136
- reflex/components/el/__init__.pyi,sha256=zmdFPcH1ta6bA1JiY3DvIXx7wPtuIFmThrzq2mk_D_E,6293
136
+ reflex/components/el/__init__.pyi,sha256=Tp0hDa_HW7TxlN2dVrDHKeuiO0mQSFnmTBFZRUXSheQ,6345
137
137
  reflex/components/el/element.py,sha256=stGVO6A2waCHq2CGQqR_g798hDKkuSZerwB0tYfZpRE,582
138
138
  reflex/components/el/element.pyi,sha256=Bld5aXzT9vR5-pgrRddo5W4JMV54CMkamOZFUeLp4fY,2368
139
- reflex/components/el/elements/__init__.py,sha256=PKchWo_qdR2oSedspbMN1kDmB7OZG90Yxt-nzDenMBs,2779
140
- reflex/components/el/elements/__init__.pyi,sha256=0efVjUvi7r1UsCKf4U3qPyRhEJVcqs7DdBTa3dVTVbA,8610
139
+ reflex/components/el/elements/__init__.py,sha256=_uZaPHSQSDZBqo-v_hRZECJbWBY3SrqJLCZt1s2CTaQ,2797
140
+ reflex/components/el/elements/__init__.pyi,sha256=LCaxINN6BUqHsxgpDITjOUqJnF3x5rRI8y2fj62ZT14,8680
141
141
  reflex/components/el/elements/base.py,sha256=4jnwyCQUHvWcIfwiIWVCiIC_jbwZlkAiOgx73t7tdw8,3075
142
142
  reflex/components/el/elements/base.pyi,sha256=RPdq_8Z1gkV-5n2qeEVQWpPCwVSTzY4eYb6iIJVU-ig,10074
143
143
  reflex/components/el/elements/forms.py,sha256=HK3bJd4pUU7CBjC4Py9Q_AblyaUE6ELyifHQ2lVWDhs,21395
144
144
  reflex/components/el/elements/forms.pyi,sha256=4O2RyZPyC5WGA52SKYWOEvRrbiWg7emLzbtO_w8G_3w,168606
145
145
  reflex/components/el/elements/inline.py,sha256=q3Ku_x8L9NaXrYQovCfkWwZ5AfXG0VyhGN_OT73kA0Y,4126
146
146
  reflex/components/el/elements/inline.pyi,sha256=0pjqiHH8DmFfghbM8MK5tqgiZGSnfT-o055GINU8xrA,231760
147
- reflex/components/el/elements/media.py,sha256=3f3zJRDDp0UCzaUIJHZV4RzLrboGhAgAMsOkxgjuVGk,13647
148
- reflex/components/el/elements/media.pyi,sha256=1g5t9N75S_-qFuwaqmh8GV30pVsiaWKfaSBdbY_ilyU,231143
147
+ reflex/components/el/elements/media.py,sha256=t5vDG5q8K_-YTu2tkyeC7bXb0O913Z5C74jPhDjIqmA,14586
148
+ reflex/components/el/elements/media.pyi,sha256=g8stEbHH7qWoK0_x_ffqZRJdmElVmCo0iBekmxMWLJA,240566
149
149
  reflex/components/el/elements/metadata.py,sha256=Vf0D0dXqvwt76FkrvDQQpESJmxDh6e6Qxnk2GIRhOlM,2316
150
150
  reflex/components/el/elements/metadata.pyi,sha256=5pqPOzE-QbjiOQBitX_qWkcrCssotx-VaP-7x62dfjg,39675
151
151
  reflex/components/el/elements/other.py,sha256=WON35QviPNYsBeLQTNbeN7a6m6ixLYIVa4WsDzo9YBY,1378
@@ -162,8 +162,8 @@ reflex/components/gridjs/__init__.py,sha256=xJwDm1AZ70L5-t9LLqZwGUtDpijbf1KuMYDT
162
162
  reflex/components/gridjs/datatable.py,sha256=7JKrRw1zkpFB0_wwoaIhrVrldsm7-dyi3PASgqLq8Hc,4224
163
163
  reflex/components/gridjs/datatable.pyi,sha256=kFgv82vCgfdWZaUq4bZ73G8X3mkw6ecvSRkZ9G9-28E,5185
164
164
  reflex/components/lucide/__init__.py,sha256=EggTK2MuQKQeOBLKW-mF0VaDK9zdWBImu1HO2dvHZbE,73
165
- reflex/components/lucide/icon.py,sha256=-xb7snRMWPXJ9OR8lLWLD3yTAP2lQviTkMC8JLgyDGE,35092
166
- reflex/components/lucide/icon.pyi,sha256=5XdzyXc1snQvLd_IXInRfLZnKl3_RH5Q-0Pu1MRqVEk,37861
165
+ reflex/components/lucide/icon.py,sha256=aqjX1dq6-FxiMvvOF_002Bbfmz2fq5MnggbEQ5wn30w,35145
166
+ reflex/components/lucide/icon.pyi,sha256=xxhLg-RZgUw0-cDT9F4898aG12EsoKZXrP3KAhkrI60,37939
167
167
  reflex/components/markdown/__init__.py,sha256=Dfl1At5uYoY7H4ufZU_RY2KOGQDLtj75dsZ2BTqqAns,87
168
168
  reflex/components/markdown/markdown.py,sha256=scDHnmn2n4KHXS2Imqa1jw1wTk1ewCB2MojC9NgKGHQ,15503
169
169
  reflex/components/markdown/markdown.pyi,sha256=oOlXZItHB0TPWsFz1Qjvr3KzG8sssthBp40UO_KkRIA,4322
@@ -325,7 +325,7 @@ reflex/components/recharts/polar.pyi,sha256=8ShEcGK9KJyu0FN6KPys1kgAYrzOZ6wtiRuy
325
325
  reflex/components/recharts/recharts.py,sha256=CrkZ1Ez6QhDpDvlL0TkeT_qtBg0keLaGS9L2qfgr8zI,3221
326
326
  reflex/components/recharts/recharts.pyi,sha256=9j8cVSMqyBkkOBBrx9pzDpP1clnbM9kD0TTViTUGDYc,7084
327
327
  reflex/components/sonner/__init__.py,sha256=L_mdRIy7-ccRGSz5VK6J8O-c-e-D1p9xWw29_ErrvGg,68
328
- reflex/components/sonner/toast.py,sha256=T_Vsq6wPnDLNeL6bmxu-DZsRRpoHm4Z4lqKW7URbSgY,12392
328
+ reflex/components/sonner/toast.py,sha256=rzSOAhb7tuT7IFOu7zSttya2GPjUNBahjQ_DEO-uocs,12392
329
329
  reflex/components/sonner/toast.pyi,sha256=jfNzgYUThyhz2lOjat61C8ObKawY16Bq_T3KLZ0aThY,7658
330
330
  reflex/components/tags/__init__.py,sha256=Pc0JU-Tv_W7KCsydXgbKmu7w2VtHNkI6Cx2hTkNhW_Q,152
331
331
  reflex/components/tags/cond_tag.py,sha256=kqN3FoDzr5fZUng1KDIvGmdQCLd7Tni3TQ_iaEz8F-w,641
@@ -334,7 +334,7 @@ reflex/components/tags/match_tag.py,sha256=cMSa_hbuEV8uFg0iCwLhRJ0J6-oU5rKQf9Z2-
334
334
  reflex/components/tags/tag.py,sha256=AbB8MtmmMUAvlMtQe7XLL-afsb1rckzo4R1MJ1RsNQs,3865
335
335
  reflex/components/tags/tagless.py,sha256=qO7Gm4V0ITDyymHkyltfz53155ZBt-W_WIPDYy93ca0,587
336
336
  reflex/constants/__init__.py,sha256=q2Jf-LBbNcGrOmx5M7QotIAYW_t3m02TsmmdtJ5_IhM,2190
337
- reflex/constants/base.py,sha256=sFv9DhRZtEM2fix6U8SwTcBn05zl5Z_X8X-bqr3fh2E,9065
337
+ reflex/constants/base.py,sha256=_ozsoSM6g0oILaqC_mjv0SaPu_DjQBbUnk62qfYures,7577
338
338
  reflex/constants/colors.py,sha256=n-FN7stNrvk5rCN0TAvE28dqwUeQZHue-b5q1CO0EyQ,2048
339
339
  reflex/constants/compiler.py,sha256=bzmC1OW6kWr06rV1Gwoa2AtQ4yPoGhEzeoqpiNY0jwU,5703
340
340
  reflex/constants/config.py,sha256=8OIjiBdZZJrRVHsNBheMwopE9AwBFFzau0SXqXKcrPg,1715
@@ -370,7 +370,7 @@ reflex/utils/build.py,sha256=lk8hE69onG95dv-LxRhjtEugct1g-KcWPUDorzqeGIE,7964
370
370
  reflex/utils/codespaces.py,sha256=kEQ-j-jclTukFpXDlYgNp95kYMGDrQmP3VNEoYGZ1u4,3052
371
371
  reflex/utils/compat.py,sha256=aSJH_M6iomgHPQ4onQ153xh1MWqPi3HSYDzE68N6gZM,2635
372
372
  reflex/utils/console.py,sha256=QIOgyElaxSVM1Bbvz0zx77-MqkDZkfpu1d6l26VRkQ0,11580
373
- reflex/utils/decorator.py,sha256=P5xP2kZsJnNdc91x2dou9_Z8U3q4YkPDB-vpfE3CZtU,3900
373
+ reflex/utils/decorator.py,sha256=QUZntENupeW5FA5mNRTx0I1GzGKFQXhMjVg24_IIM5o,3957
374
374
  reflex/utils/exceptions.py,sha256=Wwu7Ji2xgq521bJKtU2NgjwhmFfnG8erirEVN2h8S-g,8884
375
375
  reflex/utils/exec.py,sha256=KQ5tS5vz3wuu9zDGPR6clSE0IoY_vcIbJGCB5bqiDJM,21987
376
376
  reflex/utils/export.py,sha256=Z2AHuhkxGQzOi9I90BejQ4qEcD0URr2i-ZU5qTJt7eQ,2562
@@ -378,15 +378,17 @@ reflex/utils/format.py,sha256=FZe5NA0U3K0n0k7r8RIGcx-eHpN7sf8eQX9w1C8_uR8,21120
378
378
  reflex/utils/imports.py,sha256=Ov-lqv-PfsPl3kTEW13r5aDauIfn6TqzEMyv42RKLOA,3761
379
379
  reflex/utils/lazy_loader.py,sha256=BiY9OvmAJDCz10qpuyTYv9duXgMFQa6RXKQmTO9hqKU,4453
380
380
  reflex/utils/misc.py,sha256=folEweZVCrhHNkkqut9KqQdTJ80HxwL_gI41m40FnNM,4592
381
+ reflex/utils/monitoring.py,sha256=87fr9j6Y9Bvz2uF4tBxuX6CaU054h1UPx0ijcnyP_kw,5250
381
382
  reflex/utils/net.py,sha256=q3h5pNbAlFiqy8U15S9DTOvzy_OnenVVug5ROBTGRTA,4267
382
383
  reflex/utils/path_ops.py,sha256=_RS17IQDNr5vcoLLGZx2-z1E5WP-JgDHvaRAOgqrZiU,8154
383
- reflex/utils/prerequisites.py,sha256=JRZqECnuEglizSTUTpO6x39s_CfEluzDHQn6TDOFZLs,62510
384
+ reflex/utils/prerequisites.py,sha256=JUv4VGPDJmZrJM1U5Ot87ZzPwd4sG-3AbsyuTt5o7K0,63118
384
385
  reflex/utils/processes.py,sha256=t-ufWwu9RDsSMXCSsmjS2TILP5s7-AY94Rgx2O2gHMw,18178
385
386
  reflex/utils/pyi_generator.py,sha256=HdmUVs50Bk7MAMFSvpATRhH--_50w-9URMFnjLlwT40,46086
386
387
  reflex/utils/redir.py,sha256=E6lJ6UYGQs_uCyQAKHT_dDMplo5IRZ9JarWfvgGAgGo,1731
387
388
  reflex/utils/registry.py,sha256=omKh5rrsybDuuKmh4K88lwdwwcpGsu3Vc4pCko_djKY,2239
388
389
  reflex/utils/serializers.py,sha256=sVLfbWIBKPpmo0CVVxoxXGu0K3R9mYMWgaI02LXZmcM,13952
389
390
  reflex/utils/telemetry.py,sha256=XpPbFmlFdEh5uJl5vXoLyCCFv1choJN8EMko0MujigQ,7452
391
+ reflex/utils/token_manager.py,sha256=o_HGbqT9WfYRmek2iY9nem4vDZMz8Q4Dra-eW1lKmuA,6999
390
392
  reflex/utils/types.py,sha256=jFHfd2-yHWV61L7YP2gc9Zj2ZLwdthHOOfRIc_PAWH0,38390
391
393
  reflex/vars/__init__.py,sha256=85eXMt32bFoKtMdH3KxYRMD8mtnKyYiQcThPxJLoW1k,1359
392
394
  reflex/vars/base.py,sha256=IGCU5iwZSsVMPVQqODEjmHJrskqfpfMIQ2yzcVFMoSQ,112940
@@ -397,8 +399,8 @@ reflex/vars/number.py,sha256=tO7pnvFaBsedq1HWT4skytnSqHWMluGEhUbjAUMx8XQ,28190
397
399
  reflex/vars/object.py,sha256=BDmeiwG8v97s_BnR1Egq3NxOKVjv9TfnREB3cz0zZtk,17322
398
400
  reflex/vars/sequence.py,sha256=1kBrqihspyjyQ1XDqFPC8OpVGtZs_EVkOdIKBro5ilA,55249
399
401
  scripts/hatch_build.py,sha256=-4pxcLSFmirmujGpQX9UUxjhIC03tQ_fIQwVbHu9kc0,1861
400
- reflex-0.8.5a1.dist-info/METADATA,sha256=SN7VniEy2wgwl35t0psn-EUxLuHRr3fqlPrKRxyBa90,12372
401
- reflex-0.8.5a1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
402
- reflex-0.8.5a1.dist-info/entry_points.txt,sha256=Rxt4dXc7MLBNt5CSHTehVPuSe9Xqow4HLX55nD9tQQ0,45
403
- reflex-0.8.5a1.dist-info/licenses/LICENSE,sha256=dw3zLrp9f5ObD7kqS32vWfhcImfO52PMmRqvtxq_YEE,11358
404
- reflex-0.8.5a1.dist-info/RECORD,,
402
+ reflex-0.8.6a0.dist-info/METADATA,sha256=2RaX5LhTj99Yn0i6IbUON1L_nKWz5EHINSBMcYHeGpY,12541
403
+ reflex-0.8.6a0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
404
+ reflex-0.8.6a0.dist-info/entry_points.txt,sha256=Rxt4dXc7MLBNt5CSHTehVPuSe9Xqow4HLX55nD9tQQ0,45
405
+ reflex-0.8.6a0.dist-info/licenses/LICENSE,sha256=dw3zLrp9f5ObD7kqS32vWfhcImfO52PMmRqvtxq_YEE,11358
406
+ reflex-0.8.6a0.dist-info/RECORD,,