reflex 0.8.3a3__py3-none-any.whl → 0.8.4a1__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/.templates/web/utils/react-theme.js +18 -6
- reflex/.templates/web/utils/state.js +2 -2
- reflex/app.py +6 -20
- reflex/compiler/utils.py +6 -0
- reflex/constants/installer.py +3 -3
- reflex/custom_components/custom_components.py +1 -1
- reflex/istate/data.py +7 -1
- reflex/utils/console.py +2 -1
- reflex/utils/decorator.py +76 -1
- reflex/utils/misc.py +43 -0
- reflex/utils/net.py +8 -3
- reflex/utils/prerequisites.py +9 -67
- reflex/utils/processes.py +46 -7
- reflex/utils/redir.py +3 -5
- reflex/utils/registry.py +14 -2
- reflex/utils/telemetry.py +2 -2
- reflex/vars/dep_tracking.py +27 -30
- {reflex-0.8.3a3.dist-info → reflex-0.8.4a1.dist-info}/METADATA +2 -2
- {reflex-0.8.3a3.dist-info → reflex-0.8.4a1.dist-info}/RECORD +22 -22
- {reflex-0.8.3a3.dist-info → reflex-0.8.4a1.dist-info}/WHEEL +0 -0
- {reflex-0.8.3a3.dist-info → reflex-0.8.4a1.dist-info}/entry_points.txt +0 -0
- {reflex-0.8.3a3.dist-info → reflex-0.8.4a1.dist-info}/licenses/LICENSE +0 -0
|
@@ -18,9 +18,18 @@ const ThemeContext = createContext({
|
|
|
18
18
|
|
|
19
19
|
export function ThemeProvider({ children, defaultTheme = "system" }) {
|
|
20
20
|
const [theme, setTheme] = useState(defaultTheme);
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
)
|
|
21
|
+
|
|
22
|
+
// Detect system preference synchronously during initialization
|
|
23
|
+
const getInitialSystemTheme = () => {
|
|
24
|
+
if (defaultTheme !== "system") return defaultTheme;
|
|
25
|
+
if (typeof window === "undefined") return "light";
|
|
26
|
+
return window.matchMedia("(prefers-color-scheme: dark)").matches
|
|
27
|
+
? "dark"
|
|
28
|
+
: "light";
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const [systemTheme, setSystemTheme] = useState(getInitialSystemTheme);
|
|
32
|
+
const [isInitialized, setIsInitialized] = useState(false);
|
|
24
33
|
|
|
25
34
|
const firstRender = useRef(true);
|
|
26
35
|
|
|
@@ -43,6 +52,7 @@ export function ThemeProvider({ children, defaultTheme = "system" }) {
|
|
|
43
52
|
// Load saved theme from localStorage
|
|
44
53
|
const savedTheme = localStorage.getItem("theme") || defaultTheme;
|
|
45
54
|
setTheme(savedTheme);
|
|
55
|
+
setIsInitialized(true);
|
|
46
56
|
});
|
|
47
57
|
|
|
48
58
|
const resolvedTheme = useMemo(
|
|
@@ -68,10 +78,12 @@ export function ThemeProvider({ children, defaultTheme = "system" }) {
|
|
|
68
78
|
};
|
|
69
79
|
});
|
|
70
80
|
|
|
71
|
-
// Save theme to localStorage whenever it changes
|
|
81
|
+
// Save theme to localStorage whenever it changes (but not on initial mount)
|
|
72
82
|
useEffect(() => {
|
|
73
|
-
|
|
74
|
-
|
|
83
|
+
if (isInitialized) {
|
|
84
|
+
localStorage.setItem("theme", theme);
|
|
85
|
+
}
|
|
86
|
+
}, [theme, isInitialized]);
|
|
75
87
|
|
|
76
88
|
useEffect(() => {
|
|
77
89
|
const root = window.document.documentElement;
|
|
@@ -791,9 +791,9 @@ export const hydrateClientStorage = (client_storage) => {
|
|
|
791
791
|
for (const state_key in client_storage.cookies) {
|
|
792
792
|
const cookie_options = client_storage.cookies[state_key];
|
|
793
793
|
const cookie_name = cookie_options.name || state_key;
|
|
794
|
-
const cookie_value = cookies.get(cookie_name);
|
|
794
|
+
const cookie_value = cookies.get(cookie_name, { doNotParse: true });
|
|
795
795
|
if (cookie_value !== undefined) {
|
|
796
|
-
client_storage_values[state_key] =
|
|
796
|
+
client_storage_values[state_key] = cookie_value;
|
|
797
797
|
}
|
|
798
798
|
}
|
|
799
799
|
}
|
reflex/app.py
CHANGED
|
@@ -28,7 +28,6 @@ from timeit import default_timer as timer
|
|
|
28
28
|
from types import SimpleNamespace
|
|
29
29
|
from typing import TYPE_CHECKING, Any, BinaryIO, ParamSpec, get_args, get_type_hints
|
|
30
30
|
|
|
31
|
-
from fastapi import FastAPI
|
|
32
31
|
from rich.progress import MofNCompleteColumn, Progress, TimeElapsedColumn
|
|
33
32
|
from socketio import ASGIApp as EngineIOApp
|
|
34
33
|
from socketio import AsyncNamespace, AsyncServer
|
|
@@ -441,9 +440,6 @@ class App(MiddlewareMixin, LifespanMixin):
|
|
|
441
440
|
| None
|
|
442
441
|
) = None
|
|
443
442
|
|
|
444
|
-
# FastAPI app for compatibility with FastAPI.
|
|
445
|
-
_cached_fastapi_app: FastAPI | None = None
|
|
446
|
-
|
|
447
443
|
@property
|
|
448
444
|
def event_namespace(self) -> EventNamespace | None:
|
|
449
445
|
"""Get the event namespace.
|
|
@@ -598,32 +594,22 @@ class App(MiddlewareMixin, LifespanMixin):
|
|
|
598
594
|
Returns:
|
|
599
595
|
The backend api.
|
|
600
596
|
"""
|
|
597
|
+
from reflex.vars.base import GLOBAL_CACHE
|
|
598
|
+
|
|
601
599
|
# For py3.9 compatibility when redis is used, we MUST add any decorator pages
|
|
602
600
|
# before compiling the app in a thread to avoid event loop error (REF-2172).
|
|
603
601
|
self._apply_decorated_pages()
|
|
604
602
|
|
|
605
|
-
|
|
606
|
-
self._compile, prerender_routes=is_prod_mode()
|
|
607
|
-
)
|
|
603
|
+
self._compile(prerender_routes=is_prod_mode())
|
|
608
604
|
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
return f.result()
|
|
612
|
-
|
|
613
|
-
compile_future.add_done_callback(callback)
|
|
614
|
-
# Wait for the compile to finish to ensure all optional endpoints are mounted.
|
|
615
|
-
compile_future.result()
|
|
605
|
+
# We will not be making more vars, so we can clear the global cache to free up memory.
|
|
606
|
+
GLOBAL_CACHE.clear()
|
|
616
607
|
|
|
617
608
|
if not self._api:
|
|
618
609
|
msg = "The app has not been initialized."
|
|
619
610
|
raise ValueError(msg)
|
|
620
611
|
|
|
621
|
-
|
|
622
|
-
asgi_app = self._cached_fastapi_app
|
|
623
|
-
asgi_app.mount("", self._api)
|
|
624
|
-
App._add_cors(asgi_app)
|
|
625
|
-
else:
|
|
626
|
-
asgi_app = self._api
|
|
612
|
+
asgi_app = self._api
|
|
627
613
|
|
|
628
614
|
if self.api_transformer is not None:
|
|
629
615
|
api_transformers: Sequence[Starlette | Callable[[ASGIApp], ASGIApp]] = (
|
reflex/compiler/utils.py
CHANGED
|
@@ -359,6 +359,8 @@ def create_document_root(
|
|
|
359
359
|
Returns:
|
|
360
360
|
The document root.
|
|
361
361
|
"""
|
|
362
|
+
from reflex.utils.misc import preload_color_theme
|
|
363
|
+
|
|
362
364
|
existing_meta_types = set()
|
|
363
365
|
|
|
364
366
|
for component in head_components or []:
|
|
@@ -385,7 +387,11 @@ def create_document_root(
|
|
|
385
387
|
Meta.create(name="viewport", content="width=device-width, initial-scale=1")
|
|
386
388
|
)
|
|
387
389
|
|
|
390
|
+
# Add theme preload script as the very first component to prevent FOUC
|
|
391
|
+
theme_preload_components = [preload_color_theme()]
|
|
392
|
+
|
|
388
393
|
head_components = [
|
|
394
|
+
*theme_preload_components,
|
|
389
395
|
*(head_components or []),
|
|
390
396
|
*maybe_head_components,
|
|
391
397
|
*always_head_components,
|
reflex/constants/installer.py
CHANGED
|
@@ -14,7 +14,7 @@ class Bun(SimpleNamespace):
|
|
|
14
14
|
"""Bun constants."""
|
|
15
15
|
|
|
16
16
|
# The Bun version.
|
|
17
|
-
VERSION = "1.2.
|
|
17
|
+
VERSION = "1.2.19"
|
|
18
18
|
|
|
19
19
|
# Min Bun Version
|
|
20
20
|
MIN_VERSION = "1.2.17"
|
|
@@ -75,7 +75,7 @@ fetch-retries=0
|
|
|
75
75
|
|
|
76
76
|
|
|
77
77
|
def _determine_react_router_version() -> str:
|
|
78
|
-
default_version = "7.
|
|
78
|
+
default_version = "7.7.0"
|
|
79
79
|
if (version := os.getenv("REACT_ROUTER_VERSION")) and version != default_version:
|
|
80
80
|
from reflex.utils import console
|
|
81
81
|
|
|
@@ -149,5 +149,5 @@ class PackageJson(SimpleNamespace):
|
|
|
149
149
|
# This should always match the `react` version in DEPENDENCIES for recharts compatibility.
|
|
150
150
|
"react-is": _react_version,
|
|
151
151
|
"cookie": "1.0.2",
|
|
152
|
-
"rollup": "4.
|
|
152
|
+
"rollup": "4.45.1",
|
|
153
153
|
}
|
|
@@ -12,7 +12,6 @@ from pathlib import Path
|
|
|
12
12
|
from typing import Any
|
|
13
13
|
|
|
14
14
|
import click
|
|
15
|
-
import httpx
|
|
16
15
|
|
|
17
16
|
from reflex import constants
|
|
18
17
|
from reflex.constants import CustomComponents
|
|
@@ -467,6 +466,7 @@ def _collect_details_for_gallery():
|
|
|
467
466
|
Raises:
|
|
468
467
|
Exit: If pyproject.toml file is ill-formed or the request to the backend services fails.
|
|
469
468
|
"""
|
|
469
|
+
import httpx
|
|
470
470
|
from reflex_cli.utils import hosting
|
|
471
471
|
|
|
472
472
|
console.rule("[bold]Authentication with Reflex Services")
|
reflex/istate/data.py
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import dataclasses
|
|
4
4
|
from collections.abc import Mapping
|
|
5
5
|
from typing import TYPE_CHECKING
|
|
6
|
-
from urllib.parse import _NetlocResultMixinStr, urlsplit
|
|
6
|
+
from urllib.parse import _NetlocResultMixinStr, parse_qsl, urlsplit
|
|
7
7
|
|
|
8
8
|
from reflex import constants
|
|
9
9
|
from reflex.utils import console, format
|
|
@@ -102,8 +102,10 @@ class ReflexURL(str, _NetlocResultMixinStr):
|
|
|
102
102
|
if TYPE_CHECKING:
|
|
103
103
|
scheme: str
|
|
104
104
|
netloc: str
|
|
105
|
+
origin: str
|
|
105
106
|
path: str
|
|
106
107
|
query: str
|
|
108
|
+
query_parameters: Mapping[str, str]
|
|
107
109
|
fragment: str
|
|
108
110
|
|
|
109
111
|
def __new__(cls, url: str):
|
|
@@ -121,6 +123,10 @@ class ReflexURL(str, _NetlocResultMixinStr):
|
|
|
121
123
|
object.__setattr__(obj, "netloc", netloc)
|
|
122
124
|
object.__setattr__(obj, "path", path)
|
|
123
125
|
object.__setattr__(obj, "query", query)
|
|
126
|
+
object.__setattr__(obj, "origin", f"{scheme}://{netloc}")
|
|
127
|
+
object.__setattr__(
|
|
128
|
+
obj, "query_parameters", _FrozenDictStrStr(**dict(parse_qsl(query)))
|
|
129
|
+
)
|
|
124
130
|
object.__setattr__(obj, "fragment", fragment)
|
|
125
131
|
return obj
|
|
126
132
|
|
reflex/utils/console.py
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import contextlib
|
|
6
|
+
import datetime
|
|
6
7
|
import inspect
|
|
7
8
|
import os
|
|
8
9
|
import shutil
|
|
@@ -136,7 +137,7 @@ def print_to_log_file(msg: str, *, dedupe: bool = False, **kwargs):
|
|
|
136
137
|
dedupe: If True, suppress multiple console logs of print message.
|
|
137
138
|
kwargs: Keyword arguments to pass to the print function.
|
|
138
139
|
"""
|
|
139
|
-
log_file_console().print(msg, **kwargs)
|
|
140
|
+
log_file_console().print(f"[{datetime.datetime.now()}] {msg}", **kwargs)
|
|
140
141
|
|
|
141
142
|
|
|
142
143
|
def debug(msg: str, *, dedupe: bool = False, **kwargs):
|
reflex/utils/decorator.py
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
import functools
|
|
4
4
|
from collections.abc import Callable
|
|
5
|
-
from
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import ParamSpec, TypeVar, cast
|
|
6
7
|
|
|
7
8
|
T = TypeVar("T")
|
|
8
9
|
|
|
@@ -70,3 +71,77 @@ def debug(f: Callable[P, T]) -> Callable[P, T]:
|
|
|
70
71
|
return result
|
|
71
72
|
|
|
72
73
|
return wrapper
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def _write_cached_procedure_file(payload: str, cache_file: Path, value: object):
|
|
77
|
+
import pickle
|
|
78
|
+
|
|
79
|
+
cache_file.write_bytes(pickle.dumps((payload, value)))
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def _read_cached_procedure_file(cache_file: Path) -> tuple[str | None, object]:
|
|
83
|
+
import pickle
|
|
84
|
+
|
|
85
|
+
if cache_file.exists():
|
|
86
|
+
with cache_file.open("rb") as f:
|
|
87
|
+
return pickle.loads(f.read())
|
|
88
|
+
|
|
89
|
+
return None, None
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
P = ParamSpec("P")
|
|
93
|
+
Picklable = TypeVar("Picklable")
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def cached_procedure(
|
|
97
|
+
cache_file_path: Callable[[], Path],
|
|
98
|
+
payload_fn: Callable[P, str],
|
|
99
|
+
) -> Callable[[Callable[P, Picklable]], Callable[P, Picklable]]:
|
|
100
|
+
"""Decorator to cache the result of a function based on its arguments.
|
|
101
|
+
|
|
102
|
+
Args:
|
|
103
|
+
cache_file_path: Function that computes the cache file path.
|
|
104
|
+
payload_fn: Function that computes cache payload from function args.
|
|
105
|
+
|
|
106
|
+
Returns:
|
|
107
|
+
The decorated function.
|
|
108
|
+
"""
|
|
109
|
+
|
|
110
|
+
def _inner_decorator(func: Callable[P, Picklable]) -> Callable[P, Picklable]:
|
|
111
|
+
def _inner(*args: P.args, **kwargs: P.kwargs) -> Picklable:
|
|
112
|
+
_cache_file = cache_file_path()
|
|
113
|
+
|
|
114
|
+
payload, value = _read_cached_procedure_file(_cache_file)
|
|
115
|
+
new_payload = payload_fn(*args, **kwargs)
|
|
116
|
+
|
|
117
|
+
if payload != new_payload:
|
|
118
|
+
new_value = func(*args, **kwargs)
|
|
119
|
+
_write_cached_procedure_file(new_payload, _cache_file, new_value)
|
|
120
|
+
return new_value
|
|
121
|
+
|
|
122
|
+
from reflex.utils import console
|
|
123
|
+
|
|
124
|
+
console.debug(
|
|
125
|
+
f"Using cached value for {func.__name__} with payload: {new_payload}"
|
|
126
|
+
)
|
|
127
|
+
return cast("Picklable", value)
|
|
128
|
+
|
|
129
|
+
return _inner
|
|
130
|
+
|
|
131
|
+
return _inner_decorator
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def cache_result_in_disk(
|
|
135
|
+
cache_file_path: Callable[[], Path],
|
|
136
|
+
) -> Callable[[Callable[[], Picklable]], Callable[[], Picklable]]:
|
|
137
|
+
"""Decorator to cache the result of a function on disk.
|
|
138
|
+
|
|
139
|
+
Args:
|
|
140
|
+
cache_file_path: Function that computes the cache file path.
|
|
141
|
+
|
|
142
|
+
Returns:
|
|
143
|
+
The decorated function.
|
|
144
|
+
"""
|
|
145
|
+
return cached_procedure(
|
|
146
|
+
cache_file_path=cache_file_path, payload_fn=lambda: "constant"
|
|
147
|
+
)
|
reflex/utils/misc.py
CHANGED
|
@@ -90,3 +90,46 @@ def with_cwd_in_syspath():
|
|
|
90
90
|
yield
|
|
91
91
|
finally:
|
|
92
92
|
sys.path[:] = orig_sys_path
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def preload_color_theme():
|
|
96
|
+
"""Create a script component that preloads the color theme to prevent FOUC.
|
|
97
|
+
|
|
98
|
+
This script runs immediately in the document head before React hydration,
|
|
99
|
+
reading the saved theme from localStorage and applying the correct CSS classes
|
|
100
|
+
to prevent flash of unstyled content.
|
|
101
|
+
|
|
102
|
+
Returns:
|
|
103
|
+
Script: A script component to add to App.head_components
|
|
104
|
+
"""
|
|
105
|
+
from reflex.components.el.elements.scripts import Script
|
|
106
|
+
|
|
107
|
+
# Create direct inline script content (like next-themes dangerouslySetInnerHTML)
|
|
108
|
+
script_content = """
|
|
109
|
+
// Only run in browser environment, not during SSR
|
|
110
|
+
if (typeof document !== 'undefined') {
|
|
111
|
+
try {
|
|
112
|
+
const theme = localStorage.getItem("theme") || "system";
|
|
113
|
+
const systemPreference = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
114
|
+
const resolvedTheme = theme === "system" ? systemPreference : theme;
|
|
115
|
+
|
|
116
|
+
console.log("[PRELOAD] Theme applied:", resolvedTheme, "from theme:", theme, "system:", systemPreference);
|
|
117
|
+
|
|
118
|
+
// Apply theme immediately - blocks until complete
|
|
119
|
+
// Use classList to avoid overwriting other classes
|
|
120
|
+
document.documentElement.classList.remove("light", "dark");
|
|
121
|
+
document.documentElement.classList.add(resolvedTheme);
|
|
122
|
+
document.documentElement.style.colorScheme = resolvedTheme;
|
|
123
|
+
|
|
124
|
+
} catch (e) {
|
|
125
|
+
// Fallback to system preference on any error (resolve "system" to actual theme)
|
|
126
|
+
const fallbackTheme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
127
|
+
console.log("[PRELOAD] Error, falling back to:", fallbackTheme);
|
|
128
|
+
document.documentElement.classList.remove("light", "dark");
|
|
129
|
+
document.documentElement.classList.add(fallbackTheme);
|
|
130
|
+
document.documentElement.style.colorScheme = fallbackTheme;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
"""
|
|
134
|
+
|
|
135
|
+
return Script.create(script_content)
|
reflex/utils/net.py
CHANGED
|
@@ -5,8 +5,6 @@ import time
|
|
|
5
5
|
from collections.abc import Callable
|
|
6
6
|
from typing import ParamSpec, TypeVar
|
|
7
7
|
|
|
8
|
-
import httpx
|
|
9
|
-
|
|
10
8
|
from reflex.utils.decorator import once
|
|
11
9
|
from reflex.utils.types import Unset
|
|
12
10
|
|
|
@@ -42,6 +40,8 @@ def _wrap_https_func(
|
|
|
42
40
|
|
|
43
41
|
@functools.wraps(func)
|
|
44
42
|
def wrapper(*args: _P.args, **kwargs: _P.kwargs) -> _T:
|
|
43
|
+
import httpx
|
|
44
|
+
|
|
45
45
|
url = args[0]
|
|
46
46
|
console.debug(f"Sending HTTPS request to {args[0]}")
|
|
47
47
|
initial_time = time.time()
|
|
@@ -94,6 +94,8 @@ def _is_ipv4_supported() -> bool:
|
|
|
94
94
|
Returns:
|
|
95
95
|
True if the system supports IPv4, False otherwise.
|
|
96
96
|
"""
|
|
97
|
+
import httpx
|
|
98
|
+
|
|
97
99
|
try:
|
|
98
100
|
httpx.head("http://1.1.1.1", timeout=3)
|
|
99
101
|
except httpx.RequestError:
|
|
@@ -108,6 +110,8 @@ def _is_ipv6_supported() -> bool:
|
|
|
108
110
|
Returns:
|
|
109
111
|
True if the system supports IPv6, False otherwise.
|
|
110
112
|
"""
|
|
113
|
+
import httpx
|
|
114
|
+
|
|
111
115
|
try:
|
|
112
116
|
httpx.head("http://[2606:4700:4700::1111]", timeout=3)
|
|
113
117
|
except httpx.RequestError:
|
|
@@ -139,12 +143,13 @@ def _httpx_local_address_kwarg() -> str:
|
|
|
139
143
|
|
|
140
144
|
|
|
141
145
|
@once
|
|
142
|
-
def _httpx_client()
|
|
146
|
+
def _httpx_client():
|
|
143
147
|
"""Get an HTTPX client.
|
|
144
148
|
|
|
145
149
|
Returns:
|
|
146
150
|
An HTTPX client.
|
|
147
151
|
"""
|
|
152
|
+
import httpx
|
|
148
153
|
from httpx._utils import get_environment_proxies
|
|
149
154
|
|
|
150
155
|
return httpx.Client(
|
reflex/utils/prerequisites.py
CHANGED
|
@@ -19,7 +19,7 @@ import sys
|
|
|
19
19
|
import tempfile
|
|
20
20
|
import typing
|
|
21
21
|
import zipfile
|
|
22
|
-
from collections.abc import
|
|
22
|
+
from collections.abc import Sequence
|
|
23
23
|
from datetime import datetime
|
|
24
24
|
from pathlib import Path
|
|
25
25
|
from types import ModuleType
|
|
@@ -27,7 +27,6 @@ from typing import NamedTuple
|
|
|
27
27
|
from urllib.parse import urlparse
|
|
28
28
|
|
|
29
29
|
import click
|
|
30
|
-
import httpx
|
|
31
30
|
from alembic.util.exc import CommandError
|
|
32
31
|
from packaging import version
|
|
33
32
|
from redis import Redis as RedisSync
|
|
@@ -39,6 +38,7 @@ from reflex.compiler import templates
|
|
|
39
38
|
from reflex.config import Config, get_config
|
|
40
39
|
from reflex.environment import environment
|
|
41
40
|
from reflex.utils import console, net, path_ops, processes, redir
|
|
41
|
+
from reflex.utils.decorator import cached_procedure
|
|
42
42
|
from reflex.utils.exceptions import SystemPackageMissingError
|
|
43
43
|
from reflex.utils.misc import get_module_path
|
|
44
44
|
from reflex.utils.registry import get_npm_registry
|
|
@@ -1170,6 +1170,8 @@ def download_and_run(url: str, *args, show_status: bool = False, **env):
|
|
|
1170
1170
|
Raises:
|
|
1171
1171
|
Exit: If the script fails to download.
|
|
1172
1172
|
"""
|
|
1173
|
+
import httpx
|
|
1174
|
+
|
|
1173
1175
|
# Download the script
|
|
1174
1176
|
console.debug(f"Downloading {url}")
|
|
1175
1177
|
try:
|
|
@@ -1177,7 +1179,7 @@ def download_and_run(url: str, *args, show_status: bool = False, **env):
|
|
|
1177
1179
|
response.raise_for_status()
|
|
1178
1180
|
except httpx.HTTPError as e:
|
|
1179
1181
|
console.error(
|
|
1180
|
-
f"Failed to download bun install script. You can install or update bun manually from https://bun.
|
|
1182
|
+
f"Failed to download bun install script. You can install or update bun manually from https://bun.com \n{e}"
|
|
1181
1183
|
)
|
|
1182
1184
|
raise click.exceptions.Exit(1) from None
|
|
1183
1185
|
|
|
@@ -1251,71 +1253,9 @@ def install_bun():
|
|
|
1251
1253
|
)
|
|
1252
1254
|
|
|
1253
1255
|
|
|
1254
|
-
def _write_cached_procedure_file(payload: str, cache_file: str | Path):
|
|
1255
|
-
cache_file = Path(cache_file)
|
|
1256
|
-
cache_file.write_text(payload)
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
def _read_cached_procedure_file(cache_file: str | Path) -> str | None:
|
|
1260
|
-
cache_file = Path(cache_file)
|
|
1261
|
-
if cache_file.exists():
|
|
1262
|
-
return cache_file.read_text()
|
|
1263
|
-
return None
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
def _clear_cached_procedure_file(cache_file: str | Path):
|
|
1267
|
-
cache_file = Path(cache_file)
|
|
1268
|
-
if cache_file.exists():
|
|
1269
|
-
cache_file.unlink()
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
def cached_procedure(
|
|
1273
|
-
cache_file: str | None,
|
|
1274
|
-
payload_fn: Callable[..., str],
|
|
1275
|
-
cache_file_fn: Callable[[], str] | None = None,
|
|
1276
|
-
):
|
|
1277
|
-
"""Decorator to cache the runs of a procedure on disk. Procedures should not have
|
|
1278
|
-
a return value.
|
|
1279
|
-
|
|
1280
|
-
Args:
|
|
1281
|
-
cache_file: The file to store the cache payload in.
|
|
1282
|
-
payload_fn: Function that computes cache payload from function args.
|
|
1283
|
-
cache_file_fn: Function that computes the cache file name at runtime.
|
|
1284
|
-
|
|
1285
|
-
Returns:
|
|
1286
|
-
The decorated function.
|
|
1287
|
-
|
|
1288
|
-
Raises:
|
|
1289
|
-
ValueError: If both cache_file and cache_file_fn are provided.
|
|
1290
|
-
"""
|
|
1291
|
-
if cache_file and cache_file_fn is not None:
|
|
1292
|
-
msg = "cache_file and cache_file_fn cannot both be provided."
|
|
1293
|
-
raise ValueError(msg)
|
|
1294
|
-
|
|
1295
|
-
def _inner_decorator(func: Callable):
|
|
1296
|
-
def _inner(*args, **kwargs):
|
|
1297
|
-
_cache_file = cache_file_fn() if cache_file_fn is not None else cache_file
|
|
1298
|
-
if not _cache_file:
|
|
1299
|
-
msg = "Unknown cache file, cannot cache result."
|
|
1300
|
-
raise ValueError(msg)
|
|
1301
|
-
payload = _read_cached_procedure_file(_cache_file)
|
|
1302
|
-
new_payload = payload_fn(*args, **kwargs)
|
|
1303
|
-
if payload != new_payload:
|
|
1304
|
-
_clear_cached_procedure_file(_cache_file)
|
|
1305
|
-
func(*args, **kwargs)
|
|
1306
|
-
_write_cached_procedure_file(new_payload, _cache_file)
|
|
1307
|
-
|
|
1308
|
-
return _inner
|
|
1309
|
-
|
|
1310
|
-
return _inner_decorator
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
1256
|
@cached_procedure(
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
),
|
|
1317
|
-
payload_fn=lambda p, c: f"{sorted(p)!r},{c.json()}",
|
|
1318
|
-
cache_file=None,
|
|
1257
|
+
cache_file_path=lambda: get_web_dir() / "reflex.install_frontend_packages.cached",
|
|
1258
|
+
payload_fn=lambda packages, config: f"{sorted(packages)!r},{config.json()}",
|
|
1319
1259
|
)
|
|
1320
1260
|
def install_frontend_packages(packages: set[str], config: Config):
|
|
1321
1261
|
"""Installs the base and custom frontend packages.
|
|
@@ -1725,6 +1665,8 @@ def create_config_init_app_from_remote_template(app_name: str, template_url: str
|
|
|
1725
1665
|
Exit: If any download, file operations fail or unexpected zip file format.
|
|
1726
1666
|
|
|
1727
1667
|
"""
|
|
1668
|
+
import httpx
|
|
1669
|
+
|
|
1728
1670
|
# Create a temp directory for the zip download.
|
|
1729
1671
|
try:
|
|
1730
1672
|
temp_dir = tempfile.mkdtemp()
|
reflex/utils/processes.py
CHANGED
|
@@ -78,19 +78,41 @@ def _can_bind_at_port(
|
|
|
78
78
|
return True
|
|
79
79
|
|
|
80
80
|
|
|
81
|
-
def
|
|
81
|
+
def _can_bind_at_any_port(address_family: socket.AddressFamily | int) -> bool:
|
|
82
|
+
"""Check if any port is available for binding.
|
|
83
|
+
|
|
84
|
+
Args:
|
|
85
|
+
address_family: The address family (e.g., socket.AF_INET or socket.AF_INET6).
|
|
86
|
+
|
|
87
|
+
Returns:
|
|
88
|
+
Whether any port is available for binding.
|
|
89
|
+
"""
|
|
90
|
+
with closing(socket.socket(address_family, socket.SOCK_STREAM)) as sock:
|
|
91
|
+
try:
|
|
92
|
+
sock.bind(("", 0)) # Bind to any available port
|
|
93
|
+
except (OverflowError, PermissionError, OSError) as e:
|
|
94
|
+
console.debug(f"Unable to bind to any port for {address_family}: {e}")
|
|
95
|
+
return False
|
|
96
|
+
return True
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def is_process_on_port(
|
|
100
|
+
port: int,
|
|
101
|
+
address_families: Sequence[socket.AddressFamily | int] = (
|
|
102
|
+
socket.AF_INET,
|
|
103
|
+
socket.AF_INET6,
|
|
104
|
+
),
|
|
105
|
+
) -> bool:
|
|
82
106
|
"""Check if a process is running on the given port.
|
|
83
107
|
|
|
84
108
|
Args:
|
|
85
109
|
port: The port.
|
|
110
|
+
address_families: The address families to check (default: IPv4 and IPv6).
|
|
86
111
|
|
|
87
112
|
Returns:
|
|
88
113
|
Whether a process is running on the given port.
|
|
89
114
|
"""
|
|
90
|
-
return (
|
|
91
|
-
not _can_bind_at_port(socket.AF_INET, "", port) # Test IPv4 local network
|
|
92
|
-
or not _can_bind_at_port(socket.AF_INET6, "", port) # Test IPv6 local network
|
|
93
|
-
)
|
|
115
|
+
return any(not _can_bind_at_port(family, "", port) for family in address_families)
|
|
94
116
|
|
|
95
117
|
|
|
96
118
|
MAXIMUM_PORT = 2**16 - 1
|
|
@@ -113,13 +135,30 @@ def handle_port(service_name: str, port: int, auto_increment: bool) -> int:
|
|
|
113
135
|
"""
|
|
114
136
|
console.debug(f"Checking if {service_name.capitalize()} port: {port} is in use.")
|
|
115
137
|
|
|
116
|
-
|
|
138
|
+
families = [
|
|
139
|
+
address_family
|
|
140
|
+
for address_family in (socket.AF_INET, socket.AF_INET6)
|
|
141
|
+
if _can_bind_at_any_port(address_family)
|
|
142
|
+
]
|
|
143
|
+
|
|
144
|
+
if not families:
|
|
145
|
+
console.error(
|
|
146
|
+
f"Unable to bind to any port for {service_name}. "
|
|
147
|
+
"Please check your network configuration."
|
|
148
|
+
)
|
|
149
|
+
raise click.exceptions.Exit(1)
|
|
150
|
+
|
|
151
|
+
console.debug(
|
|
152
|
+
f"Checking if {service_name.capitalize()} port: {port} is in use for families: {families}."
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
if not is_process_on_port(port, families):
|
|
117
156
|
console.debug(f"{service_name.capitalize()} port: {port} is not in use.")
|
|
118
157
|
return port
|
|
119
158
|
|
|
120
159
|
if auto_increment:
|
|
121
160
|
for new_port in range(port + 1, MAXIMUM_PORT + 1):
|
|
122
|
-
if not is_process_on_port(new_port):
|
|
161
|
+
if not is_process_on_port(new_port, families):
|
|
123
162
|
console.info(
|
|
124
163
|
f"The {service_name} will run on port [bold underline]{new_port}[/bold underline]."
|
|
125
164
|
)
|
reflex/utils/redir.py
CHANGED
|
@@ -3,8 +3,6 @@
|
|
|
3
3
|
import time
|
|
4
4
|
import webbrowser
|
|
5
5
|
|
|
6
|
-
import httpx
|
|
7
|
-
|
|
8
6
|
from reflex import constants
|
|
9
7
|
from reflex.utils import net
|
|
10
8
|
|
|
@@ -25,9 +23,7 @@ def open_browser(target_url: str) -> None:
|
|
|
25
23
|
console.info(f"Opening browser to {target_url}.")
|
|
26
24
|
|
|
27
25
|
|
|
28
|
-
def open_browser_and_wait(
|
|
29
|
-
target_url: str, poll_url: str, interval: int = 2
|
|
30
|
-
) -> httpx.Response:
|
|
26
|
+
def open_browser_and_wait(target_url: str, poll_url: str, interval: int = 2):
|
|
31
27
|
"""Open a browser window to target_url and request poll_url until it returns successfully.
|
|
32
28
|
|
|
33
29
|
Args:
|
|
@@ -38,6 +34,8 @@ def open_browser_and_wait(
|
|
|
38
34
|
Returns:
|
|
39
35
|
The response from the poll_url.
|
|
40
36
|
"""
|
|
37
|
+
import httpx
|
|
38
|
+
|
|
41
39
|
open_browser(target_url)
|
|
42
40
|
console.info("[b]Complete the workflow in the browser to continue.[/b]")
|
|
43
41
|
while True:
|
reflex/utils/registry.py
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"""Utilities for working with registries."""
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
from pathlib import Path
|
|
4
4
|
|
|
5
5
|
from reflex.environment import environment
|
|
6
6
|
from reflex.utils import console, net
|
|
7
|
-
from reflex.utils.decorator import once
|
|
7
|
+
from reflex.utils.decorator import cache_result_in_disk, once
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
def latency(registry: str) -> int:
|
|
@@ -16,6 +16,8 @@ def latency(registry: str) -> int:
|
|
|
16
16
|
Returns:
|
|
17
17
|
int: The latency of the registry in microseconds.
|
|
18
18
|
"""
|
|
19
|
+
import httpx
|
|
20
|
+
|
|
19
21
|
try:
|
|
20
22
|
time_to_respond = net.get(registry, timeout=2).elapsed.microseconds
|
|
21
23
|
except httpx.HTTPError:
|
|
@@ -41,6 +43,16 @@ def average_latency(registry: str, attempts: int = 3) -> int:
|
|
|
41
43
|
return registry_latency
|
|
42
44
|
|
|
43
45
|
|
|
46
|
+
def _best_registry_file_path() -> Path:
|
|
47
|
+
"""Get the file path for the best registry cache.
|
|
48
|
+
|
|
49
|
+
Returns:
|
|
50
|
+
The file path for the best registry cache.
|
|
51
|
+
"""
|
|
52
|
+
return environment.REFLEX_DIR.get() / "reflex_best_registry.cached"
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
@cache_result_in_disk(cache_file_path=_best_registry_file_path)
|
|
44
56
|
def _get_best_registry() -> str:
|
|
45
57
|
"""Get the best registry based on latency.
|
|
46
58
|
|
reflex/utils/telemetry.py
CHANGED
|
@@ -12,8 +12,6 @@ from contextlib import suppress
|
|
|
12
12
|
from datetime import datetime, timezone
|
|
13
13
|
from typing import TypedDict
|
|
14
14
|
|
|
15
|
-
import httpx
|
|
16
|
-
|
|
17
15
|
from reflex import constants
|
|
18
16
|
from reflex.environment import environment
|
|
19
17
|
from reflex.utils import console
|
|
@@ -218,6 +216,8 @@ def _prepare_event(event: str, **kwargs) -> _Event | None:
|
|
|
218
216
|
|
|
219
217
|
|
|
220
218
|
def _send_event(event_data: _Event) -> bool:
|
|
219
|
+
import httpx
|
|
220
|
+
|
|
221
221
|
try:
|
|
222
222
|
httpx.post(POSTHOG_API_URL, json=event_data)
|
|
223
223
|
except Exception:
|
reflex/vars/dep_tracking.py
CHANGED
|
@@ -7,6 +7,7 @@ import dataclasses
|
|
|
7
7
|
import dis
|
|
8
8
|
import enum
|
|
9
9
|
import inspect
|
|
10
|
+
import sys
|
|
10
11
|
from types import CellType, CodeType, FunctionType
|
|
11
12
|
from typing import TYPE_CHECKING, Any, ClassVar, cast
|
|
12
13
|
|
|
@@ -60,9 +61,7 @@ class DependencyTracker:
|
|
|
60
61
|
tracked_locals: dict[str, type[BaseState]] = dataclasses.field(default_factory=dict)
|
|
61
62
|
|
|
62
63
|
_getting_state_class: type[BaseState] | None = dataclasses.field(default=None)
|
|
63
|
-
|
|
64
|
-
default_factory=list
|
|
65
|
-
)
|
|
64
|
+
_get_var_value_positions: dis.Positions | None = dataclasses.field(default=None)
|
|
66
65
|
|
|
67
66
|
INVALID_NAMES: ClassVar[list[str]] = ["parent_state", "substates", "get_substate"]
|
|
68
67
|
|
|
@@ -114,6 +113,8 @@ class DependencyTracker:
|
|
|
114
113
|
return
|
|
115
114
|
if instruction.argval == "get_var_value":
|
|
116
115
|
# Special case: arbitrary var access requested.
|
|
116
|
+
if sys.version_info >= (3, 11):
|
|
117
|
+
self._get_var_value_positions = instruction.positions
|
|
117
118
|
self.scan_status = ScanStatus.GETTING_VAR
|
|
118
119
|
return
|
|
119
120
|
|
|
@@ -222,9 +223,12 @@ class DependencyTracker:
|
|
|
222
223
|
self.scan_status = ScanStatus.SCANNING
|
|
223
224
|
self._getting_state_class = None
|
|
224
225
|
|
|
225
|
-
def _eval_var(self) -> Var:
|
|
226
|
+
def _eval_var(self, positions: dis.Positions) -> Var:
|
|
226
227
|
"""Evaluate instructions from the wrapped function to get the Var object.
|
|
227
228
|
|
|
229
|
+
Args:
|
|
230
|
+
positions: The disassembly positions of the get_var_value call.
|
|
231
|
+
|
|
228
232
|
Returns:
|
|
229
233
|
The Var object.
|
|
230
234
|
|
|
@@ -233,15 +237,13 @@ class DependencyTracker:
|
|
|
233
237
|
"""
|
|
234
238
|
# Get the original source code and eval it to get the Var.
|
|
235
239
|
module = inspect.getmodule(self.func)
|
|
236
|
-
|
|
237
|
-
positions1 = self._getting_var_instructions[-1].positions
|
|
238
|
-
if module is None or positions0 is None or positions1 is None:
|
|
240
|
+
if module is None or self._get_var_value_positions is None:
|
|
239
241
|
msg = f"Cannot determine the source code for the var in {self.func!r}."
|
|
240
242
|
raise VarValueError(msg)
|
|
241
|
-
start_line =
|
|
242
|
-
start_column =
|
|
243
|
-
end_line =
|
|
244
|
-
end_column =
|
|
243
|
+
start_line = self._get_var_value_positions.end_lineno
|
|
244
|
+
start_column = self._get_var_value_positions.end_col_offset
|
|
245
|
+
end_line = positions.end_lineno
|
|
246
|
+
end_column = positions.end_col_offset
|
|
245
247
|
if (
|
|
246
248
|
start_line is None
|
|
247
249
|
or start_column is None
|
|
@@ -254,14 +256,10 @@ class DependencyTracker:
|
|
|
254
256
|
# Create a python source string snippet.
|
|
255
257
|
if len(source) > 1:
|
|
256
258
|
snipped_source = "".join(
|
|
257
|
-
[
|
|
258
|
-
*source[0][start_column:],
|
|
259
|
-
*(source[1:-2] if len(source) > 2 else []),
|
|
260
|
-
*source[-1][: end_column - 1],
|
|
261
|
-
]
|
|
259
|
+
[*source[0][start_column:], *source[1:-1], *source[-1][:end_column]]
|
|
262
260
|
)
|
|
263
261
|
else:
|
|
264
|
-
snipped_source = source[0][start_column
|
|
262
|
+
snipped_source = source[0][start_column:end_column]
|
|
265
263
|
# Evaluate the string in the context of the function's globals and closure.
|
|
266
264
|
return eval(f"({snipped_source})", self._get_globals(), self._get_closure())
|
|
267
265
|
|
|
@@ -279,20 +277,19 @@ class DependencyTracker:
|
|
|
279
277
|
Raises:
|
|
280
278
|
VarValueError: if the source code for the var cannot be determined.
|
|
281
279
|
"""
|
|
282
|
-
if instruction.opname == "CALL"
|
|
283
|
-
if
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
self.
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
280
|
+
if instruction.opname == "CALL":
|
|
281
|
+
if instruction.positions is None:
|
|
282
|
+
msg = f"Cannot determine the source code for the var in {self.func!r}."
|
|
283
|
+
raise VarValueError(msg)
|
|
284
|
+
the_var = self._eval_var(instruction.positions)
|
|
285
|
+
the_var_data = the_var._get_all_var_data()
|
|
286
|
+
if the_var_data is None:
|
|
287
|
+
msg = f"Cannot determine the source code for the var in {self.func!r}."
|
|
288
|
+
raise VarValueError(msg)
|
|
289
|
+
self.dependencies.setdefault(the_var_data.state, set()).add(
|
|
290
|
+
the_var_data.field_name
|
|
291
|
+
)
|
|
293
292
|
self.scan_status = ScanStatus.SCANNING
|
|
294
|
-
else:
|
|
295
|
-
self._getting_var_instructions.append(instruction)
|
|
296
293
|
|
|
297
294
|
def _populate_dependencies(self) -> None:
|
|
298
295
|
"""Update self.dependencies based on the disassembly of self.func.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: reflex
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.4a1
|
|
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
|
|
@@ -20,7 +20,6 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
20
20
|
Requires-Python: <4.0,>=3.10
|
|
21
21
|
Requires-Dist: alembic<2.0,>=1.15.2
|
|
22
22
|
Requires-Dist: click>=8.2
|
|
23
|
-
Requires-Dist: fastapi>=0.115.0
|
|
24
23
|
Requires-Dist: granian[reload]>=2.4.0
|
|
25
24
|
Requires-Dist: httpx<1.0,>=0.28.0
|
|
26
25
|
Requires-Dist: jinja2<4.0,>=3.1.2
|
|
@@ -34,6 +33,7 @@ Requires-Dist: redis<7.0,>=5.2.1
|
|
|
34
33
|
Requires-Dist: reflex-hosting-cli>=0.1.51
|
|
35
34
|
Requires-Dist: rich<15,>=13
|
|
36
35
|
Requires-Dist: sqlmodel<0.1,>=0.0.24
|
|
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
39
|
Description-Content-Type: text/markdown
|
|
@@ -2,7 +2,7 @@ reflex/__init__.py,sha256=xGw7ZbGlWsa-OShPv-I81RuUOACxHGTQFlX17x5n9Hg,10328
|
|
|
2
2
|
reflex/__init__.pyi,sha256=GfoYvxYXK1GFGbUsMA8Su7IFoqupV_xxG6__KSgnitA,10097
|
|
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=
|
|
5
|
+
reflex/app.py,sha256=w2VOaN8ZwxQgW8AXnXnXy1Yubcks2DgbPt3Z8n_MTHM,75036
|
|
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=HgJ57Op-glTro23GoQKmyXwUplvGYgZFKjvClYpD27s,19359
|
|
@@ -51,8 +51,8 @@ reflex/.templates/web/components/reflex/radix_themes_color_mode_provider.js,sha2
|
|
|
51
51
|
reflex/.templates/web/components/shiki/code.js,sha256=4Es1pxsr-lX4hTQ5mglrwwC6O_SI-z-O60k03z8VFzQ,1144
|
|
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
|
-
reflex/.templates/web/utils/react-theme.js,sha256=
|
|
55
|
-
reflex/.templates/web/utils/state.js,sha256=
|
|
54
|
+
reflex/.templates/web/utils/react-theme.js,sha256=LRnJCHijMMIjDAy-hs7INgJXXGjbyAUD0qm_kFOP-BU,2800
|
|
55
|
+
reflex/.templates/web/utils/state.js,sha256=Z9NeC1sjePtIg03kvxILng-1ri_PNZFAM_t64K4d5Dg,36162
|
|
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
|
|
@@ -65,7 +65,7 @@ reflex/app_mixins/mixin.py,sha256=R1YncalqDrbdPZvpKVbm72ZKmQZxYAWfuFq9JknzTqQ,30
|
|
|
65
65
|
reflex/compiler/__init__.py,sha256=r8jqmDSFf09iV2lHlNhfc9XrTLjNxfDNwPYlxS4cmHE,27
|
|
66
66
|
reflex/compiler/compiler.py,sha256=r-qvhlz0I7Gw__rIFRjt2vCbUYW2yl-rHvznyO7SS4Q,28835
|
|
67
67
|
reflex/compiler/templates.py,sha256=mQifVgvE7cKyzMFL9F5jxdJb9KFxucWJa7nuOp09ZUo,6002
|
|
68
|
-
reflex/compiler/utils.py,sha256=
|
|
68
|
+
reflex/compiler/utils.py,sha256=Eo0-zLCj4rFhkVZQNWSMoMSGTSAkHIivoNwoAgMBYi8,19266
|
|
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=0ZouhQgfO5hAbKu3Z4ytM0jvaz70U0Uab9SrIewdUbQ,99431
|
|
@@ -344,17 +344,17 @@ reflex/constants/compiler.py,sha256=VoA1vWZpl-2EdIOhAiOLwSX4S-bFLbkiESlNBmN08NQ,
|
|
|
344
344
|
reflex/constants/config.py,sha256=8OIjiBdZZJrRVHsNBheMwopE9AwBFFzau0SXqXKcrPg,1715
|
|
345
345
|
reflex/constants/custom_components.py,sha256=joJt4CEt1yKy7wsBH6vYo7_QRW0O_fWXrrTf0VY2q14,1317
|
|
346
346
|
reflex/constants/event.py,sha256=tgoynWQi2L0_Kqc3XhXo7XXL76A-OKhJGHRrNjm7gFw,2885
|
|
347
|
-
reflex/constants/installer.py,sha256=
|
|
347
|
+
reflex/constants/installer.py,sha256=VBYFL9BHD0m6cO6RjTQm_PD3JIV63LEl-TtkFJxKkUI,4141
|
|
348
348
|
reflex/constants/route.py,sha256=UBjqaAOxiUxlDZCSY4O2JJChKvA4MZrhUU0E5rNvKbM,2682
|
|
349
349
|
reflex/constants/state.py,sha256=uF_7-M9Gid-P3DjAOq4F1ERplyZhiNccowo_jLrdJrg,323
|
|
350
350
|
reflex/constants/utils.py,sha256=e1ChEvbHfmE_V2UJvCSUhD_qTVAIhEGPpRJSqdSd6PA,780
|
|
351
351
|
reflex/custom_components/__init__.py,sha256=R4zsvOi4dfPmHc18KEphohXnQFBPnUCb50cMR5hSLDE,36
|
|
352
|
-
reflex/custom_components/custom_components.py,sha256=
|
|
352
|
+
reflex/custom_components/custom_components.py,sha256=IPW7Kbtyr8vjk1FzXRsCyCaLJTlaLQMYjOxgf1WK_jg,20210
|
|
353
353
|
reflex/experimental/__init__.py,sha256=P8fe8S2e2gy2HCwHFGQzr3lPMmh7qN5Ii2e8ukoPHuQ,1664
|
|
354
354
|
reflex/experimental/client_state.py,sha256=1VOe6rYhpOBOZi7-tZwfOnSNPPdX3tsXzlfgNs7aDrg,10020
|
|
355
355
|
reflex/experimental/hooks.py,sha256=CHYGrAE5t8riltrJmDFgJ4D2Vhmhw-y3B3MSGNlOQow,2366
|
|
356
356
|
reflex/istate/__init__.py,sha256=afq_pCS5B_REC-Kl3Rbaa538uWi59xNz4INeuENcWnk,2039
|
|
357
|
-
reflex/istate/data.py,sha256=
|
|
357
|
+
reflex/istate/data.py,sha256=KrANpAQFTZcfFWnxyykgK1FRNuXTwTin1WYpyqymV-U,7547
|
|
358
358
|
reflex/istate/dynamic.py,sha256=xOQ9upZVPf6ngqcLQZ9HdAAYmoWwJ8kRFPH34Q5HTiM,91
|
|
359
359
|
reflex/istate/manager.py,sha256=te5uQN6n-ctOGrf6NbZUVy6BKgWapLlMtCzDaO6RthU,30412
|
|
360
360
|
reflex/istate/proxy.py,sha256=Q8JrV1m6drVcTNJL9JuN-nKUXclazs96OHl_fhR0UBk,25928
|
|
@@ -373,36 +373,36 @@ reflex/utils/__init__.py,sha256=y-AHKiRQAhk2oAkvn7W8cRVTZVK625ff8tTwvZtO7S4,24
|
|
|
373
373
|
reflex/utils/build.py,sha256=lk8hE69onG95dv-LxRhjtEugct1g-KcWPUDorzqeGIE,7964
|
|
374
374
|
reflex/utils/codespaces.py,sha256=kEQ-j-jclTukFpXDlYgNp95kYMGDrQmP3VNEoYGZ1u4,3052
|
|
375
375
|
reflex/utils/compat.py,sha256=aSJH_M6iomgHPQ4onQ153xh1MWqPi3HSYDzE68N6gZM,2635
|
|
376
|
-
reflex/utils/console.py,sha256=
|
|
377
|
-
reflex/utils/decorator.py,sha256=
|
|
376
|
+
reflex/utils/console.py,sha256=QIOgyElaxSVM1Bbvz0zx77-MqkDZkfpu1d6l26VRkQ0,11580
|
|
377
|
+
reflex/utils/decorator.py,sha256=P5xP2kZsJnNdc91x2dou9_Z8U3q4YkPDB-vpfE3CZtU,3900
|
|
378
378
|
reflex/utils/exceptions.py,sha256=Wwu7Ji2xgq521bJKtU2NgjwhmFfnG8erirEVN2h8S-g,8884
|
|
379
379
|
reflex/utils/exec.py,sha256=KQ5tS5vz3wuu9zDGPR6clSE0IoY_vcIbJGCB5bqiDJM,21987
|
|
380
380
|
reflex/utils/export.py,sha256=Z2AHuhkxGQzOi9I90BejQ4qEcD0URr2i-ZU5qTJt7eQ,2562
|
|
381
381
|
reflex/utils/format.py,sha256=FZe5NA0U3K0n0k7r8RIGcx-eHpN7sf8eQX9w1C8_uR8,21120
|
|
382
382
|
reflex/utils/imports.py,sha256=Ov-lqv-PfsPl3kTEW13r5aDauIfn6TqzEMyv42RKLOA,3761
|
|
383
383
|
reflex/utils/lazy_loader.py,sha256=BiY9OvmAJDCz10qpuyTYv9duXgMFQa6RXKQmTO9hqKU,4453
|
|
384
|
-
reflex/utils/misc.py,sha256=
|
|
385
|
-
reflex/utils/net.py,sha256=
|
|
384
|
+
reflex/utils/misc.py,sha256=tP_mVuLG38W8-KGwRDm0mJpKjzTYv4oKjPUxkYD5pFU,4781
|
|
385
|
+
reflex/utils/net.py,sha256=GXq5KNmYowT-BP4o9HmEqKthm-N9nj82KH8es3EeTWI,4138
|
|
386
386
|
reflex/utils/path_ops.py,sha256=_RS17IQDNr5vcoLLGZx2-z1E5WP-JgDHvaRAOgqrZiU,8154
|
|
387
|
-
reflex/utils/prerequisites.py,sha256=
|
|
388
|
-
reflex/utils/processes.py,sha256=
|
|
387
|
+
reflex/utils/prerequisites.py,sha256=8S_Yn3n2ojiqwDkpVmTqbxnTY7ILobFSm4f2MjYXtAw,64129
|
|
388
|
+
reflex/utils/processes.py,sha256=szY-jWXVdpMF48q5sVaxTW_KiJOUKgTVPhl-C519NsQ,18182
|
|
389
389
|
reflex/utils/pyi_generator.py,sha256=HdmUVs50Bk7MAMFSvpATRhH--_50w-9URMFnjLlwT40,46086
|
|
390
|
-
reflex/utils/redir.py,sha256=
|
|
391
|
-
reflex/utils/registry.py,sha256=
|
|
390
|
+
reflex/utils/redir.py,sha256=E6lJ6UYGQs_uCyQAKHT_dDMplo5IRZ9JarWfvgGAgGo,1731
|
|
391
|
+
reflex/utils/registry.py,sha256=omKh5rrsybDuuKmh4K88lwdwwcpGsu3Vc4pCko_djKY,2239
|
|
392
392
|
reflex/utils/serializers.py,sha256=sVLfbWIBKPpmo0CVVxoxXGu0K3R9mYMWgaI02LXZmcM,13952
|
|
393
|
-
reflex/utils/telemetry.py,sha256=
|
|
393
|
+
reflex/utils/telemetry.py,sha256=XpPbFmlFdEh5uJl5vXoLyCCFv1choJN8EMko0MujigQ,7452
|
|
394
394
|
reflex/utils/types.py,sha256=jFHfd2-yHWV61L7YP2gc9Zj2ZLwdthHOOfRIc_PAWH0,38390
|
|
395
395
|
reflex/vars/__init__.py,sha256=85eXMt32bFoKtMdH3KxYRMD8mtnKyYiQcThPxJLoW1k,1359
|
|
396
396
|
reflex/vars/base.py,sha256=IGCU5iwZSsVMPVQqODEjmHJrskqfpfMIQ2yzcVFMoSQ,112940
|
|
397
397
|
reflex/vars/datetime.py,sha256=F2Jv_bfydipFSkIQ1F6x5MnSgFEyES9Vq5RG_uGH81E,5118
|
|
398
|
-
reflex/vars/dep_tracking.py,sha256=
|
|
398
|
+
reflex/vars/dep_tracking.py,sha256=LfDGgAGlqfC0DeiVcitRBcA1uCe1C3fNRARRekLgCz4,13738
|
|
399
399
|
reflex/vars/function.py,sha256=0i-VkxHkDJmZtfQUwUfaF0rlS6WM8azjwQ8k7rEOkyk,13944
|
|
400
400
|
reflex/vars/number.py,sha256=tO7pnvFaBsedq1HWT4skytnSqHWMluGEhUbjAUMx8XQ,28190
|
|
401
401
|
reflex/vars/object.py,sha256=BDmeiwG8v97s_BnR1Egq3NxOKVjv9TfnREB3cz0zZtk,17322
|
|
402
402
|
reflex/vars/sequence.py,sha256=1kBrqihspyjyQ1XDqFPC8OpVGtZs_EVkOdIKBro5ilA,55249
|
|
403
403
|
scripts/hatch_build.py,sha256=-4pxcLSFmirmujGpQX9UUxjhIC03tQ_fIQwVbHu9kc0,1861
|
|
404
|
-
reflex-0.8.
|
|
405
|
-
reflex-0.8.
|
|
406
|
-
reflex-0.8.
|
|
407
|
-
reflex-0.8.
|
|
408
|
-
reflex-0.8.
|
|
404
|
+
reflex-0.8.4a1.dist-info/METADATA,sha256=wzr6Xa_YGUJDS051hxGUEVoLq1tWxK6CaYPOMcyPIZw,12372
|
|
405
|
+
reflex-0.8.4a1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
406
|
+
reflex-0.8.4a1.dist-info/entry_points.txt,sha256=Rxt4dXc7MLBNt5CSHTehVPuSe9Xqow4HLX55nD9tQQ0,45
|
|
407
|
+
reflex-0.8.4a1.dist-info/licenses/LICENSE,sha256=dw3zLrp9f5ObD7kqS32vWfhcImfO52PMmRqvtxq_YEE,11358
|
|
408
|
+
reflex-0.8.4a1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|