reflex 0.3.5a1__py3-none-any.whl → 0.3.5a3__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.

Files changed (36) hide show
  1. reflex/.templates/jinja/web/pages/custom_component.js.jinja2 +3 -0
  2. reflex/.templates/jinja/web/utils/context.js.jinja2 +5 -0
  3. reflex/.templates/web/utils/state.js +9 -4
  4. reflex/app.py +6 -5
  5. reflex/app.pyi +1 -1
  6. reflex/compiler/templates.py +1 -0
  7. reflex/compiler/utils.py +1 -0
  8. reflex/components/base/head.py +2 -2
  9. reflex/components/base/head.pyi +4 -7
  10. reflex/components/component.py +69 -18
  11. reflex/components/forms/input.py +3 -1
  12. reflex/components/forms/input.pyi +1 -1
  13. reflex/components/graphing/recharts/charts.pyi +2 -5
  14. reflex/components/graphing/recharts/general.py +2 -1
  15. reflex/components/graphing/recharts/general.pyi +4 -6
  16. reflex/components/graphing/recharts/recharts.py +4 -4
  17. reflex/components/graphing/recharts/recharts.pyi +4 -7
  18. reflex/components/layout/cond.py +2 -2
  19. reflex/components/layout/foreach.py +3 -0
  20. reflex/components/media/icon.py +2 -2
  21. reflex/components/media/icon.pyi +2 -2
  22. reflex/components/typography/markdown.py +19 -5
  23. reflex/components/typography/markdown.pyi +4 -0
  24. reflex/constants/__init__.py +6 -0
  25. reflex/constants/compiler.py +23 -0
  26. reflex/constants/route.py +4 -0
  27. reflex/event.py +11 -1
  28. reflex/middleware/hydrate_middleware.py +2 -8
  29. reflex/state.py +21 -1
  30. reflex/utils/prerequisites.py +8 -0
  31. reflex/vars.py +23 -0
  32. {reflex-0.3.5a1.dist-info → reflex-0.3.5a3.dist-info}/METADATA +1 -1
  33. {reflex-0.3.5a1.dist-info → reflex-0.3.5a3.dist-info}/RECORD +36 -36
  34. {reflex-0.3.5a1.dist-info → reflex-0.3.5a3.dist-info}/LICENSE +0 -0
  35. {reflex-0.3.5a1.dist-info → reflex-0.3.5a3.dist-info}/WHEEL +0 -0
  36. {reflex-0.3.5a1.dist-info → reflex-0.3.5a3.dist-info}/entry_points.txt +0 -0
@@ -22,6 +22,9 @@ export const {{component.name}} = memo(({ {{-component.props|join(", ")-}} }) =>
22
22
 
23
23
  }
24
24
  {% endif %}
25
+ {% for hook in component.hooks %}
26
+ {{ hook }}
27
+ {% endfor %}
25
28
  return(
26
29
  {{utils.render(component.render)}}
27
30
  )
@@ -23,10 +23,15 @@ export const clientStorage = {}
23
23
  {% endif %}
24
24
 
25
25
  {% if state_name %}
26
+ export const onLoadInternalEvent = () => [Event('{{state_name}}.{{const.on_load_internal}}')]
27
+
26
28
  export const initialEvents = () => [
27
29
  Event('{{state_name}}.{{const.hydrate}}', hydrateClientStorage(clientStorage)),
30
+ ...onLoadInternalEvent()
28
31
  ]
29
32
  {% else %}
33
+ export const onLoadInternalEvent = () => []
34
+
30
35
  export const initialEvents = () => []
31
36
  {% endif %}
32
37
 
@@ -6,7 +6,7 @@ import env from "env.json";
6
6
  import Cookies from "universal-cookie";
7
7
  import { useEffect, useReducer, useRef, useState } from "react";
8
8
  import Router, { useRouter } from "next/router";
9
- import { initialEvents, initialState } from "utils/context.js"
9
+ import { initialEvents, initialState, onLoadInternalEvent } from "utils/context.js"
10
10
 
11
11
  // Endpoint URLs.
12
12
  const EVENTURL = env.EVENT
@@ -529,10 +529,15 @@ export const useEventLoop = (
529
529
  }
530
530
 
531
531
  const sentHydrate = useRef(false); // Avoid double-hydrate due to React strict-mode
532
- // initial state hydrate
533
532
  useEffect(() => {
534
533
  if (router.isReady && !sentHydrate.current) {
535
- addEvents(initial_events())
534
+ const events = initial_events()
535
+ addEvents(events.map((e) => (
536
+ {
537
+ ...e,
538
+ router_data: (({ pathname, query, asPath }) => ({ pathname, query, asPath }))(router)
539
+ }
540
+ )))
536
541
  sentHydrate.current = true
537
542
  }
538
543
  }, [router.isReady])
