reflex 0.6.0a1__py3-none-any.whl → 0.6.0a2__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 (249) hide show
  1. reflex/.templates/jinja/web/pages/_app.js.jinja2 +1 -1
  2. reflex/.templates/jinja/web/pages/utils.js.jinja2 +2 -2
  3. reflex/__init__.py +8 -2
  4. reflex/__init__.pyi +2 -1
  5. reflex/app.py +4 -2
  6. reflex/base.py +1 -1
  7. reflex/compiler/compiler.py +2 -2
  8. reflex/compiler/utils.py +3 -3
  9. reflex/components/base/app_wrap.py +2 -2
  10. reflex/components/base/app_wrap.pyi +17 -27
  11. reflex/components/base/bare.py +4 -5
  12. reflex/components/base/body.pyi +17 -27
  13. reflex/components/base/document.pyi +81 -131
  14. reflex/components/base/error_boundary.py +6 -7
  15. reflex/components/base/error_boundary.pyi +20 -33
  16. reflex/components/base/fragment.pyi +17 -27
  17. reflex/components/base/head.pyi +33 -53
  18. reflex/components/base/link.py +1 -1
  19. reflex/components/base/link.pyi +33 -54
  20. reflex/components/base/meta.pyi +65 -105
  21. reflex/components/base/script.py +1 -2
  22. reflex/components/base/script.pyi +21 -38
  23. reflex/components/component.py +48 -47
  24. reflex/components/core/banner.py +23 -27
  25. reflex/components/core/banner.pyi +134 -171
  26. reflex/components/core/client_side_routing.py +2 -3
  27. reflex/components/core/client_side_routing.pyi +33 -54
  28. reflex/components/core/clipboard.py +2 -1
  29. reflex/components/core/clipboard.pyi +20 -33
  30. reflex/components/core/cond.py +5 -5
  31. reflex/components/core/debounce.py +5 -5
  32. reflex/components/core/debounce.pyi +20 -33
  33. reflex/components/core/foreach.py +3 -4
  34. reflex/components/core/html.py +1 -1
  35. reflex/components/core/html.pyi +35 -46
  36. reflex/components/core/match.py +17 -17
  37. reflex/components/core/upload.py +17 -23
  38. reflex/components/core/upload.pyi +78 -124
  39. reflex/components/datadisplay/code.py +9 -10
  40. reflex/components/datadisplay/code.pyi +302 -412
  41. reflex/components/datadisplay/dataeditor.py +8 -10
  42. reflex/components/datadisplay/dataeditor.pyi +40 -53
  43. reflex/components/el/element.pyi +17 -27
  44. reflex/components/el/elements/base.py +1 -1
  45. reflex/components/el/elements/base.pyi +34 -45
  46. reflex/components/el/elements/forms.py +16 -16
  47. reflex/components/el/elements/forms.pyi +554 -707
  48. reflex/components/el/elements/inline.py +1 -1
  49. reflex/components/el/elements/inline.pyi +937 -1218
  50. reflex/components/el/elements/media.py +1 -1
  51. reflex/components/el/elements/media.pyi +786 -997
  52. reflex/components/el/elements/metadata.py +3 -6
  53. reflex/components/el/elements/metadata.pyi +181 -242
  54. reflex/components/el/elements/other.py +1 -1
  55. reflex/components/el/elements/other.pyi +235 -306
  56. reflex/components/el/elements/scripts.py +1 -1
  57. reflex/components/el/elements/scripts.pyi +109 -140
  58. reflex/components/el/elements/sectioning.py +0 -2
  59. reflex/components/el/elements/sectioning.pyi +496 -647
  60. reflex/components/el/elements/tables.py +1 -1
  61. reflex/components/el/elements/tables.pyi +351 -452
  62. reflex/components/el/elements/typography.py +1 -1
  63. reflex/components/el/elements/typography.pyi +506 -657
  64. reflex/components/gridjs/datatable.py +6 -9
  65. reflex/components/gridjs/datatable.pyi +35 -56
  66. reflex/components/lucide/icon.py +1 -1
  67. reflex/components/lucide/icon.pyi +33 -54
  68. reflex/components/markdown/markdown.py +26 -31
  69. reflex/components/markdown/markdown.pyi +27 -37
  70. reflex/components/moment/moment.py +13 -12
  71. reflex/components/moment/moment.pyi +23 -35
  72. reflex/components/next/base.pyi +17 -27
  73. reflex/components/next/image.py +1 -1
  74. reflex/components/next/image.pyi +22 -37
  75. reflex/components/next/link.py +1 -1
  76. reflex/components/next/link.pyi +17 -28
  77. reflex/components/next/video.py +1 -1
  78. reflex/components/next/video.pyi +17 -28
  79. reflex/components/plotly/plotly.py +12 -13
  80. reflex/components/plotly/plotly.pyi +39 -54
  81. reflex/components/props.py +1 -1
  82. reflex/components/radix/__init__.pyi +1 -0
  83. reflex/components/radix/primitives/__init__.pyi +1 -0
  84. reflex/components/radix/primitives/accordion.py +4 -4
  85. reflex/components/radix/primitives/accordion.pyi +424 -495
  86. reflex/components/radix/primitives/base.py +1 -1
  87. reflex/components/radix/primitives/base.pyi +33 -54
  88. reflex/components/radix/primitives/drawer.py +1 -1
  89. reflex/components/radix/primitives/drawer.pyi +172 -273
  90. reflex/components/radix/primitives/form.py +1 -1
  91. reflex/components/radix/primitives/form.pyi +257 -364
  92. reflex/components/radix/primitives/progress.py +1 -1
  93. reflex/components/radix/primitives/progress.pyi +231 -282
  94. reflex/components/radix/primitives/slider.py +1 -1
  95. reflex/components/radix/primitives/slider.pyi +87 -138
  96. reflex/components/radix/themes/base.py +3 -24
  97. reflex/components/radix/themes/base.pyi +178 -250
  98. reflex/components/radix/themes/color_mode.py +5 -5
  99. reflex/components/radix/themes/color_mode.pyi +187 -220
  100. reflex/components/radix/themes/components/alert_dialog.py +1 -1
  101. reflex/components/radix/themes/components/alert_dialog.pyi +136 -207
  102. reflex/components/radix/themes/components/aspect_ratio.py +1 -1
  103. reflex/components/radix/themes/components/aspect_ratio.pyi +17 -28
  104. reflex/components/radix/themes/components/avatar.py +1 -1
  105. reflex/components/radix/themes/components/avatar.pyi +70 -81
  106. reflex/components/radix/themes/components/badge.py +1 -1
  107. reflex/components/radix/themes/components/badge.pyi +88 -99
  108. reflex/components/radix/themes/components/button.py +1 -1
  109. reflex/components/radix/themes/components/button.pyi +98 -109
  110. reflex/components/radix/themes/components/callout.py +1 -1
  111. reflex/components/radix/themes/components/callout.pyi +322 -373
  112. reflex/components/radix/themes/components/card.py +1 -1
  113. reflex/components/radix/themes/components/card.pyi +38 -49
  114. reflex/components/radix/themes/components/checkbox.py +1 -2
  115. reflex/components/radix/themes/components/checkbox.pyi +208 -245
  116. reflex/components/radix/themes/components/checkbox_cards.py +1 -1
  117. reflex/components/radix/themes/components/checkbox_cards.pyi +94 -115
  118. reflex/components/radix/themes/components/checkbox_group.py +1 -1
  119. reflex/components/radix/themes/components/checkbox_group.pyi +86 -107
  120. reflex/components/radix/themes/components/context_menu.py +1 -1
  121. reflex/components/radix/themes/components/context_menu.pyi +238 -319
  122. reflex/components/radix/themes/components/data_list.py +1 -1
  123. reflex/components/radix/themes/components/data_list.pyi +130 -171
  124. reflex/components/radix/themes/components/dialog.py +1 -1
  125. reflex/components/radix/themes/components/dialog.pyi +139 -210
  126. reflex/components/radix/themes/components/dropdown_menu.py +1 -1
  127. reflex/components/radix/themes/components/dropdown_menu.pyi +249 -332
  128. reflex/components/radix/themes/components/hover_card.py +1 -1
  129. reflex/components/radix/themes/components/hover_card.pyi +90 -131
  130. reflex/components/radix/themes/components/icon_button.py +2 -3
  131. reflex/components/radix/themes/components/icon_button.pyi +98 -109
  132. reflex/components/radix/themes/components/inset.py +1 -1
  133. reflex/components/radix/themes/components/inset.pyi +47 -58
  134. reflex/components/radix/themes/components/popover.py +1 -1
  135. reflex/components/radix/themes/components/popover.pyi +95 -136
  136. reflex/components/radix/themes/components/progress.py +1 -1
  137. reflex/components/radix/themes/components/progress.pyi +71 -82
  138. reflex/components/radix/themes/components/radio.py +1 -1
  139. reflex/components/radix/themes/components/radio.pyi +69 -80
  140. reflex/components/radix/themes/components/radio_cards.py +1 -1
  141. reflex/components/radix/themes/components/radio_cards.pyi +98 -119
  142. reflex/components/radix/themes/components/radio_group.py +8 -11
  143. reflex/components/radix/themes/components/radio_group.pyi +228 -271
  144. reflex/components/radix/themes/components/scroll_area.py +1 -1
  145. reflex/components/radix/themes/components/scroll_area.pyi +21 -32
  146. reflex/components/radix/themes/components/segmented_control.py +1 -1
  147. reflex/components/radix/themes/components/segmented_control.pyi +90 -113
  148. reflex/components/radix/themes/components/select.py +2 -3
  149. reflex/components/radix/themes/components/select.pyi +374 -471
  150. reflex/components/radix/themes/components/separator.py +1 -2
  151. reflex/components/radix/themes/components/separator.pyi +69 -80
  152. reflex/components/radix/themes/components/skeleton.py +1 -1
  153. reflex/components/radix/themes/components/skeleton.pyi +23 -34
  154. reflex/components/radix/themes/components/slider.py +2 -3
  155. reflex/components/radix/themes/components/slider.pyi +75 -88
  156. reflex/components/radix/themes/components/spinner.py +1 -1
  157. reflex/components/radix/themes/components/spinner.pyi +19 -30
  158. reflex/components/radix/themes/components/switch.py +1 -1
  159. reflex/components/radix/themes/components/switch.pyi +71 -84
  160. reflex/components/radix/themes/components/table.py +1 -1
  161. reflex/components/radix/themes/components/table.pyi +261 -332
  162. reflex/components/radix/themes/components/tabs.py +1 -1
  163. reflex/components/radix/themes/components/tabs.pyi +139 -194
  164. reflex/components/radix/themes/components/text_area.py +1 -1
  165. reflex/components/radix/themes/components/text_area.pyi +96 -111
  166. reflex/components/radix/themes/components/text_field.py +1 -1
  167. reflex/components/radix/themes/components/text_field.pyi +247 -286
  168. reflex/components/radix/themes/components/tooltip.py +1 -1
  169. reflex/components/radix/themes/components/tooltip.pyi +26 -37
  170. reflex/components/radix/themes/layout/__init__.pyi +1 -0
  171. reflex/components/radix/themes/layout/base.py +1 -1
  172. reflex/components/radix/themes/layout/base.pyi +56 -67
  173. reflex/components/radix/themes/layout/box.pyi +34 -45
  174. reflex/components/radix/themes/layout/center.pyi +56 -67
  175. reflex/components/radix/themes/layout/container.py +1 -2
  176. reflex/components/radix/themes/layout/container.pyi +36 -47
  177. reflex/components/radix/themes/layout/flex.py +1 -1
  178. reflex/components/radix/themes/layout/flex.pyi +56 -67
  179. reflex/components/radix/themes/layout/grid.py +1 -1
  180. reflex/components/radix/themes/layout/grid.pyi +64 -75
  181. reflex/components/radix/themes/layout/list.py +5 -6
  182. reflex/components/radix/themes/layout/list.pyi +193 -244
  183. reflex/components/radix/themes/layout/section.py +1 -2
  184. reflex/components/radix/themes/layout/section.pyi +36 -47
  185. reflex/components/radix/themes/layout/spacer.pyi +56 -67
  186. reflex/components/radix/themes/layout/stack.py +1 -1
  187. reflex/components/radix/themes/layout/stack.pyi +128 -159
  188. reflex/components/radix/themes/typography/blockquote.py +1 -1
  189. reflex/components/radix/themes/typography/blockquote.pyi +89 -100
  190. reflex/components/radix/themes/typography/code.py +1 -1
  191. reflex/components/radix/themes/typography/code.pyi +90 -101
  192. reflex/components/radix/themes/typography/heading.py +1 -1
  193. reflex/components/radix/themes/typography/heading.pyi +96 -107
  194. reflex/components/radix/themes/typography/link.py +1 -1
  195. reflex/components/radix/themes/typography/link.pyi +102 -113
  196. reflex/components/radix/themes/typography/text.py +1 -1
  197. reflex/components/radix/themes/typography/text.pyi +501 -572
  198. reflex/components/react_player/audio.pyi +33 -60
  199. reflex/components/react_player/react_player.py +1 -1
  200. reflex/components/react_player/react_player.pyi +33 -60
  201. reflex/components/react_player/video.pyi +33 -60
  202. reflex/components/recharts/cartesian.py +2 -3
  203. reflex/components/recharts/cartesian.pyi +678 -861
  204. reflex/components/recharts/charts.py +4 -5
  205. reflex/components/recharts/charts.pyi +252 -357
  206. reflex/components/recharts/general.py +1 -2
  207. reflex/components/recharts/general.pyi +180 -231
  208. reflex/components/recharts/polar.py +4 -5
  209. reflex/components/recharts/polar.pyi +144 -181
  210. reflex/components/recharts/recharts.pyi +33 -53
  211. reflex/components/sonner/toast.py +16 -17
  212. reflex/components/sonner/toast.pyi +36 -47
  213. reflex/components/suneditor/editor.py +2 -3
  214. reflex/components/suneditor/editor.pyi +55 -78
  215. reflex/components/tags/cond_tag.py +6 -4
  216. reflex/components/tags/iter_tag.py +28 -16
  217. reflex/components/tags/match_tag.py +6 -4
  218. reflex/components/tags/tag.py +40 -23
  219. reflex/event.py +113 -65
  220. reflex/experimental/client_state.py +18 -18
  221. reflex/experimental/hooks.py +16 -16
  222. reflex/experimental/layout.py +5 -5
  223. reflex/experimental/layout.pyi +136 -187
  224. reflex/middleware/hydrate_middleware.py +2 -0
  225. reflex/middleware/middleware.py +3 -3
  226. reflex/state.py +148 -82
  227. reflex/style.py +21 -22
  228. reflex/utils/exceptions.py +16 -0
  229. reflex/utils/format.py +22 -34
  230. reflex/utils/imports.py +16 -73
  231. reflex/utils/prerequisites.py +15 -8
  232. reflex/utils/pyi_generator.py +13 -8
  233. reflex/utils/serializers.py +12 -22
  234. reflex/utils/telemetry.py +2 -1
  235. reflex/utils/types.py +10 -5
  236. reflex/{ivars → vars}/__init__.py +6 -2
  237. reflex/{ivars → vars}/base.py +567 -206
  238. reflex/{ivars → vars}/function.py +15 -19
  239. reflex/{ivars → vars}/number.py +16 -18
  240. reflex/{ivars → vars}/object.py +28 -30
  241. reflex/{ivars → vars}/sequence.py +53 -42
  242. {reflex-0.6.0a1.dist-info → reflex-0.6.0a2.dist-info}/METADATA +2 -2
  243. reflex-0.6.0a2.dist-info/RECORD +382 -0
  244. reflex/.templates/web/components/reflex/chakra_color_mode_provider.js +0 -36
  245. reflex/vars.py +0 -501
  246. reflex-0.6.0a1.dist-info/RECORD +0 -384
  247. {reflex-0.6.0a1.dist-info → reflex-0.6.0a2.dist-info}/LICENSE +0 -0
  248. {reflex-0.6.0a1.dist-info → reflex-0.6.0a2.dist-info}/WHEEL +0 -0
  249. {reflex-0.6.0a1.dist-info → reflex-0.6.0a2.dist-info}/entry_points.txt +0 -0