@@ -560,7 +565,7 @@ export const useEventLoop = (
560
565
 
561
566
  // Route after the initial page hydration.
562
567
  useEffect(() => {
563
- const change_complete = () => addEvents(initial_events())
568
+ const change_complete = () => addEvents(onLoadInternalEvent())
564
569
  router.events.on('routeChangeComplete', change_complete)
565
570
  return () => {
566
571
  router.events.off('routeChangeComplete', change_complete)
reflex/app.py CHANGED
@@ -161,11 +161,12 @@ class App(Base):
161
161
  "rx.BaseState cannot be subclassed multiple times. use rx.State instead"
162
162
  )
163
163
 
164
- # verify that provided state is valid
165
- if self.state and self.state is not State:
166
- console.warn(
167
- f"Using substate ({self.state.__name__}) as root state in `rx.App` is currently not supported."
168
- f" Defaulting to root state: ({State.__name__})"
164
+ if "state" in kwargs:
165
+ console.deprecate(
166
+ feature_name="`state` argument for App()",
167
+ reason="due to all `rx.State` subclasses being inferred.",
168
+ deprecation_version="0.3.5",
169
+ removal_version="0.4.0",
169
170
  )
170
171
  self.state = State
171
172
  # Get the config
reflex/app.pyi CHANGED
@@ -125,7 +125,7 @@ class App(Base):
125
125
  self, state: State, event: Event
126
126
  ) -> asyncio.Task | None: ...
127
127
 
128
- async def process(
128
+ def process(
129
129
  app: App, event: Event, sid: str, headers: Dict, client_ip: str
130
130
  ) -> AsyncIterator[StateUpdate]: ...
131
131
  async def ping() -> str: ...
@@ -40,6 +40,7 @@ class ReflexJinjaEnvironment(Environment):
40
40
  "toggle_color_mode": constants.ColorMode.TOGGLE,
41
41
  "use_color_mode": constants.ColorMode.USE,
42
42
  "hydrate": constants.CompileVars.HYDRATE,
43
+ "on_load_internal": constants.CompileVars.ON_LOAD_INTERNAL,
43
44
  }
44
45
 
45
46
 
reflex/compiler/utils.py CHANGED
@@ -254,6 +254,7 @@ def compile_custom_component(
254
254
  "name": component.tag,
255
255
  "props": props,
256
256
  "render": render.render(),
257
+ "hooks": render.get_hooks(),
257
258
  "custom_code": render.get_custom_code(),
258
259
  },
259
260
  imports,
@@ -1,6 +1,6 @@
1
1
  """The head component."""
2
2
 
3
- from reflex.components.component import Component
3
+ from reflex.components.component import Component, MemoizationLeaf
4
4
 
5
5
 
6
6
  class NextHeadLib(Component):
@@ -9,7 +9,7 @@ class NextHeadLib(Component):
9
9
  library = "next/head"
10
10
 
11
11
 
12
- class Head(NextHeadLib):
12
+ class Head(NextHeadLib, MemoizationLeaf):
13
13
  """Head Component."""
14
14
 
15
15
  tag = "NextHead"
@@ -7,7 +7,7 @@ from typing import Any, Dict, Literal, Optional, Union, overload
7
7
  from reflex.vars import Var, BaseVar, ComputedVar
8
8
  from reflex.event import EventChain, EventHandler, EventSpec
9
9
  from reflex.style import Style
10
- from reflex.components.component import Component
10
+ from reflex.components.component import Component, MemoizationLeaf
11
11
 
12
12
  class NextHeadLib(Component):
13
13
  @overload
@@ -88,7 +88,7 @@ class NextHeadLib(Component):
88
88
  """
89
89
  ...
90
90
 
91
- class Head(NextHeadLib):
91
+ class Head(NextHeadLib, MemoizationLeaf):
92
92
  @overload
93
93
  @classmethod
94
94
  def create( # type: ignore
@@ -147,7 +147,7 @@ class Head(NextHeadLib):
147
147
  ] = None,
148
148
  **props
149
149
  ) -> "Head":
150
- """Create the component.
150
+ """Create a new memoization leaf component.
151
151
 
152
152
  Args:
153
153
  *children: The children of the component.
@@ -160,9 +160,6 @@ class Head(NextHeadLib):
160
160
  **props: The props of the component.
161
161
 
162
162
  Returns:
163
- The component.
164
-
165
- Raises:
166
- TypeError: If an invalid child is passed.
163
+ The memoization leaf
167
164
  """
168
165
  ...
@@ -23,7 +23,15 @@ from typing import (
23
23
  from reflex.base import Base
24
24
  from reflex.compiler.templates import STATEFUL_COMPONENT
25
25
  from reflex.components.tags import Tag
26
- from reflex.constants import Dirs, EventTriggers, Hooks, Imports, PageNames
26
+ from reflex.constants import (
27
+ Dirs,
28
+ EventTriggers,
29
+ Hooks,
30
+ Imports,
31
+ MemoizationDisposition,
32
+ MemoizationMode,
33
+ PageNames,
34
+ )
27
35
  from reflex.event import (
28
36
  EventChain,
29
37
  EventHandler,
@@ -150,6 +158,9 @@ class Component(BaseComponent, ABC):
150
158
  # custom attribute
151
159
  custom_attrs: Dict[str, Union[Var, str]] = {}
152
160
 
161
+ # When to memoize this component and its children.
162
+ _memoization_mode: MemoizationMode = MemoizationMode()
163
+
153
164
  @classmethod
154
165
  def __init_subclass__(cls, **kwargs):
155
166
  """Set default properties.
@@ -1353,20 +1364,29 @@ class StatefulComponent(BaseComponent):
1353
1364
  """
1354
1365
  from reflex.components.layout.foreach import Foreach
1355
1366
 
1367
+ if component._memoization_mode.disposition == MemoizationDisposition.NEVER:
1368
+ # Never memoize this component.
1369
+ return None
1370
+
1356
1371
  if component.tag is None:
1357
1372
  # Only memoize components with a tag.
1358
1373
  return None
1359
1374
 
1360
1375
  # If _var_data is found in this component, it is a candidate for auto-memoization.
1361
- has_var_data = False
1376
+ should_memoize = False
1362
1377
 
1363
- # Determine if any Vars have associated data.
1364
- for prop_var in component._get_vars():
1365
- if prop_var._var_data:
1366
- has_var_data = True
1367
- break
1378
+ # If the component requests to be memoized, then ignore other checks.
1379
+ if component._memoization_mode.disposition == MemoizationDisposition.ALWAYS:
1380
+ should_memoize = True
1368
1381
 
1369
- if not has_var_data:
1382
+ if not should_memoize:
1383
+ # Determine if any Vars have associated data.
1384
+ for prop_var in component._get_vars():
1385
+ if prop_var._var_data:
1386
+ should_memoize = True
1387
+ break
1388
+
1389
+ if not should_memoize:
1370
1390
  # Check for special-cases in child components.
1371
1391
  for child in component.children:
1372
1392
  # Skip BaseComponent and StatefulComponent children.
@@ -1374,14 +1394,14 @@ class StatefulComponent(BaseComponent):
1374
1394
  continue
1375
1395
  # Always consider Foreach something that must be memoized by the parent.
1376
1396
  if isinstance(child, Foreach):
1377
- has_var_data = True
1397
+ should_memoize = True
1378
1398
  break
1379
1399
  child = cls._child_var(child)
1380
1400
  if isinstance(child, Var) and child._var_data:
1381
- has_var_data = True
1401
+ should_memoize = True
1382
1402
  break
1383
1403
 
1384
- if has_var_data or component.event_triggers:
1404
+ if should_memoize or component.event_triggers:
1385
1405
  # Render the component to determine tag+hash based on component code.
1386
1406
  tag_name = cls._get_tag_name(component)
1387
1407
  if tag_name is None:
@@ -1643,15 +1663,46 @@ class StatefulComponent(BaseComponent):
1643
1663
  Returns:
1644
1664
  The memoized component tree.
1645
1665
  """
1646
- from reflex.components.layout.foreach import Foreach
1647
-
1648
- # Foreach must be memoized as a single component to retain index Var context.
1649
- if not isinstance(component, Foreach):
1650
- component.children = [
1651
- cls.compile_from(child) for child in component.children
1652
- ]
1653
1666
  if isinstance(component, Component):
1667
+ if component._memoization_mode.recursive:
1668
+ # Recursively memoize stateful children (default).
1669
+ component.children = [
1670
+ cls.compile_from(child) for child in component.children
1671
+ ]
1672
+ # Memoize this component if it depends on state.
1654
1673
  stateful_component = cls.create(component)
1655
1674
  if stateful_component is not None:
1656
1675
  return stateful_component
1657
1676
  return component
1677
+
1678
+
1679
+ class MemoizationLeaf(Component):
1680
+ """A component that does not separately memoize its children.
1681
+
1682
+ Any component which depends on finding the exact names of children
1683
+ components within it, should be a memoization leaf so the compiler
1684
+ does not replace the provided child tags with memoized tags.
1685
+
1686
+ During creation, a memoization leaf will mark itself as wanting to be
1687
+ memoized if any of its children return any hooks.
1688
+ """
1689
+
1690
+ _memoization_mode = MemoizationMode(recursive=False)
1691
+
1692
+ @classmethod
1693
+ def create(cls, *children, **props) -> Component:
1694
+ """Create a new memoization leaf component.
1695
+
1696
+ Args:
1697
+ *children: The children of the component.
1698
+ **props: The props of the component.
1699
+
1700
+ Returns:
1701
+ The memoization leaf
1702
+ """
1703
+ comp = super().create(*children, **props)
1704
+ if comp.get_hooks():
1705
+ comp._memoization_mode = cls._memoization_mode.copy(
1706
+ update={"disposition": MemoizationDisposition.ALWAYS}
1707
+ )
1708
+ return comp
@@ -9,7 +9,7 @@ from reflex.components.libs.chakra import (
9
9
  LiteralButtonSize,
10
10
  LiteralInputVariant,
11
11
  )
12
- from reflex.constants import EventTriggers
12
+ from reflex.constants import EventTriggers, MemoizationMode
13
13
  from reflex.utils import imports
14
14
  from reflex.vars import Var
15
15
 
@@ -107,6 +107,8 @@ class InputGroup(ChakraComponent):
107
107
 
108
108
  tag = "InputGroup"
109
109
 
110
+ _memoization_mode = MemoizationMode(recursive=False)
111
+
110
112
 
111
113
  class InputLeftAddon(ChakraComponent):
112
114
  """The InputLeftAddon component is a component that is used to add an addon to the left of an input."""
@@ -15,7 +15,7 @@ from reflex.components.libs.chakra import (
15
15
  LiteralButtonSize,
16
16
  LiteralInputVariant,
17
17
  )
18
- from reflex.constants import EventTriggers
18
+ from reflex.constants import EventTriggers, MemoizationMode
19
19
  from reflex.utils import imports
20
20
  from reflex.vars import Var
21
21
 
@@ -770,7 +770,7 @@ class FunnelChart(RechartsCharts):
770
770
  ] = None,
771
771
  **props
772
772
  ) -> "FunnelChart":
773
- """Create the component.
773
+ """Create a new memoization leaf component.
774
774
 
775
775
  Args:
776
776
  *children: The children of the component.
@@ -791,10 +791,7 @@ class FunnelChart(RechartsCharts):
791
791
  **props: The props of the component.
792
792
 
793
793
  Returns:
794
- The component.
795
-
796
- Raises:
797
- TypeError: If an invalid child is passed.
794
+ The memoization leaf
798
795
  """
799
796
  ...
800
797
 
@@ -3,6 +3,7 @@ from __future__ import annotations
3
3
 
4
4
  from typing import Any, Dict, List, Union
5
5
 
6
+ from reflex.components.component import MemoizationLeaf
6
7
  from reflex.constants import EventTriggers
7
8
  from reflex.vars import Var
8
9
 
@@ -16,7 +17,7 @@ from .recharts import (
16
17
  )
17
18
 
18
19
 
19
- class ResponsiveContainer(Recharts):
20
+ class ResponsiveContainer(Recharts, MemoizationLeaf):
20
21
  """A base class for responsive containers in Recharts."""
21
22
 
22
23
  tag = "ResponsiveContainer"
@@ -8,6 +8,7 @@ from reflex.vars import Var, BaseVar, ComputedVar
8
8
  from reflex.event import EventChain, EventHandler, EventSpec
9
9
  from reflex.style import Style
10
10
  from typing import Any, Dict, List, Union
11
+ from reflex.components.component import MemoizationLeaf
11
12
  from reflex.constants import EventTriggers
12
13
  from reflex.vars import Var
13
14
  from .recharts import (
@@ -19,7 +20,7 @@ from .recharts import (
19
20
  Recharts,
20
21
  )
21
22
 
22
- class ResponsiveContainer(Recharts):
23
+ class ResponsiveContainer(Recharts, MemoizationLeaf):
23
24
  @overload
24
25
  @classmethod
25
26
  def create( # type: ignore
@@ -84,7 +85,7 @@ class ResponsiveContainer(Recharts):
84
85
  ] = None,
85
86
  **props
86
87
  ) -> "ResponsiveContainer":
87
- """Create the component.
88
+ """Create a new memoization leaf component.
88
89
 
89
90
  Args:
90
91
  *children: The children of the component.
@@ -103,10 +104,7 @@ class ResponsiveContainer(Recharts):
103
104
  **props: The props of the component.
104
105
 
105
106
  Returns:
106
- The component.
107
-
108
- Raises:
109
- TypeError: If an invalid child is passed.
107
+ The memoization leaf
110
108
  """
111
109
  ...
112
110
 
@@ -1,17 +1,17 @@
1
1
  """A component that wraps a recharts lib."""
2
2
  from typing import Literal
3
3
 
4
- from reflex.components.component import Component, NoSSRComponent
4
+ from reflex.components.component import Component, MemoizationLeaf, NoSSRComponent
5
5
 
6
6
 
7
7
  class Recharts(Component):
8
- """A component that wraps a victory lib."""
8
+ """A component that wraps a recharts lib."""
9
9
 
10
10
  library = "recharts@2.8.0"
11
11
 
12
12
 
13
- class RechartsCharts(NoSSRComponent):
14
- """A component that wraps a victory lib."""
13
+ class RechartsCharts(NoSSRComponent, MemoizationLeaf):
14
+ """A component that wraps a recharts lib."""
15
15
 
16
16
  library = "recharts@2.8.0"
17
17
 
@@ -8,7 +8,7 @@ from reflex.vars import Var, BaseVar, ComputedVar
8
8
  from reflex.event import EventChain, EventHandler, EventSpec
9
9
  from reflex.style import Style
10
10
  from typing import Literal
11
- from reflex.components.component import Component, NoSSRComponent
11
+ from reflex.components.component import Component, MemoizationLeaf, NoSSRComponent
12
12
 
13
13
  class Recharts(Component):
14
14
  @overload
@@ -89,7 +89,7 @@ class Recharts(Component):
89
89
  """
90
90
  ...
91
91
 
92
- class RechartsCharts(NoSSRComponent):
92
+ class RechartsCharts(NoSSRComponent, MemoizationLeaf):
93
93
  @overload
94
94
  @classmethod
95
95
  def create( # type: ignore
@@ -148,7 +148,7 @@ class RechartsCharts(NoSSRComponent):
148
148
  ] = None,
149
149
  **props
150
150
  ) -> "RechartsCharts":
151
- """Create the component.
151
+ """Create a new memoization leaf component.
152
152
 
153
153
  Args:
154
154
  *children: The children of the component.
@@ -161,10 +161,7 @@ class RechartsCharts(NoSSRComponent):
161
161
  **props: The props of the component.
162
162
 
163
163
  Returns:
164
- The component.
165
-
166
- Raises:
167
- TypeError: If an invalid child is passed.
164
+ The memoization leaf
168
165
  """
169
166
  ...
170
167
 
@@ -3,7 +3,7 @@ from __future__ import annotations
3
3
 
4
4
  from typing import Any, Dict, Optional, overload
5
5
 
6
- from reflex.components.component import BaseComponent, Component
6
+ from reflex.components.component import BaseComponent, Component, MemoizationLeaf
7
7
  from reflex.components.layout.fragment import Fragment
8
8
  from reflex.components.tags import CondTag, Tag
9
9
  from reflex.constants import Dirs
@@ -15,7 +15,7 @@ _IS_TRUE_IMPORT = {
15
15
  }
16
16
 
17
17
 
18
- class Cond(Component):
18
+ class Cond(MemoizationLeaf):
19
19
  """Render one of two components based on a condition."""
20
20
 
21
21
  # The cond to determine which component to render.
@@ -8,12 +8,15 @@ from typing import Any, Callable, Iterable
8
8
  from reflex.components.component import Component
9
9
  from reflex.components.layout.fragment import Fragment
10
10
  from reflex.components.tags import IterTag
11
+ from reflex.constants import MemoizationMode
11
12
  from reflex.vars import Var
12
13
 
13
14
 
14
15
  class Foreach(Component):
15
16
  """A component that takes in an iterable and a render function and renders a list of components."""
16
17
 
18
+ _memoization_mode = MemoizationMode(recursive=False)
19
+
17
20
  # The iterable to create components from.
18
21
  iterable: Var[Iterable]
19
22
 
@@ -1,11 +1,11 @@
1
1
  """An icon component."""
2
2
  from typing import List
3
3
 
4
- from reflex.components.component import Component
4
+ from reflex.components.libs.chakra import ChakraComponent
5
5
  from reflex.utils import format
6
6
 
7
7
 
8
- class ChakraIconComponent(Component):
8
+ class ChakraIconComponent(ChakraComponent):
9
9
  """A component that wraps a Chakra icon component."""
10
10
 
11
11
  library = "@chakra-ui/icons@2.0.19"
@@ -8,10 +8,10 @@ from reflex.vars import Var, BaseVar, ComputedVar
8
8
  from reflex.event import EventChain, EventHandler, EventSpec
9
9
  from reflex.style import Style
10
10
  from typing import List
11
- from reflex.components.component import Component
11
+ from reflex.components.libs.chakra import ChakraComponent
12
12
  from reflex.utils import format
13
13
 
14
- class ChakraIconComponent(Component):
14
+ class ChakraIconComponent(ChakraComponent):
15
15
  @overload
16
16
  @classmethod
17
17
  def create( # type: ignore
@@ -3,6 +3,7 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import textwrap
6
+ from functools import lru_cache
6
7
  from hashlib import md5
7
8
  from typing import Any, Callable, Dict, Union
8
9
 
@@ -35,6 +36,7 @@ _REHYPE_PLUGINS = Var.create_safe([_REHYPE_KATEX, _REHYPE_RAW])
35
36
 
36
37
 
37
38
  # Component Mapping
39
+ @lru_cache
38
40
  def get_base_component_map() -> dict[str, Callable]:
39
41
  """Get the base component map.
40
42
 
@@ -89,6 +91,9 @@ class Markdown(Component):
89
91
  # Custom styles for the markdown (deprecated in v0.2.9).
90
92
  custom_styles: Dict[str, Any] = {}
91
93
 
94
+ # The hash of the component map, generated at create() time.
95
+ component_map_hash: str = ""
96
+
92
97
  @classmethod
93
98
  def create(cls, *children, **props) -> Component:
94
99
  """Create a markdown component.
@@ -124,7 +129,12 @@ class Markdown(Component):
124
129
  src = textwrap.dedent(src)
125
130
 
126
131
  # Create the component.
127
- return super().create(src, component_map=component_map, **props)
132
+ return super().create(
133
+ src,
134
+ component_map=component_map,
135
+ component_map_hash=cls._component_map_hash(component_map),
136
+ **props,
137
+ )
128
138
 
129
139
  def get_custom_components(
130
140
  self, seen: set[str] | None = None
@@ -264,11 +274,15 @@ class Markdown(Component):
264
274
 
265
275
  return components
266
276
 
267
- def _component_map_hash(self) -> str:
268
- return md5(str(self.component_map).encode()).hexdigest()
277
+ @staticmethod
278
+ def _component_map_hash(component_map) -> str:
279
+ inp = str(
280
+ {tag: component(_MOCK_ARG) for tag, component in component_map.items()}
281
+ ).encode()
282
+ return md5(inp).hexdigest()
269
283
 
270
284
  def _get_component_map_name(self) -> str:
271
- return f"ComponentMap_{self._component_map_hash()}"
285
+ return f"ComponentMap_{self.component_map_hash}"
272
286
 
273
287
  def _get_custom_code(self) -> str | None:
274
288
  hooks = set()
@@ -292,7 +306,7 @@ class Markdown(Component):
292
306
  remark_plugins=_REMARK_PLUGINS,
293
307
  rehype_plugins=_REHYPE_PLUGINS,
294
308
  )
295
- .remove_props("componentMap")
309
+ .remove_props("componentMap", "componentMapHash")
296
310
  )
297
311
  tag.special_props.add(
298
312
  Var.create_safe(
@@ -8,6 +8,7 @@ from reflex.vars import Var, BaseVar, ComputedVar
8
8
  from reflex.event import EventChain, EventHandler, EventSpec
9
9
  from reflex.style import Style
10
10
  import textwrap
11
+ from functools import lru_cache
11
12
  from hashlib import md5
12
13
  from typing import Any, Callable, Dict, Union
13
14
  from reflex.compiler import utils
@@ -32,6 +33,7 @@ _REHYPE_KATEX = Var.create_safe("rehypeKatex", _var_is_local=False)
32
33
  _REHYPE_RAW = Var.create_safe("rehypeRaw", _var_is_local=False)
33
34
  _REHYPE_PLUGINS = Var.create_safe([_REHYPE_KATEX, _REHYPE_RAW])
34
35
 
36
+ @lru_cache
35
37
  def get_base_component_map() -> dict[str, Callable]: ...
36
38
 
37
39
  class Markdown(Component):
@@ -42,6 +44,7 @@ class Markdown(Component):
42
44
  *children,
43
45
  component_map: Optional[Dict[str, Any]] = None,
44
46
  custom_styles: Optional[Dict[str, Any]] = None,
47
+ component_map_hash: Optional[str] = None,
45
48
  style: Optional[Style] = None,
46
49
  key: Optional[Any] = None,
47
50
  id: Optional[Any] = None,
@@ -101,6 +104,7 @@ class Markdown(Component):
101
104
  *children: The children of the component.
102
105
  component_map: The component map from a tag to a lambda that creates a component.
103
106
  custom_styles: Custom styles for the markdown (deprecated in v0.2.9).
107
+ component_map_hash: The hash of the component map, generated at create() time.
104
108
  style: The style of the component.
105
109
  key: A unique key for the component.
106
110
  id: The id for the component.
@@ -25,6 +25,8 @@ from .compiler import (
25
25
  Ext,
26
26
  Hooks,
27
27
  Imports,
28
+ MemoizationDisposition,
29
+ MemoizationMode,
28
30
  PageNames,
29
31
  )
30
32
  from .config import (
@@ -46,6 +48,7 @@ from .route import (
46
48
  ROUTE_NOT_FOUND,
47
49
  ROUTER,
48
50
  ROUTER_DATA,
51
+ ROUTER_DATA_INCLUDE,
49
52
  DefaultPage,
50
53
  Page404,
51
54
  RouteArgType,
@@ -75,6 +78,8 @@ __ALL__ = [
75
78
  IS_WINDOWS,
76
79
  LOCAL_STORAGE,
77
80
  LogLevel,
81
+ MemoizationDisposition,
82
+ MemoizationMode,
78
83
  Next,
79
84
  Node,
80
85
  NOCOMPILE_FILE,
@@ -93,6 +98,7 @@ __ALL__ = [
93
98
  RouteVar,
94
99
  ROUTER,
95
100
  ROUTER_DATA,
101
+ ROUTER_DATA_INCLUDE,
96
102
  ROUTE_NOT_FOUND,
97
103
  SETTER_PREFIX,
98
104
  SKIP_COMPILE_ENV_VAR,
@@ -1,7 +1,9 @@
1
1
  """Compiler variables."""
2
+ import enum
2
3
  from enum import Enum
3
4
  from types import SimpleNamespace
4
5
 
6
+ from reflex.base import Base
5
7
  from reflex.constants import Dirs
6
8
  from reflex.utils.imports import ImportVar
7
9
 
@@ -56,6 +58,8 @@ class CompileVars(SimpleNamespace):
56
58
  CONNECT_ERROR = "connectError"
57
59
  # The name of the function for converting a dict to an event.
58
60
  TO_EVENT = "Event"
61
+ # The name of the internal on_load event.
62
+ ON_LOAD_INTERNAL = "on_load_internal"
59
63
 
60
64
 
61
65
  class PageNames(SimpleNamespace):
@@ -104,3 +108,22 @@ class Hooks(SimpleNamespace):
104
108
  """Common sets of hook declarations."""
105
109
 
106
110
  EVENTS = f"const [{CompileVars.ADD_EVENTS}, {CompileVars.CONNECT_ERROR}] = useContext(EventLoopContext);"
111
+
112
+
113
+ class MemoizationDisposition(enum.Enum):
114
+ """The conditions under which a component should be memoized."""
115
+
116
+ # If the component uses state or events, it should be memoized.
117
+ STATEFUL = "stateful"
118
+ ALWAYS = "always"
119
+ NEVER = "never"
120
+
121
+
122
+ class MemoizationMode(Base):
123
+ """The mode for memoizing a Component."""
124
+
125
+ # The conditions under which the component should be memoized.
126
+ disposition: MemoizationDisposition = MemoizationDisposition.STATEFUL
127
+
128
+ # Whether children of this component should be memoized first.
129
+ recursive: bool = True
reflex/constants/route.py CHANGED
@@ -30,6 +30,10 @@ class RouteVar(SimpleNamespace):
30
30
  COOKIE = "cookie"
31
31
 
32
32
 
33
+ # This subset of router_data is included in chained on_load events.
34
+ ROUTER_DATA_INCLUDE = set((RouteVar.PATH, RouteVar.ORIGIN, RouteVar.QUERY))
35
+
36
+
33
37
  class RouteRegex(SimpleNamespace):
34
38
  """Regex used for extracting route args in route."""
35
39
 
reflex/event.py CHANGED
@@ -826,6 +826,10 @@ def fix_events(
826
826
  # Fix the events created by the handler.
827
827
  out = []
828
828
  for e in events:
829
+ if isinstance(e, Event):
830
+ # If the event is already an event, append it to the list.
831
+ out.append(e)
832
+ continue
829
833
  if not isinstance(e, (EventHandler, EventSpec)):
830
834
  e = EventHandler(fn=e)
831
835
  # Otherwise, create an event from the event spec.
@@ -835,13 +839,19 @@ def fix_events(
835
839
  name = format.format_event_handler(e.handler)
836
840
  payload = {k._var_name: v._decode() for k, v in e.args} # type: ignore
837
841
 
842
+ # Filter router_data to reduce payload size
843
+ event_router_data = {
844
+ k: v
845
+ for k, v in (router_data or {}).items()
846
+ if k in constants.route.ROUTER_DATA_INCLUDE
847
+ }
838
848
  # Create an event and append it to the list.
839
849
  out.append(
840
850
  Event(
841
851
  token=token,
842
852
  name=name,
843
853
  payload=payload,
844
- router_data=router_data or {},
854
+ router_data=event_router_data,
845
855
  )
846
856
  )
847
857
 
@@ -4,7 +4,7 @@ from __future__ import annotations
4
4
  from typing import TYPE_CHECKING, Optional
5
5
 
6
6
  from reflex import constants
7
- from reflex.event import Event, fix_events, get_hydrate_event
7
+ from reflex.event import Event, get_hydrate_event
8
8
  from reflex.middleware.middleware import Middleware
9
9
  from reflex.state import BaseState, StateUpdate
10
10
  from reflex.utils import format
@@ -52,11 +52,5 @@ class HydrateMiddleware(Middleware):
52
52
  # since a full dict was captured, clean any dirtiness
53
53
  state._clean()
54
54
 
55
- # Get the route for on_load events.
56
- route = event.router_data.get(constants.RouteVar.PATH, "")
57
- # Add the on_load events and set is_hydrated to True.
58
- events = [*app.get_load_events(route), type(state).set_is_hydrated(True)] # type: ignore
59
- events = fix_events(events, event.token, router_data=event.router_data)
60
-
61
55
  # Return the state update.
62
- return StateUpdate(delta=delta, events=events)
56
+ return StateUpdate(delta=delta, events=[])
reflex/state.py CHANGED
@@ -1016,7 +1016,7 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
1016
1016
  """
1017
1017
 
1018
1018
  def _is_valid_type(events: Any) -> bool:
1019
- return isinstance(events, (EventHandler, EventSpec))
1019
+ return isinstance(events, (Event, EventHandler, EventSpec))
1020
1020
 
1021
1021
  if events is None or _is_valid_type(events):
1022
1022
  return events
@@ -1313,6 +1313,26 @@ class State(BaseState):
1313
1313
  # The hydrated bool.
1314
1314
  is_hydrated: bool = False
1315
1315
 
1316
+ def on_load_internal(self) -> list[Event | EventSpec] | None:
1317
+ """Queue on_load handlers for the current page.
1318
+
1319
+ Returns:
1320
+ The list of events to queue for on load handling.
1321
+ """
1322
+ app = getattr(prerequisites.get_app(), constants.CompileVars.APP)
1323
+ load_events = app.get_load_events(self.router.page.path)
1324
+ if not load_events and self.is_hydrated:
1325
+ return # Fast path for page-to-page navigation
1326
+ self.is_hydrated = False
1327
+ return [
1328
+ *fix_events(
1329
+ load_events,
1330
+ self.router.session.client_token,
1331
+ router_data=self.router_data,
1332
+ ),
1333
+ type(self).set_is_hydrated(True), # type: ignore
1334
+ ]
1335
+
1316
1336
 
1317
1337
  class StateProxy(wrapt.ObjectProxy):
1318
1338
  """Proxy of a state instance to control mutability of vars for a background task.
@@ -123,9 +123,17 @@ def get_app(reload: bool = False) -> ModuleType:
123
123
 
124
124
  Returns:
125
125
  The app based on the default config.
126
+
127
+ Raises:
128
+ RuntimeError: If the app name is not set in the config.
126
129
  """
127
130
  os.environ[constants.RELOAD_CONFIG] = str(reload)
128
131
  config = get_config()
132
+ if not config.app_name:
133
+ raise RuntimeError(
134
+ "Cannot get the app module because `app_name` is not set in rxconfig! "
135
+ "If this error occurs in a reflex test case, ensure that `get_app` is mocked."
136
+ )
129
137
  module = ".".join([config.app_name, config.app_name])
130
138
  sys.path.insert(0, os.getcwd())
131
139
  app = __import__(module, fromlist=(constants.CompileVars.APP,))
reflex/vars.py CHANGED
@@ -1284,6 +1284,29 @@ class Var:
1284
1284
  _var_type=str,
1285
1285
  )
1286
1286
 
1287
+ def strip(self, other: str | Var[str] = " ") -> Var:
1288
+ """Strip a string var.
1289
+
1290
+ Args:
1291
+ other: The string to strip the var with.
1292
+
1293
+ Returns:
1294
+ A var with the stripped string.
1295
+
1296
+ Raises:
1297
+ TypeError: If the var is not a string.
1298
+ """
1299
+ if not types._issubclass(self._var_type, str):
1300
+ raise TypeError(f"Cannot strip non-string var {self._var_full_name}.")
1301
+
1302
+ other = Var.create_safe(json.dumps(other)) if isinstance(other, str) else other
1303
+
1304
+ return self._replace(
1305
+ _var_name=f"{self._var_name}.replace(/^${other._var_full_name}|${other._var_full_name}$/g, '')",
1306
+ _var_is_string=False,
1307
+ merge_var_data=other._var_data,
1308
+ )
1309
+
1287
1310
  def split(self, other: str | Var[str] = " ") -> Var:
1288
1311
  """Split a string var into a list.
1289
1312
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: reflex
3
- Version: 0.3.5a1
3
+ Version: 0.3.5a3
4
4
  Summary: Web apps in pure Python.
5
5
  Home-page: https://reflex.dev
6
6
  License: Apache-2.0
@@ -53,14 +53,14 @@ reflex/.templates/jinja/web/pages/_app.js.jinja2,sha256=8iIL2oZPK0_3qjef9t7BOn6v
53
53
  reflex/.templates/jinja/web/pages/_document.js.jinja2,sha256=E2r3MWp-gimAa6DdRs9ErQpPEyjS_yV5fdid_wdOOlA,182
54
54
  reflex/.templates/jinja/web/pages/base_page.js.jinja2,sha256=GGnXlJqdPCNv4Ki0Sn0crU8fiuA7TuJOAQivAM0HmdM,318
55
55
  reflex/.templates/jinja/web/pages/component.js.jinja2,sha256=1Pui62uSL7LYA7FXZrh9ZmhKH8vHYu663eR134hhsAY,86
56
- reflex/.templates/jinja/web/pages/custom_component.js.jinja2,sha256=cNcKeZBSRjJe-41L9XgDxktXPViQeIZGhwsw4NREimc,812
56
+ reflex/.templates/jinja/web/pages/custom_component.js.jinja2,sha256=jDqpIxibHp1imx6xT8cpr8hgdXXWHTU7uqYB5pBvyXk,882
57
57
  reflex/.templates/jinja/web/pages/index.js.jinja2,sha256=5yzGDRJ-pMCnYwVSnUCQk7eZK-hfD0VW7tLISHkMnvA,343
58
58
  reflex/.templates/jinja/web/pages/stateful_component.js.jinja2,sha256=Zk9MpnnvxQLK4CyxywvvaWFP-ON3n4VESrzRRWG4mFk,298
59
59
  reflex/.templates/jinja/web/pages/stateful_components.js.jinja2,sha256=BfHi7ckH9u5xOliKWxjgmnia6AJbNnII97SC-dt_KSU,101
60
60
  reflex/.templates/jinja/web/pages/utils.js.jinja2,sha256=s10s9JZiNkDzMdqJQkdXPy-FA6g6V1V2QjHRSTKNEzI,3180
61
61
  reflex/.templates/jinja/web/styles/styles.css.jinja2,sha256=4-CvqGR8-nRzkuCOSp_PdqmhPEmOs_kOhskOlhLMEUg,141
62
62
  reflex/.templates/jinja/web/tailwind.config.js.jinja2,sha256=Tl60dYXB_kDw-5OpgwD_o3azLKGkq_x-dgvUvne8zh0,356
63
- reflex/.templates/jinja/web/utils/context.js.jinja2,sha256=J4FvlgsCBlRao2ma5YLqi3Z7G1mKGjC0PjhKRf9zy3s,2611
63
+ reflex/.templates/jinja/web/utils/context.js.jinja2,sha256=yj7gFQExMSntQnetCdoHCV5Gjz2mYamyInwG0zZOXZc,2780
64
64
  reflex/.templates/jinja/web/utils/theme.js.jinja2,sha256=cdRQR4cx0OFHUY060k1AdsPpK7BNUV--NzsC9HdH4l8,37
65
65
  reflex/.templates/web/.gitignore,sha256=3tT0CtVkCL09D_Y3Hd4myUgGcBuESeavCa0WHU5ifJ4,417
66
66
  reflex/.templates/web/components/reflex/chakra_color_mode_provider.js,sha256=4vJnV_AVrlH6FRzT4p0DF-kfHGKF3H6nXKtUEmAscKI,595
@@ -72,18 +72,18 @@ reflex/.templates/web/styles/tailwind.css,sha256=zBp60NAZ3bHTLQ7LWIugrCbOQdhiXdb
72
72
  reflex/.templates/web/utils/client_side_routing.js,sha256=iGGnZY07XMNLUT2GT_Y6OEICP7uc1FaWn9cPlQUpGgo,1254
73
73
  reflex/.templates/web/utils/helpers/dataeditor.js,sha256=K6_GVf_pjwE3TT054CjWyFGaA71gOZsoly-8vH-AEpg,1859
74
74
  reflex/.templates/web/utils/helpers/range.js,sha256=FevdZzCVxjF57ullfjpcUpeOXRxh5v09YnBB0jPbrS4,1152
75
- reflex/.templates/web/utils/state.js,sha256=o7cmLgQJNZTV5PfZGRxDGzrx0LcZacO12hu_a6Dep9s,18668
75
+ reflex/.templates/web/utils/state.js,sha256=UefNdUKAgTuTS5UqxEhXI-q2gKdZoygr6pkHboY1l9o,18847
76
76
  reflex/__init__.py,sha256=uokcDukKB8JFn2TYivO2zBvkVZY65PG1QxqwOYVrY30,7310
77
77
  reflex/__init__.pyi,sha256=grvhJNV6LJB27hai2T_FzkEjBpCrSn4WSU8Q4_7BBdQ,26736
78
78
  reflex/__main__.py,sha256=6cVrGEyT3j3tEvlEVUatpaYfbB5EF3UVY-6vc_Z7-hw,108
79
79
  reflex/admin.py,sha256=-bTxFUEoHo4X9FzmcSa6KSVVPpF7wh38lBvF67GhSvQ,373
80
- reflex/app.py,sha256=09utrmtVQA916D8YCPRRlVVm5MGsI7Fw2N5omb39dtc,37763
81
- reflex/app.pyi,sha256=RYBy8HpkBbBfz5whkMisrLqKQ4Hm68YCUwC0YeOtmoY,4701
80
+ reflex/app.py,sha256=zvI8H52tgAYJdROmIZLCxJJE5aBrkz3bQ1xaEZuJLYQ,37748
81
+ reflex/app.pyi,sha256=tg6JMC8vGshJjZFWeO3VK50yWab-Vhc6kX1g_kWTVxM,4695
82
82
  reflex/base.py,sha256=8UcGxfd_ayYie-VK6M9IXNZ1EjjX_OpxBJGY0F1Az1k,3608
83
83
  reflex/compiler/__init__.py,sha256=r8jqmDSFf09iV2lHlNhfc9XrTLjNxfDNwPYlxS4cmHE,27
84
84
  reflex/compiler/compiler.py,sha256=Fg6YBMAmKtFzD_45OcQFbsOUWDs53-gtRw-OrwMIsO4,12163
85
- reflex/compiler/templates.py,sha256=4f1j26Dl6fVqFUDRdasY1AvQr0hHRtS184QB86ZHNAI,3444
86
- reflex/compiler/utils.py,sha256=JxHkYP89jj-JDCHERzhVguqdGlI1eDzmTxPuquFAtiY,12789
85
+ reflex/compiler/templates.py,sha256=U4Nt1WH0UsP-fkM3TQoV9ASBsCJEZEM7HOzthzhphtE,3516
86
+ reflex/compiler/utils.py,sha256=gvZsj_OXGHa8Aewfp5UOLCh1-7ukxHnWEifOR4WyB9Y,12830
87
87
  reflex/components/__init__.py,sha256=jIpJevwio4FqpsFOAs0fd-se0xFsqCE38hZxiEWQhAE,7419
88
88
  reflex/components/base/__init__.py,sha256=BIobn_49_ZsyQf-F50kOGq4FklfXiBRDTPCbPBM4p64,260
89
89
  reflex/components/base/app_wrap.py,sha256=_4Zoqz8_8EVO1rh99o7LyJdKU4ekWYRoD0owcqQfRkI,575
@@ -93,15 +93,15 @@ reflex/components/base/body.py,sha256=QHOGMr98I6bUXsQKXcY0PzJdhopH6gQ8AESrDSgJV6
93
93
  reflex/components/base/body.pyi,sha256=1jtmYDFxUtsVPM_Q7xaqSC765z6ct57xDKO1Wfse4ik,3272
94
94
  reflex/components/base/document.py,sha256=6py5UDCALAzdAccFiiJbKxVXgHjGK3bBk5zvUpLQNZE,725
95
95
  reflex/components/base/document.pyi,sha256=STyq72fDZzbJpPizU5nUfF2Q5h6yCbqAr5rJHjvjs2s,17396
96
- reflex/components/base/head.py,sha256=zaaBzDiJjxQekGgMykcBgkhHPh6USmSIO0qKafh8cAw,263
97
- reflex/components/base/head.pyi,sha256=cWb-tMYZeENPzJSxb7UPWxIu0rOQifccgJQxEoTFENM,6080
96
+ reflex/components/base/head.py,sha256=r7uis6H3Vc11ob8gqGNfExI_HPUKyTDNydInQXg6JeM,297
97
+ reflex/components/base/head.pyi,sha256=DuHBorUNGyVy9sDIPeKBi6sdJkegtQWDgmouPyoSyrI,6068
98
98
  reflex/components/base/link.py,sha256=y26QGX8QERS-vWjFggvYt_xKxJAfrpKmU0FGJMi3mh0,929
99
99
  reflex/components/base/link.pyi,sha256=uuWh2firoXrrY-uT7xRWFTP13dfEEqynYs8wYL7Rxow,7127
100
100
  reflex/components/base/meta.py,sha256=RWITTQTA_35-FbaVGhjkAWDOmU65rzJ-WedENRJk-3k,1438
101
101
  reflex/components/base/meta.pyi,sha256=JIWM2x8z_A8sOpEoRv-avjOXyEC8OajqTGnCOnmBMqQ,13083
102
102
  reflex/components/base/script.py,sha256=sNuoSeO1XxVfqSd9EADlOeNDti-zf8-vn_yd0NcmImc,2298
103
103
  reflex/components/base/script.pyi,sha256=11PEE77sBt78L4AsEdhgD7uQ7TpqGNStCpD_vI8MIDw,4495
104
- reflex/components/component.py,sha256=1ZgAdEL4udtXGYXcAdCp5zVAIm13j1sw5x0eTbH5vIM,54079
104
+ reflex/components/component.py,sha256=zf2_Za9h_JSwSMee13hzG0_OFEJttcCV4-UUOd3EGcU,55739
105
105
  reflex/components/datadisplay/__init__.py,sha256=UB-LJcrXj6L7nZK-WLoUwWOvc0b21Yh0s6W3J0xE8iU,721
106
106
  reflex/components/datadisplay/badge.py,sha256=5QJivxZyjZhcxJS-XBU56CW1A7vADINKcwrhg9qUeKg,357
107
107
  reflex/components/datadisplay/badge.pyi,sha256=bX3mS37wsMOoL60hXDpqK440GBhlJSmLXl8KF1ptFk8,3718
@@ -196,8 +196,8 @@ reflex/components/forms/form.py,sha256=1JRo57c1F4ABO4qcjPkHYcX4lSgZrsaOmg-ybZIJ6
196
196
  reflex/components/forms/form.pyi,sha256=wj9S-ESijVibC8M67ZeFa0HyBGKXCy45IzsF9q0D4lM,16932
197
197
  reflex/components/forms/iconbutton.py,sha256=tTmul_GEUROkhF_nD3ol_H0e8VX1uvQ0HMZnsVvgMfM,888
198
198
  reflex/components/forms/iconbutton.pyi,sha256=gpMfqgfgYEniKhPCMMwqET3TntMR_HKFFXLoSVKhPko,4720
199
- reflex/components/forms/input.py,sha256=n005PfwWEhZE7EyuQFPbCUV5S4MbFuohLENKzV8XawE,4465
200
- reflex/components/forms/input.pyi,sha256=f1Yq9R2-cXh6-kGXqkJtN3AgqtriAWV-0B-6r986zIo,20247
199
+ reflex/components/forms/input.py,sha256=Z9Nj7omsbtIsta-scZUinGyZGcCI3mpuH4IukXKHcP8,4540
200
+ reflex/components/forms/input.pyi,sha256=66Vo5hi6W6NrLY1__Ny0AL8I8BFLfXSCqybs7Z2MuhY,20264
201
201
  reflex/components/forms/multiselect.py,sha256=EbBbcJxjkv59q-lGDSi107wxzwR7tp8wAgQbZeht9S0,12940
202
202
  reflex/components/forms/numberinput.py,sha256=1sGQyAyDACIvCzwY9KZ6yAx8N3P4QC1BlAEdK01H5r0,4250
203
203
  reflex/components/forms/numberinput.pyi,sha256=z4PPmzSBFaZuf4DAF3GPVaUdCFPyNZ7d7s7roZQermo,18159
@@ -226,13 +226,13 @@ reflex/components/graphing/recharts/__init__.py,sha256=_z8TImfBT085hUYH-UQGwtSO6
226
226
  reflex/components/graphing/recharts/cartesian.py,sha256=kSOdShCDIP7sXSmRxTfwPYSuOEoBs8MNcT9yja37-bc,19595
227
227
  reflex/components/graphing/recharts/cartesian.pyi,sha256=DCapfKTgwpFRCr7ZS4GdnjV-Whag3tnPvSEhpCdmQJQ,85504
228
228
  reflex/components/graphing/recharts/charts.py,sha256=-FPGn4MkAlNfSd-luZF3jgsVSR2KenOat1vrdpTRev4,18502
229
- reflex/components/graphing/recharts/charts.pyi,sha256=h0jgmSgobreXKwsSEU4ZEvqHI6GxcuXyG1jHwXeJzO0,48816
230
- reflex/components/graphing/recharts/general.py,sha256=0eBac10hMwIY8_tq_SxXx5nriE1zUA--qhgFGhf7b_g,5551
231
- reflex/components/graphing/recharts/general.pyi,sha256=bvPwj95riCQ1PADuHaRn-AIGP8zsg6vpwGXm4KF7W20,23048
229
+ reflex/components/graphing/recharts/charts.pyi,sha256=t5nCGkWVczhPkfHWX6lYLSVyKkWN0RynI7TF2u4BcUw,48770
230
+ reflex/components/graphing/recharts/general.py,sha256=71Z8IFDjNGT6m2110lkz81AeH6yFuyA9g5JH58qbYpE,5624
231
+ reflex/components/graphing/recharts/general.pyi,sha256=EfHc7wao-SsPkHTPzXfPZRV9i6VVz9ETVqcr38Iobpo,23075
232
232
  reflex/components/graphing/recharts/polar.py,sha256=X4qG0IOCnC11Zb6iDTXuV9_IVU5MrIFYzmnQLpyFufY,10410
233
233
  reflex/components/graphing/recharts/polar.pyi,sha256=v9set3PzPT5lDCcrdN8sMhFpc05h4Z86FuxY3OPp_uQ,24756
234
- reflex/components/graphing/recharts/recharts.py,sha256=GSL2HHKEEVQSpXlCRkg5xYkHaOvy2Gbd4eQeZYB8Qws,2834
235
- reflex/components/graphing/recharts/recharts.pyi,sha256=DXh6TiGggUbBGyqNYXdGXHGhY84XQQbTr_buPhBUcCA,8622
234
+ reflex/components/graphing/recharts/recharts.py,sha256=Ap4HCCBY2Q9gdrh-PnHOvJY5ebIKCLgnQNrUWDp_bRs,2870
235
+ reflex/components/graphing/recharts/recharts.pyi,sha256=BlmqDBZveWoCqj324J9yBJgLbMLGnJHs0WJTcuwxMdM,8610
236
236
  reflex/components/layout/__init__.py,sha256=p6k9RBI6wF37vE0CjZ2Ptr0eWZ8FxmMtJhClNy2rTUM,872
237
237
  reflex/components/layout/aspect_ratio.py,sha256=8ulf9WvYZ2hGzZk0TCZMORU_exC-yH_lDhUamA4ftCY,320
238
238
  reflex/components/layout/aspect_ratio.pyi,sha256=t_V4XcPe3zMswcCrSjvS9iCpaQujdfbnX9NCVpYKIu8,3443
@@ -242,12 +242,12 @@ reflex/components/layout/card.py,sha256=mRCy-v3Z3Eq3zQfDfBKV-JtgfhTr66DVCXsJwKW3
242
242
  reflex/components/layout/card.pyi,sha256=kq3--gk7q3qyd9DSXYdWxX425RiZtiX-UmL64ssuUng,14056
243
243
  reflex/components/layout/center.py,sha256=C9Y_V7eKc5uyOcgK1panVjBlbW2q3lC6S_IBJR6ZQSI,394
244
244
  reflex/components/layout/center.pyi,sha256=H2T9Z7DQIZoiBO3VNTz1MQUqYZhmnmVJwhU2mYl82-E,8898
245
- reflex/components/layout/cond.py,sha256=R38BwET3jzpdOWsnnyokuE6LNRcuKotJJNaSWynj_gg,5056
245
+ reflex/components/layout/cond.py,sha256=XgZ7OjwSar0zOuaOPKzeaFj8KE1wOtEgmXj-DYOS2h8,5079
246
246
  reflex/components/layout/container.py,sha256=BNv819mXySO8NeRM8WlMa33XitJ440Aof4sbhOZPO4g,359
247
247
  reflex/components/layout/container.pyi,sha256=6b9hbgz7Qn80ngEbddyCak2FqXiipoLKWeA1K5PTLRM,3495
248
248
  reflex/components/layout/flex.py,sha256=WMgKYImjFLyBC8EayqMCzME8yfIO-2LxLazHUYkKgg0,720
249
249
  reflex/components/layout/flex.pyi,sha256=oXLPPpF83YGrWW_nzymYSUJWZXOD-7xAjP81i9XuTbo,4202
250
- reflex/components/layout/foreach.py,sha256=gZJe8YaH9PUZy4UxvGdSVxgGT71LUtmKRxDrs4B6Yn0,3545
250
+ reflex/components/layout/foreach.py,sha256=U3RONgJpWAfbwP-3bz3nRpGkdoQ79MPIT0jFLmGzWTM,3648
251
251
  reflex/components/layout/fragment.py,sha256=HGKEEqEW87bEkwGvwqYE_1o22l8J1xGX9T4P3J5Tn6k,312
252
252
  reflex/components/layout/fragment.pyi,sha256=2CdZhklzf8IJaACXZ9FBxIuhR6VNazvF-VAk_XTxmtQ,3286
253
253
  reflex/components/layout/grid.py,sha256=9UuPpFDT5mj3teyyKgNv4dAGzz7xkk3aEmssZ-FV46I,4323
@@ -272,8 +272,8 @@ reflex/components/media/audio.py,sha256=dLV0w_zIBBJccj8b3cOfZnx2QVhVCSxOlNcpwRVO
272
272
  reflex/components/media/audio.pyi,sha256=Lmjbc5qritmC4WApON79JMk9EhTYoMeSQdd756GZu04,4396
273
273
  reflex/components/media/avatar.py,sha256=1Cy9Vhkp66vGVOvrWpqLhwOblM5w9wLReCbniKB6TvA,1673
274
274
  reflex/components/media/avatar.pyi,sha256=S_H5-ux4HxVtYyktB0u0RALGWCH2PxcH98kSz5h8mcE,10651
275
- reflex/components/media/icon.py,sha256=S_XGUxYMwI84bJZIb23ca6Fz8uQ4Znef1GmTHAhAFec,2444
276
- reflex/components/media/icon.pyi,sha256=XE7thrHhC0FEakFLPiZhoxRvs9uQbEXXKETvZAYq4sw,6321
275
+ reflex/components/media/icon.py,sha256=Kvs-oOQpC1FJdglLLgkzB60qEK1VH4LLy0mjqzEclSM,2458
276
+ reflex/components/media/icon.pyi,sha256=hceJFS5f3f0-VLNExaRyz1p5e3AKUBQcu9eFmBzRP7g,6335
277
277
  reflex/components/media/image.py,sha256=Ez54IbY6SR4Ox0ojTOwZf_XVoU1WlHDmm1BLQYY0bII,3095
278
278
  reflex/components/media/image.pyi,sha256=T7AE9pxbapS8AfbS_JfHaWXY2fgupMVJAmd_yaEyYyY,5628
279
279
  reflex/components/media/video.py,sha256=CJ99fj_JQp8zrY-x2YHkcp3v6oh6YDyaMJguAM7FygU,195
@@ -326,32 +326,32 @@ reflex/components/typography/heading.py,sha256=a07yOx5LJ-ySUyXZkwcrAIv0AtUgw1B9s
326
326
  reflex/components/typography/heading.pyi,sha256=5D4NCkS3Q_99eg9MUHwBFPepc32iQZi5ZoUYY_tXi7A,3770
327
327
  reflex/components/typography/highlight.py,sha256=DYWJ3JrVnWHgkU_qaljyPpgfzyaieS4jSaCT_HD39X4,676
328
328
  reflex/components/typography/highlight.pyi,sha256=jkFoiM5KmAz-yskKesoUN3sfkQUqRkiw1kMLrd_rB0Q,3709
329
- reflex/components/typography/markdown.py,sha256=kJQvavbRtg7fSgniuwPikIFi2MbqMazP14nFb9UmxTg,10307
330
- reflex/components/typography/markdown.pyi,sha256=y7qZESEdYpsxc4wf5vI1MCFC9Iz8TNO1B5jrmXOva3s,4990
329
+ reflex/components/typography/markdown.py,sha256=DQ9dd5wr3TzkWr3gBGFTwlCEtfPKmYQBz9_VAvMpGa4,10704
330
+ reflex/components/typography/markdown.pyi,sha256=I-7GM9jaq8XLTfMp3xcrmiqtslUfCJvu83BwH8IIFRM,5174
331
331
  reflex/components/typography/span.py,sha256=kvIj5UAEvzhRpvXkAEZ_JxBRSt-LNBiEz9Arlj5m7jo,333
332
332
  reflex/components/typography/span.pyi,sha256=q_PqfZ1zj-YpYDZZhXkwSyKL8Hc_Kv4AaIFHZBhTemk,3436
333
333
  reflex/components/typography/text.py,sha256=32HSSQteGs_brWsuCnCiFiZkfIyAt6VTJlA8SJfo-sk,477
334
334
  reflex/components/typography/text.pyi,sha256=u4fLPQvOSwStBBCxHIesnSCY1XhEb9EX47XIuUWz74I,3660
335
335
  reflex/config.py,sha256=EEY7gBZ2T3p9g6-LqbD-wt_jO6qcPW3a2t6NLtk1QKo,10606
336
336
  reflex/config.pyi,sha256=Gf0Ptm9h0xEPsv0FAfwsSq6fs5ycjiR0WxbYimt9TKY,3278
337
- reflex/constants/__init__.py,sha256=k22X9RFac73RncV7RhKV8mbT_dOSUNPGFhuW71tLMvM,1653
337
+ reflex/constants/__init__.py,sha256=goPNimkDuJHX6kxEKeKvfM8kjiOVfYkMZY7HmmeUvxI,1801
338
338
  reflex/constants/base.py,sha256=3sl5N6LeBa_xic38sanc7t57ntD23L_xwCB71uy2SWc,5175
339
- reflex/constants/compiler.py,sha256=A1yzPnwcyVUAHkoj4pc1wmVVdUPttq2Q9-F-8JGwdH8,2991
339
+ reflex/constants/compiler.py,sha256=PuZuIasjtj-EJtZBAJtVd_Yjhe5yiLDbdLOntVs1DLE,3683
340
340
  reflex/constants/config.py,sha256=DnoljtuYLsPUlpqVoMCWBm7RhSjCdKP0NE2ZQe-qf-I,1331
341
341
  reflex/constants/event.py,sha256=8Glq8yt5M0Wlac3iySZ38de_ZHF_VjG6bXVX39D22xU,2266
342
342
  reflex/constants/installer.py,sha256=aDRDkyFMNEZcsSkfy4Es2sSuG6Hx2nJFT7KL4s69PnE,3139
343
- reflex/constants/route.py,sha256=z-LJf9sbjkuKjBD2CTOrHXHpgTVmfUyjjxp_GYL1xNA,1810
343
+ reflex/constants/route.py,sha256=yk0WEPqQrNbTvvV8TEy1vvmV2ISg_Gr5jdVxSqFWEm4,1956
344
344
  reflex/constants/style.py,sha256=cHQ7SzX5ag8Q7rqW462pUSkF5UZLCldSVmvNaIypGic,604
345
- reflex/event.py,sha256=0qZcNsvvxwMxxTNsq34jahMqUgBNq3xlhmdGOSU7egk,24550
345
+ reflex/event.py,sha256=kTxt2vk_t93FfzGcOuO-lpde-A1_o7x8qJDg0-7B3nI,24918
346
346
  reflex/middleware/__init__.py,sha256=x7xTeDuc73Hjj43k1J63naC9x8vzFxl4sq7cCFBX7sk,111
347
- reflex/middleware/hydrate_middleware.py,sha256=XXyHWUKIR7QQaXs2wAPl3IKuqu57vf9TGVmY-MFjXQw,2292
347
+ reflex/middleware/hydrate_middleware.py,sha256=8wkeB92prQ5rWg2VBU2dO-zgg3qOdeE8T2Dckr6mgws,1924
348
348
  reflex/middleware/middleware.py,sha256=PX9TPaCHI1O-F3OucsZSp94gtMP3ALYs3zXSALOlN9E,1169
349
349
  reflex/model.py,sha256=3pek3P0bLeK-MRuCvZ25je-bjNOUmjK--UzV0G09dD8,10737
350
350
  reflex/page.py,sha256=VkrInVJ1jIlu141y4ssFh4dW7d5Uc8CbOaWY9JzwBa0,1916
351
351
  reflex/page.pyi,sha256=nFfbDe-tBsrIrcAKWsoTy92olMkAosbmddh_Pgf2Sxc,505
352
352
  reflex/reflex.py,sha256=DVHhrjJc3q6jHtyZUSiTSD1gz8tOTljyuviF16TlrJ4,16420
353
353
  reflex/route.py,sha256=eVi2TSk9uM7DDGBy6rDYe6Gq4iuHZFK00Vmoq9IbIjk,2732
354
- reflex/state.py,sha256=YZyNWAwtWrQ1_jBt9DeRdaYbAROH16IE5uQKdqnNXi0,70776
354
+ reflex/state.py,sha256=3ALUZuyk1vb0PszLns2cz_sYwq1PKaPA0EWbJGfgf_g,71533
355
355
  reflex/style.py,sha256=ajB6SXPrIbAmE-jg6JQLDNze5ySLactFLK2wMg4-MKI,3694
356
356
  reflex/testing.py,sha256=52RCYyEstG8Lie_ZA3d3qVdy3io2_USfO1xVlLC8YtA,26288
357
357
  reflex/utils/__init__.py,sha256=y-AHKiRQAhk2oAkvn7W8cRVTZVK625ff8tTwvZtO7S4,24
@@ -363,16 +363,16 @@ reflex/utils/export.py,sha256=gjtISftVt__OYMlJXXVslHbedVym7mTCHqzav7IuEjE,2445
363
363
  reflex/utils/format.py,sha256=sVov_b-78fGL8BPTxuLfvgHlIVnmy41vXvrhRqovbDQ,19055
364
364
  reflex/utils/imports.py,sha256=yah1kSVsOyUxA0wOMxJTwcmu6xlmkLJtV_zRIhshpsA,1919
365
365
  reflex/utils/path_ops.py,sha256=pUcqPPKsvP6G5VVggX9fcw8lEkiKueTNoFq0eUlMyGc,4706
366
- reflex/utils/prerequisites.py,sha256=uB-HdZZE6Vk9KH8ABR2X0fvjFMnXMLbNe3wQfQwghpM,25675
366
+ reflex/utils/prerequisites.py,sha256=0dWFGjMqif0nhluq8hEmPqSY_hI-iJHoY-dlWt0HYAI,25993
367
367
  reflex/utils/processes.py,sha256=pDJvgtT_F3N9p0rRpkzwFBc_W4ng1-qfl35HmAlZAjk,8145
368
368
  reflex/utils/serializers.py,sha256=7S9q10E7oUhyyCcoqWOsG4sg96t4qjPF2ygme02Ouso,5715
369
369
  reflex/utils/telemetry.py,sha256=CxRreEGR3e3mq6oOuAf3krN4cCKtdPs47Q9gaY0svr8,2388
370
370
  reflex/utils/types.py,sha256=7HWt89qz8Za5awm_sVTZ1P_F-V8ZVpkKd3Gkz45Acro,7434
371
371
  reflex/utils/watch.py,sha256=HzGrHQIZ_62Di0BO46kd2AZktNA3A6nFIBuf8c6ip30,2609
372
- reflex/vars.py,sha256=6nNW_JxT6x-cw-HVog_9skODpe4tMDULx_hcz14pARA,58674
372
+ reflex/vars.py,sha256=OLLZHSDJkbe031eX-OoYtlnBDGa9S10HUWbBdxskgKs,59428
373
373
  reflex/vars.pyi,sha256=VsVyNRIcuWnCDo2xrxF25gHV7qTM8wU1O350UBay3Rk,5032
374
- reflex-0.3.5a1.dist-info/LICENSE,sha256=dw3zLrp9f5ObD7kqS32vWfhcImfO52PMmRqvtxq_YEE,11358
375
- reflex-0.3.5a1.dist-info/METADATA,sha256=WvdmyoZaVh7574qYf1_HwKNJqk27tnaGwiFPp9mVIRI,11044
376
- reflex-0.3.5a1.dist-info/WHEEL,sha256=d2fvjOD7sXsVzChCqf0Ty0JbHKBaLYwDbGQDwQTnJ50,88
377
- reflex-0.3.5a1.dist-info/entry_points.txt,sha256=H1Z5Yat_xJfy0dRT1Frk2PkO_p41Xy7fCKlj4FcdL9o,44
378
- reflex-0.3.5a1.dist-info/RECORD,,
374
+ reflex-0.3.5a3.dist-info/LICENSE,sha256=dw3zLrp9f5ObD7kqS32vWfhcImfO52PMmRqvtxq_YEE,11358
375
+ reflex-0.3.5a3.dist-info/METADATA,sha256=labYjjUnc-6X7Jr4rPUJQruXxkzKXOiDB6AHpGG1FfQ,11044
376
+ reflex-0.3.5a3.dist-info/WHEEL,sha256=d2fvjOD7sXsVzChCqf0Ty0JbHKBaLYwDbGQDwQTnJ50,88
377
+ reflex-0.3.5a3.dist-info/entry_points.txt,sha256=H1Z5Yat_xJfy0dRT1Frk2PkO_p41Xy7fCKlj4FcdL9o,44
378
+ reflex-0.3.5a3.dist-info/RECORD,,