reflex/utils/format.py CHANGED
@@ -10,7 +10,6 @@ from typing import TYPE_CHECKING, Any, Callable, List, Optional, Union
10
10
 
11
11
  from reflex import constants
12
12
  from reflex.utils import exceptions, types
13
- from reflex.vars import Var
14
13
 
15
14
  if TYPE_CHECKING:
16
15
  from reflex.components.component import ComponentStyle
@@ -298,9 +297,9 @@ def format_route(route: str, format_case=True) -> str:
298
297
 
299
298
 
300
299
  def format_match(
301
- cond: str | ImmutableVar,
302
- match_cases: List[List[ImmutableVar]],
303
- default: ImmutableVar,
300
+ cond: str | Var,
301
+ match_cases: List[List[Var]],
302
+ default: Var,
304
303
  ) -> str:
305
304
  """Format a match expression whose return type is a Var.
306
305
 
@@ -332,7 +331,7 @@ def format_match(
332
331
 
333
332
 
334
333
  def format_prop(
335
- prop: Union[ImmutableVar, EventChain, ComponentStyle, str],
334
+ prop: Union[Var, EventChain, ComponentStyle, str],
336
335
  ) -> Union[int, float, str]:
337
336
  """Format a prop.
338
337
 
@@ -348,12 +347,12 @@ def format_prop(
348
347
  """
349
348
  # import here to avoid circular import.
350
349
  from reflex.event import EventChain
351
- from reflex.ivars import ImmutableVar
352
350
  from reflex.utils import serializers
351
+ from reflex.vars import Var
353
352
 
354
353
  try:
355
354
  # Handle var props.
356
- if isinstance(prop, ImmutableVar):
355
+ if isinstance(prop, Var):
357
356
  return str(prop)
358
357
 
359
358
  # Handle event props.
@@ -406,26 +405,15 @@ def format_props(*single_props, **key_value_props) -> list[str]:
406
405
  The formatted props list.
407
406
  """
408
407
  # Format all the props.
409
- from reflex.ivars.base import ImmutableVar, LiteralVar
408
+ from reflex.vars.base import LiteralVar, Var
410
409
 
411
410
  return [
412
411
  (
413
- f"{name}={format_prop(prop)}"
414
- if isinstance(prop, ImmutableVar) and not isinstance(prop, ImmutableVar)
415
- else (
416
- f"{name}={{{format_prop(prop if isinstance(prop, ImmutableVar) else LiteralVar.create(prop))}}}"
417
- )
412
+ f"{name}={{{format_prop(prop if isinstance(prop, Var) else LiteralVar.create(prop))}}}"
418
413
  )
419
414
  for name, prop in sorted(key_value_props.items())
420
415
  if prop is not None
421
- ] + [
422
- (
423
- str(prop)
424
- if isinstance(prop, ImmutableVar) and not isinstance(prop, ImmutableVar)
425
- else f"{str(LiteralVar.create(prop))}"
426
- )
427
- for prop in single_props
428
- ]
416
+ ] + [(f"{str(LiteralVar.create(prop))}") for prop in single_props]
429
417
 
430
418
 
431
419
  def get_event_handler_parts(handler: EventHandler) -> tuple[str, str]:
@@ -486,10 +474,10 @@ def format_event(event_spec: EventSpec) -> str:
486
474
  [
487
475
  ":".join(
488
476
  (
489
- name._var_name,
477
+ name._js_expr,
490
478
  (
491
479
  wrap(
492
- json.dumps(val._var_name).strip('"').replace("`", "\\`"),
480
+ json.dumps(val._js_expr).strip('"').replace("`", "\\`"),
493
481
  "`",
494
482
  )
495
483
  if val._var_is_string
@@ -511,7 +499,7 @@ def format_event(event_spec: EventSpec) -> str:
511
499
 
512
500
 
513
501
  if TYPE_CHECKING:
514
- from reflex.ivars import ImmutableVar
502
+ from reflex.vars import Var
515
503
 
516
504
 
517
505
  def format_queue_events(
@@ -523,7 +511,7 @@ def format_queue_events(
523
511
  | None
524
512
  ) = None,
525
513
  args_spec: Optional[ArgsSpec] = None,
526
- ) -> ImmutableVar[EventChain]:
514
+ ) -> Var[EventChain]:
527
515
  """Format a list of event handler / event spec as a javascript callback.
528
516
 
529
517
  The resulting code can be passed to interfaces that expect a callback
@@ -549,10 +537,10 @@ def format_queue_events(
549
537
  call_event_fn,
550
538
  call_event_handler,
551
539
  )
552
- from reflex.ivars import FunctionVar, ImmutableVar
540
+ from reflex.vars import FunctionVar, Var
553
541
 
554
542
  if not events:
555
- return ImmutableVar("(() => null)").to(FunctionVar, EventChain) # type: ignore
543
+ return Var("(() => null)").to(FunctionVar, EventChain) # type: ignore
556
544
 
557
545
  # If no spec is provided, the function will take no arguments.
558
546
  def _default_args_spec():
@@ -577,7 +565,7 @@ def format_queue_events(
577
565
  specs = [call_event_handler(spec, args_spec or _default_args_spec)]
578
566
  elif isinstance(spec, type(lambda: None)):
579
567
  specs = call_event_fn(spec, args_spec or _default_args_spec) # type: ignore
580
- if isinstance(specs, ImmutableVar):
568
+ if isinstance(specs, Var):
581
569
  raise ValueError(
582
570
  f"Invalid event spec: {specs}. Expected a list of EventSpecs."
583
571
  )
@@ -585,7 +573,7 @@ def format_queue_events(
585
573
 
586
574
  # Return the final code snippet, expecting queueEvents, processEvent, and socket to be in scope.
587
575
  # Typically this snippet will _only_ run from within an rx.call_script eval context.
588
- return ImmutableVar(
576
+ return Var(
589
577
  f"{arg_def} => {{queueEvents([{','.join(payloads)}], {constants.CompileVars.SOCKET}); "
590
578
  f"processEvent({constants.CompileVars.SOCKET})}}",
591
579
  ).to(FunctionVar, EventChain) # type: ignore
@@ -727,7 +715,7 @@ def collect_form_dict_names(form_dict: dict[str, Any]) -> dict[str, Any]:
727
715
  return collapsed
728
716
 
729
717
 
730
- def format_array_ref(refs: str, idx: ImmutableVar | None) -> str:
718
+ def format_array_ref(refs: str, idx: Var | None) -> str:
731
719
  """Format a ref accessed by array.
732
720
 
733
721
  Args:
@@ -756,7 +744,7 @@ def format_data_editor_column(col: str | dict):
756
744
  Returns:
757
745
  The formatted column.
758
746
  """
759
- from reflex.ivars import ImmutableVar
747
+ from reflex.vars import Var
760
748
 
761
749
  if isinstance(col, str):
762
750
  return {"title": col, "id": col.lower(), "type": "str"}
@@ -770,7 +758,7 @@ def format_data_editor_column(col: str | dict):
770
758
  col["overlayIcon"] = None
771
759
  return col
772
760
 
773
- if isinstance(col, ImmutableVar):
761
+ if isinstance(col, Var):
774
762
  return col
775
763
 
776
764
  raise ValueError(
@@ -787,9 +775,9 @@ def format_data_editor_cell(cell: Any):
787
775
  Returns:
788
776
  The formatted cell.
789
777
  """
790
- from reflex.ivars.base import ImmutableVar
778
+ from reflex.vars.base import Var
791
779
 
792
780
  return {
793
- "kind": ImmutableVar.create("GridCellKind.Text"),
781
+ "kind": Var(_js_expr="GridCellKind.Text"),
794
782
  "data": cell,
795
783
  }
reflex/utils/imports.py CHANGED
@@ -2,10 +2,9 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ import dataclasses
5
6
  from collections import defaultdict
6
- from typing import Dict, List, Optional, Tuple, Union
7
-
8
- from reflex.base import Base
7
+ from typing import DefaultDict, Dict, List, Optional, Tuple, Union
9
8
 
10
9
 
11
10
  def merge_imports(
@@ -19,12 +18,22 @@ def merge_imports(
19
18
  Returns:
20
19
  The merged import dicts.
21
20
  """
22
- all_imports = defaultdict(list)
21
+ all_imports: DefaultDict[str, List[ImportVar]] = defaultdict(list)
23
22
  for import_dict in imports:
24
23
  for lib, fields in (
25
24
  import_dict if isinstance(import_dict, tuple) else import_dict.items()
26
25
  ):
27
- all_imports[lib].extend(fields)
26
+ if isinstance(fields, (list, tuple, set)):
27
+ all_imports[lib].extend(
28
+ (
29
+ ImportVar(field) if isinstance(field, str) else field
30
+ for field in fields
31
+ )
32
+ )
33
+ else:
34
+ all_imports[lib].append(
35
+ ImportVar(fields) if isinstance(fields, str) else fields
36
+ )
28
37
  return all_imports
29
38
 
30
39
 
@@ -75,7 +84,8 @@ def collapse_imports(
75
84
  }
76
85
 
77
86
 
78
- class ImportVar(Base):
87
+ @dataclasses.dataclass(order=True, frozen=True)
88
+ class ImportVar:
79
89
  """An import var."""
80
90
 
81
91
  # The name of the import tag.
@@ -111,73 +121,6 @@ class ImportVar(Base):
111
121
  else:
112
122
  return self.tag or ""
113
123
 
114
- def __lt__(self, other: ImportVar) -> bool:
115
- """Compare two ImportVar objects.
116
-
117
- Args:
118
- other: The other ImportVar object to compare.
119
-
120
- Returns:
121
- Whether this ImportVar object is less than the other.
122
- """
123
- return (
124
- self.tag,
125
- self.is_default,
126
- self.alias,
127
- self.install,
128
- self.render,
129
- self.transpile,
130
- ) < (
131
- other.tag,
132
- other.is_default,
133
- other.alias,
134
- other.install,
135
- other.render,
136
- other.transpile,
137
- )
138
-
139
- def __eq__(self, other: ImportVar) -> bool:
140
- """Check if two ImportVar objects are equal.
141
-
142
- Args:
143
- other: The other ImportVar object to compare.
144
-
145
- Returns:
146
- Whether the two ImportVar objects are equal.
147
- """
148
- return (
149
- self.tag,
150
- self.is_default,
151
- self.alias,
152
- self.install,
153
- self.render,
154
- self.transpile,
155
- ) == (
156
- other.tag,
157
- other.is_default,
158
- other.alias,
159
- other.install,
160
- other.render,
161
- other.transpile,
162
- )
163
-
164
- def __hash__(self) -> int:
165
- """Hash the ImportVar object.
166
-
167
- Returns:
168
- The hash of the ImportVar object.
169
- """
170
- return hash(
171
- (
172
- self.tag,
173
- self.is_default,
174
- self.alias,
175
- self.install,
176
- self.render,
177
- self.transpile,
178
- )
179
- )
180
-
181
124
 
182
125
  ImportTypes = Union[str, ImportVar, List[Union[str, ImportVar]], List[ImportVar]]
183
126
  ImportDict = Dict[str, ImportTypes]
@@ -2,6 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ import dataclasses
5
6
  import functools
6
7
  import glob
7
8
  import importlib
@@ -32,7 +33,6 @@ from redis import exceptions
32
33
  from redis.asyncio import Redis
33
34
 
34
35
  from reflex import constants, model
35
- from reflex.base import Base
36
36
  from reflex.compiler import templates
37
37
  from reflex.config import Config, get_config
38
38
  from reflex.utils import console, net, path_ops, processes
@@ -42,7 +42,8 @@ from reflex.utils.registry import _get_best_registry
42
42
  CURRENTLY_INSTALLING_NODE = False
43
43
 
44
44
 
45
- class Template(Base):
45
+ @dataclasses.dataclass(frozen=True)
46
+ class Template:
46
47
  """A template for a Reflex app."""
47
48
 
48
49
  name: str
@@ -51,7 +52,8 @@ class Template(Base):
51
52
  demo_url: str
52
53
 
53
54
 
54
- class CpuInfo(Base):
55
+ @dataclasses.dataclass(frozen=True)
56
+ class CpuInfo:
55
57
  """Model to save cpu info."""
56
58
 
57
59
  manufacturer_id: Optional[str]
@@ -1277,11 +1279,16 @@ def fetch_app_templates(version: str) -> dict[str, Template]:
1277
1279
  ),
1278
1280
  None,
1279
1281
  )
1280
- return {
1281
- tp["name"]: Template.parse_obj(tp)
1282
- for tp in templates_data
1283
- if not tp["hidden"] and tp["code_url"] is not None
1284
- }
1282
+
1283
+ filtered_templates = {}
1284
+ for tp in templates_data:
1285
+ if tp["hidden"] or tp["code_url"] is None:
1286
+ continue
1287
+ known_fields = set(f.name for f in dataclasses.fields(Template))
1288
+ filtered_templates[tp["name"]] = Template(
1289
+ **{k: v for k, v in tp.items() if k in known_fields}
1290
+ )
1291
+ return filtered_templates
1285
1292
 
1286
1293
 
1287
1294
  def create_config_init_app_from_remote_template(app_name: str, template_url: str):
@@ -19,8 +19,8 @@ from types import ModuleType, SimpleNamespace
19
19
  from typing import Any, Callable, Iterable, Type, get_args
20
20
 
21
21
  from reflex.components.component import Component
22
- from reflex.ivars.base import ImmutableVar
23
22
  from reflex.utils import types as rx_types
23
+ from reflex.vars.base import Var
24
24
 
25
25
  logger = logging.getLogger("pyi_generator")
26
26
 
@@ -69,11 +69,10 @@ DEFAULT_TYPING_IMPORTS = {
69
69
  # TODO: fix import ordering and unused imports with ruff later
70
70
  DEFAULT_IMPORTS = {
71
71
  "typing": sorted(DEFAULT_TYPING_IMPORTS),
72
- "reflex.vars": ["Var"],
73
72
  "reflex.components.core.breakpoints": ["Breakpoints"],
74
73
  "reflex.event": ["EventChain", "EventHandler", "EventSpec"],
75
74
  "reflex.style": ["Style"],
76
- "reflex.ivars.base": ["ImmutableVar"],
75
+ "reflex.vars.base": ["Var"],
77
76
  }
78
77
 
79
78
 
@@ -151,7 +150,7 @@ def _get_type_hint(value, type_hint_globals, is_optional=True) -> str:
151
150
 
152
151
  if args:
153
152
  inner_container_type_args = (
154
- [repr(arg) for arg in args]
153
+ sorted((repr(arg) for arg in args))
155
154
  if rx_types.is_literal(value)
156
155
  else [
157
156
  _get_type_hint(arg, type_hint_globals, is_optional=False)
@@ -185,7 +184,7 @@ def _get_type_hint(value, type_hint_globals, is_optional=True) -> str:
185
184
  if arg is not type(None)
186
185
  ]
187
186
  if len(types) > 1:
188
- res = ", ".join(types)
187
+ res = ", ".join(sorted(types))
189
188
  res = f"Union[{res}]"
190
189
  elif isinstance(value, str):
191
190
  ev = eval(value, type_hint_globals)
@@ -356,7 +355,7 @@ def _extract_class_props_as_ast_nodes(
356
355
  with contextlib.suppress(AttributeError, KeyError):
357
356
  # Try to get default from pydantic field definition.
358
357
  default = target_class.__fields__[name].default
359
- if isinstance(default, ImmutableVar):
358
+ if isinstance(default, Var):
360
359
  default = default._decode() # type: ignore
361
360
 
362
361
  kwargs.append(
@@ -434,7 +433,7 @@ def _generate_component_create_functiondef(
434
433
  ast.arg(
435
434
  arg=trigger,
436
435
  annotation=ast.Name(
437
- id="Optional[Union[EventHandler, EventSpec, list, Callable, ImmutableVar]]"
436
+ id="Optional[Union[EventHandler, EventSpec, list, Callable, Var]]"
438
437
  ),
439
438
  ),
440
439
  ast.Constant(value=None),
@@ -903,7 +902,13 @@ class PyiGenerator:
903
902
  # construct the import statement and handle special cases for aliases
904
903
  sub_mod_attrs_imports = [
905
904
  f"from .{path} import {mod if not isinstance(mod, tuple) else mod[0]} as {mod if not isinstance(mod, tuple) else mod[1]}"
906
- + (" # type: ignore" if mod in pyright_ignore_imports else "")
905
+ + (
906
+ " # type: ignore"
907
+ if mod in pyright_ignore_imports
908
+ else " # noqa" # ignore ruff formatting here for cases like rx.list.
909
+ if isinstance(mod, tuple)
910
+ else ""
911
+ )
907
912
  for mod, path in sub_mod_attrs.items()
908
913
  ]
909
914
  sub_mod_attrs_imports.append("")
@@ -2,6 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ import dataclasses
5
6
  import functools
6
7
  import json
7
8
  import warnings
@@ -29,7 +30,7 @@ from reflex.utils import types
29
30
 
30
31
  # Mapping from type to a serializer.
31
32
  # The serializer should convert the type to a JSON object.
32
- SerializedType = Union[str, bool, int, float, list, dict]
33
+ SerializedType = Union[str, bool, int, float, list, dict, None]
33
34
 
34
35
 
35
36
  Serializer = Callable[[Type], SerializedType]
@@ -124,6 +125,8 @@ def serialize(
124
125
 
125
126
  # If there is no serializer, return None.
126
127
  if serializer is None:
128
+ if dataclasses.is_dataclass(value) and not isinstance(value, type):
129
+ return serialize(dataclasses.asdict(value))
127
130
  if get_type:
128
131
  return None, None
129
132
  return None
@@ -225,7 +228,7 @@ def serialize_str(value: str) -> str:
225
228
 
226
229
 
227
230
  @serializer
228
- def serialize_primitive(value: Union[bool, int, float, None]) -> str:
231
+ def serialize_primitive(value: Union[bool, int, float, None]):
229
232
  """Serialize a primitive type.
230
233
 
231
234
  Args:
@@ -234,13 +237,11 @@ def serialize_primitive(value: Union[bool, int, float, None]) -> str:
234
237
  Returns:
235
238
  The serialized number/bool/None.
236
239
  """
237
- from reflex.utils import format
238
-
239
- return format.json_dumps(value)
240
+ return value
240
241
 
241
242
 
242
243
  @serializer
243
- def serialize_base(value: Base) -> str:
244
+ def serialize_base(value: Base) -> dict:
244
245
  """Serialize a Base instance.
245
246
 
246
247
  Args:
@@ -249,18 +250,11 @@ def serialize_base(value: Base) -> str:
249
250
  Returns:
250
251
  The serialized Base.
251
252
  """
252
- from reflex.ivars import LiteralObjectVar
253
-
254
- return str(
255
- LiteralObjectVar.create(
256
- {k: (None if callable(v) else v) for k, v in value.dict().items()},
257
- _var_type=type(value),
258
- )
259
- )
253
+ return {k: serialize(v) for k, v in value.dict().items() if not callable(v)}
260
254
 
261
255
 
262
256
  @serializer
263
- def serialize_list(value: Union[List, Tuple, Set]) -> str:
257
+ def serialize_list(value: Union[List, Tuple, Set]) -> list:
264
258
  """Serialize a list to a JSON string.
265
259
 
266
260
  Args:
@@ -269,13 +263,11 @@ def serialize_list(value: Union[List, Tuple, Set]) -> str:
269
263
  Returns:
270
264
  The serialized list.
271
265
  """
272
- from reflex.ivars import LiteralArrayVar
273
-
274
- return str(LiteralArrayVar.create(value))
266
+ return [serialize(item) for item in value]
275
267
 
276
268
 
277
269
  @serializer
278
- def serialize_dict(prop: Dict[str, Any]) -> str:
270
+ def serialize_dict(prop: Dict[str, Any]) -> dict:
279
271
  """Serialize a dictionary to a JSON string.
280
272
 
281
273
  Args:
@@ -284,9 +276,7 @@ def serialize_dict(prop: Dict[str, Any]) -> str:
284
276
  Returns:
285
277
  The serialized dictionary.
286
278
  """
287
- from reflex.ivars import LiteralObjectVar
288
-
289
- return str(LiteralObjectVar.create(prop))
279
+ return {k: serialize(v) for k, v in prop.items()}
290
280
 
291
281
 
292
282
  @serializer(to=str)
reflex/utils/telemetry.py CHANGED
@@ -3,6 +3,7 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import asyncio
6
+ import dataclasses
6
7
  import multiprocessing
7
8
  import platform
8
9
  import warnings
@@ -144,7 +145,7 @@ def _prepare_event(event: str, **kwargs) -> dict:
144
145
  "python_version": get_python_version(),
145
146
  "cpu_count": get_cpu_count(),
146
147
  "memory": get_memory(),
147
- "cpu_info": dict(cpuinfo) if cpuinfo else {},
148
+ "cpu_info": dataclasses.asdict(cpuinfo) if cpuinfo else {},
148
149
  **additional_fields,
149
150
  },
150
151
  "timestamp": stamp,
reflex/utils/types.py CHANGED
@@ -3,6 +3,7 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import contextlib
6
+ import dataclasses
6
7
  import inspect
7
8
  import sys
8
9
  import types
@@ -95,7 +96,7 @@ PrimitiveType = Union[int, float, bool, str, list, dict, set, tuple]
95
96
  StateVar = Union[PrimitiveType, Base, None]
96
97
  StateIterVar = Union[list, set, tuple]
97
98
 
98
- # ArgsSpec = Callable[[ImmutableVar], list[ImmutableVar]]
99
+ # ArgsSpec = Callable[[Var], list[Var]]
99
100
  ArgsSpec = Callable
100
101
 
101
102
 
@@ -480,7 +481,11 @@ def is_valid_var_type(type_: Type) -> bool:
480
481
 
481
482
  if is_union(type_):
482
483
  return all((is_valid_var_type(arg) for arg in get_args(type_)))
483
- return _issubclass(type_, StateVar) or serializers.has_serializer(type_)
484
+ return (
485
+ _issubclass(type_, StateVar)
486
+ or serializers.has_serializer(type_)
487
+ or dataclasses.is_dataclass(type_)
488
+ )
484
489
 
485
490
 
486
491
  def is_backend_base_variable(name: str, cls: Type) -> bool:
@@ -514,7 +519,7 @@ def is_backend_base_variable(name: str, cls: Type) -> bool:
514
519
  if name in cls.inherited_backend_vars:
515
520
  return False
516
521
 
517
- from reflex.ivars.base import is_computed_var
522
+ from reflex.vars.base import is_computed_var
518
523
 
519
524
  if name in cls.__dict__:
520
525
  value = cls.__dict__[name]
@@ -590,11 +595,11 @@ def validate_literal(key: str, value: Any, expected_type: Type, comp_name: str):
590
595
  Raises:
591
596
  ValueError: When the value is not a valid literal.
592
597
  """
593
- from reflex.ivars import ImmutableVar
598
+ from reflex.vars import Var
594
599
 
595
600
  if (
596
601
  is_literal(expected_type)
597
- and not isinstance(value, ImmutableVar) # validating vars is not supported yet.
602
+ and not isinstance(value, Var) # validating vars is not supported yet.
598
603
  and not is_encoded_fstring(value) # f-strings are not supported.
599
604
  and value not in expected_type.__args__
600
605
  ):
@@ -1,8 +1,12 @@
1
- """Experimental Immutable-Based Var System."""
1
+ """Immutable-Based Var System."""
2
2
 
3
- from .base import ImmutableVar as ImmutableVar
4
3
  from .base import LiteralVar as LiteralVar
4
+ from .base import Var as Var
5
+ from .base import VarData as VarData
6
+ from .base import get_unique_variable_name as get_unique_variable_name
7
+ from .base import get_uuid_string_var as get_uuid_string_var
5
8
  from .base import var_operation as var_operation
9
+ from .base import var_operation_return as var_operation_return
6
10
  from .function import FunctionStringVar as FunctionStringVar
7
11
  from .function import FunctionVar as FunctionVar
8
12
  from .function import VarOperationCall as VarOperationCall