Skip to content

Commit bf4d783

Browse files
committed
Add single-pass component tree collector and compiler plugin foundations
Replace 6 separate recursive tree walks (_get_all_imports, _get_all_hooks, _get_all_custom_code, _get_all_dynamic_imports, _get_all_refs, _get_all_app_wrap_components) with a single collect_component_tree_artifacts walk that gathers all compilation data in one pass. Wire the new collector into app.py, compiler.py, and utils.py. Add CompilerPlugin protocol, CompilerHooks dispatcher, and BaseContext/ PageContext/CompileContext types as foundations for the async plugin pipeline.
1 parent 2178184 commit bf4d783

8 files changed

Lines changed: 1199 additions & 144 deletions

File tree

pyi_hashes.json

Lines changed: 0 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -1,123 +1,4 @@
11
{
2-
"packages/reflex-components-code/src/reflex_components_code/code.pyi": "a252d3efb9c621216c3ac32327158a83",
3-
"packages/reflex-components-code/src/reflex_components_code/shiki_code_block.pyi": "2ae0bc697886c5a735afbe232a84f022",
4-
"packages/reflex-components-core/src/reflex_components_core/__init__.pyi": "e4f253225cf70b62900e25d0a5c16436",
5-
"packages/reflex-components-core/src/reflex_components_core/base/__init__.pyi": "407342f78a72e87489c8b22e40de68b9",
6-
"packages/reflex-components-core/src/reflex_components_core/base/app_wrap.pyi": "8a0b6dcdf622b96be65311b7803c8ce9",
7-
"packages/reflex-components-core/src/reflex_components_core/base/body.pyi": "aa734326f57b0fee9caed75bd318762e",
8-
"packages/reflex-components-core/src/reflex_components_core/base/document.pyi": "8edb8967aa628329c4d1b7cfa3705f3a",
9-
"packages/reflex-components-core/src/reflex_components_core/base/error_boundary.pyi": "c02999fa5d121904a242a83d2221f069",
10-
"packages/reflex-components-core/src/reflex_components_core/base/fragment.pyi": "ba9a750fa1036dd4f454e7f3235aa4aa",
11-
"packages/reflex-components-core/src/reflex_components_core/base/link.pyi": "fbae966c13c0da651a1e35f7045799c1",
12-
"packages/reflex-components-core/src/reflex_components_core/base/meta.pyi": "9c1df9038ff6394cac77dbac6b3175c5",
13-
"packages/reflex-components-core/src/reflex_components_core/base/script.pyi": "434ca63fb809077642112d53879380f5",
14-
"packages/reflex-components-core/src/reflex_components_core/base/strict_mode.pyi": "4002f8ac81d1b38177c3b837cbc3b44d",
15-
"packages/reflex-components-core/src/reflex_components_core/core/__init__.pyi": "3c22950d97f6017b8e6cc6a6c83cb4b3",
16-
"packages/reflex-components-core/src/reflex_components_core/core/auto_scroll.pyi": "3f8b625f5b38a9351b01201c7adb2ca0",
17-
"packages/reflex-components-core/src/reflex_components_core/core/banner.pyi": "b2e4b26b13f33d8900550fedd2d5f447",
18-
"packages/reflex-components-core/src/reflex_components_core/core/clipboard.pyi": "4164c841934cab71b1c4b132d15663f5",
19-
"packages/reflex-components-core/src/reflex_components_core/core/debounce.pyi": "d01e9934bcfd81b5fc969d82e362ac20",
20-
"packages/reflex-components-core/src/reflex_components_core/core/helmet.pyi": "3bf7bee5665293f7583009f651ea3cb1",
21-
"packages/reflex-components-core/src/reflex_components_core/core/html.pyi": "7209d1607545e412ed38dbe2a129321c",
22-
"packages/reflex-components-core/src/reflex_components_core/core/sticky.pyi": "8241c75ca16a0960b7dea6d6e7aff52e",
23-
"packages/reflex-components-core/src/reflex_components_core/core/upload.pyi": "73e38c074d7e6ca2fda8eaad820f177e",
24-
"packages/reflex-components-core/src/reflex_components_core/core/window_events.pyi": "4407cecb1825dc359bcc7b2bea011a8e",
25-
"packages/reflex-components-core/src/reflex_components_core/datadisplay/__init__.pyi": "aaab42816119ac0f308841dc5482b3f1",
26-
"packages/reflex-components-core/src/reflex_components_core/el/__init__.pyi": "e27fddec8de079db37d6699e136411d1",
27-
"packages/reflex-components-core/src/reflex_components_core/el/element.pyi": "6add8b77380ea3702031b07330fc7d60",
28-
"packages/reflex-components-core/src/reflex_components_core/el/elements/__init__.pyi": "721b328e94510f8328728be1657abbb8",
29-
"packages/reflex-components-core/src/reflex_components_core/el/elements/base.pyi": "7c427fcd82fc6ccf86b4d2b5c4756426",
30-
"packages/reflex-components-core/src/reflex_components_core/el/elements/forms.pyi": "5912179a169da4dc3b152042558be2cf",
31-
"packages/reflex-components-core/src/reflex_components_core/el/elements/inline.pyi": "6bf366f345e14a556dbb3c0f230e1355",
32-
"packages/reflex-components-core/src/reflex_components_core/el/elements/media.pyi": "f8d2a995e488ebc5e8633977151758ce",
33-
"packages/reflex-components-core/src/reflex_components_core/el/elements/metadata.pyi": "20d803fcc05d4c378547ceaa0e1bcc70",
34-
"packages/reflex-components-core/src/reflex_components_core/el/elements/other.pyi": "1cf906cbc2751f87adbcd85e03b72d2e",
35-
"packages/reflex-components-core/src/reflex_components_core/el/elements/scripts.pyi": "b4b5bb69e6ce8d08c0df51301e132af4",
36-
"packages/reflex-components-core/src/reflex_components_core/el/elements/sectioning.pyi": "4ce119b25459a01d128bdb5b79b0d128",
37-
"packages/reflex-components-core/src/reflex_components_core/el/elements/tables.pyi": "9e58353a97dc006d37d2c7c50506fac4",
38-
"packages/reflex-components-core/src/reflex_components_core/el/elements/typography.pyi": "3325f8a4af0aadb70cbfc50558e2f3b2",
39-
"packages/reflex-components-core/src/reflex_components_core/react_router/dom.pyi": "d77a80f688b29d2e1048007172d2b65f",
40-
"packages/reflex-components-dataeditor/src/reflex_components_dataeditor/dataeditor.pyi": "caa83be6f97faa95588bfa9ae9e9331e",
41-
"packages/reflex-components-gridjs/src/reflex_components_gridjs/datatable.pyi": "32880736442800061a39ce4b55267eaf",
42-
"packages/reflex-components-lucide/src/reflex_components_lucide/icon.pyi": "e55c023c9ecc907321f163955f4c4875",
43-
"packages/reflex-components-markdown/src/reflex_components_markdown/markdown.pyi": "bacf19a5b6904281d7238dbd51e6fc1c",
44-
"packages/reflex-components-moment/src/reflex_components_moment/moment.pyi": "b997bdd994844f0e6ca923bbb2dc34a1",
45-
"packages/reflex-components-plotly/src/reflex_components_plotly/plotly.pyi": "65a93d778a0fde06975dac9244f51bb3",
46-
"packages/reflex-components-radix/src/reflex_components_radix/__init__.pyi": "4843dd071acb073dc30028322c3d4023",
47-
"packages/reflex-components-radix/src/reflex_components_radix/primitives/__init__.pyi": "bc25cae0eca01c8684443d5dfd7b6455",
48-
"packages/reflex-components-radix/src/reflex_components_radix/primitives/accordion.pyi": "6dd30847af62ad7d50d5c5daf6c4a1d7",
49-
"packages/reflex-components-radix/src/reflex_components_radix/primitives/base.pyi": "6c12ef3d9f82926bf17d410b774d56f5",
50-
"packages/reflex-components-radix/src/reflex_components_radix/primitives/dialog.pyi": "810fa8c626b79035cdbb04f43b5bc5ad",
51-
"packages/reflex-components-radix/src/reflex_components_radix/primitives/drawer.pyi": "cb67e835f9be41f70ee2bae0f8c0a764",
52-
"packages/reflex-components-radix/src/reflex_components_radix/primitives/form.pyi": "ba31009535c078df0bc5a26bce6dfd2b",
53-
"packages/reflex-components-radix/src/reflex_components_radix/primitives/progress.pyi": "2356caa9e23f9c8888cccbbb41b57985",
54-
"packages/reflex-components-radix/src/reflex_components_radix/primitives/slider.pyi": "f694033992ef188f2da04e865d5a7d77",
55-
"packages/reflex-components-radix/src/reflex_components_radix/themes/__init__.pyi": "5d9a06872953d3e3df99e1ff154a4e0c",
56-
"packages/reflex-components-radix/src/reflex_components_radix/themes/base.pyi": "d7c20bd180f28fdb4affcba37e2aa1ff",
57-
"packages/reflex-components-radix/src/reflex_components_radix/themes/color_mode.pyi": "ba0ff3b00289cd1896e327fa2be99563",
58-
"packages/reflex-components-radix/src/reflex_components_radix/themes/components/__init__.pyi": "2b0f9f472ba6dcc743c2df17642c4a4b",
59-
"packages/reflex-components-radix/src/reflex_components_radix/themes/components/alert_dialog.pyi": "fad40b463a8ebb0d3ca3900dc8a91679",
60-
"packages/reflex-components-radix/src/reflex_components_radix/themes/components/aspect_ratio.pyi": "0d22969c5407592a0bb36768e149f2b5",
61-
"packages/reflex-components-radix/src/reflex_components_radix/themes/components/avatar.pyi": "6a6e9b8f6ca3428c45d62bd0e7f94693",
62-
"packages/reflex-components-radix/src/reflex_components_radix/themes/components/badge.pyi": "d96b2048ae17a558d9eb3378ae98524e",
63-
"packages/reflex-components-radix/src/reflex_components_radix/themes/components/button.pyi": "1c7f518e1881e98614eadff952da0844",
64-
"packages/reflex-components-radix/src/reflex_components_radix/themes/components/callout.pyi": "be245c1c3796f695ac4b2d77c3b88a3a",
65-
"packages/reflex-components-radix/src/reflex_components_radix/themes/components/card.pyi": "b56fa19913ed15d9e630951e70479b36",
66-
"packages/reflex-components-radix/src/reflex_components_radix/themes/components/checkbox.pyi": "f33d86a3bb176e3144570198ce5f93ae",
67-
"packages/reflex-components-radix/src/reflex_components_radix/themes/components/checkbox_cards.pyi": "10af49cf574b738d616803df2c055ad0",
68-
"packages/reflex-components-radix/src/reflex_components_radix/themes/components/checkbox_group.pyi": "3edbddceb585fd80d9e7959977ff276e",
69-
"packages/reflex-components-radix/src/reflex_components_radix/themes/components/context_menu.pyi": "0a06f6fa5cf8a2590c302f618451ca65",
70-
"packages/reflex-components-radix/src/reflex_components_radix/themes/components/data_list.pyi": "82508b83193afde0b3bc06911cb78f87",
71-
"packages/reflex-components-radix/src/reflex_components_radix/themes/components/dialog.pyi": "8f21ba52183221d4cf0b8beaacd8e006",
72-
"packages/reflex-components-radix/src/reflex_components_radix/themes/components/dropdown_menu.pyi": "b167c32571142878305d98c0bd656b09",
73-
"packages/reflex-components-radix/src/reflex_components_radix/themes/components/hover_card.pyi": "8009f36c543c1407e2aa7ead41178ceb",
74-
"packages/reflex-components-radix/src/reflex_components_radix/themes/components/icon_button.pyi": "3814bb2950e2bcc454d186d50d123e9f",
75-
"packages/reflex-components-radix/src/reflex_components_radix/themes/components/inset.pyi": "31af9b53ec38736ab7457ea731642869",
76-
"packages/reflex-components-radix/src/reflex_components_radix/themes/components/popover.pyi": "2ca6dfe4f9e00f2647f0ad4fd131e6d3",
77-
"packages/reflex-components-radix/src/reflex_components_radix/themes/components/progress.pyi": "7a874fa512ce2d8a490aa41531f5814b",
78-
"packages/reflex-components-radix/src/reflex_components_radix/themes/components/radio.pyi": "465a6d6e9525ac909b4f193d2d788682",
79-
"packages/reflex-components-radix/src/reflex_components_radix/themes/components/radio_cards.pyi": "ddb2835ecbeaf90681e4030a14d74604",
80-
"packages/reflex-components-radix/src/reflex_components_radix/themes/components/radio_group.pyi": "d5333b59e6ba9ad30923d2b60d0e382e",
81-
"packages/reflex-components-radix/src/reflex_components_radix/themes/components/scroll_area.pyi": "6b2d881a8ecdf4dd169b341418a703db",
82-
"packages/reflex-components-radix/src/reflex_components_radix/themes/components/segmented_control.pyi": "79764047f53543d673d6e1b2c929d9b8",
83-
"packages/reflex-components-radix/src/reflex_components_radix/themes/components/select.pyi": "f71a320b02ac8f1d6db07b9198b296ec",
84-
"packages/reflex-components-radix/src/reflex_components_radix/themes/components/separator.pyi": "f8420b5196edb74275d2119d780d0031",
85-
"packages/reflex-components-radix/src/reflex_components_radix/themes/components/skeleton.pyi": "574407d03b311ca9cdf0f98ab53a6fbe",
86-
"packages/reflex-components-radix/src/reflex_components_radix/themes/components/slider.pyi": "9e26688af77fab944635e16e0bf7283f",
87-
"packages/reflex-components-radix/src/reflex_components_radix/themes/components/spinner.pyi": "3477cc5e00146eaa2cde5d35f9459ad6",
88-
"packages/reflex-components-radix/src/reflex_components_radix/themes/components/switch.pyi": "37e0c8dc43c5a24bdba03429e3ca9052",
89-
"packages/reflex-components-radix/src/reflex_components_radix/themes/components/table.pyi": "c910ebd02d7a78627f884e3431426552",
90-
"packages/reflex-components-radix/src/reflex_components_radix/themes/components/tabs.pyi": "ead639a106a76cc0e3fd2c8f093f9f23",
91-
"packages/reflex-components-radix/src/reflex_components_radix/themes/components/text_area.pyi": "1a03d9525a1544816392067499c3354d",
92-
"packages/reflex-components-radix/src/reflex_components_radix/themes/components/text_field.pyi": "c2fbd8547de4993e03017844e8c4b477",
93-
"packages/reflex-components-radix/src/reflex_components_radix/themes/components/tooltip.pyi": "4545b70fd0802f19993419ab0163d595",
94-
"packages/reflex-components-radix/src/reflex_components_radix/themes/layout/__init__.pyi": "417e490adc15e93dc2cdb854ee0361d2",
95-
"packages/reflex-components-radix/src/reflex_components_radix/themes/layout/base.pyi": "3195e198d92ff43644a09c277303b83b",
96-
"packages/reflex-components-radix/src/reflex_components_radix/themes/layout/box.pyi": "69d12b6c918a476ac4557f42fef73c27",
97-
"packages/reflex-components-radix/src/reflex_components_radix/themes/layout/center.pyi": "88880d197ff7347ec7d3f81d6e57de8e",
98-
"packages/reflex-components-radix/src/reflex_components_radix/themes/layout/container.pyi": "f329387a5d4a988bc195e6a487ff44db",
99-
"packages/reflex-components-radix/src/reflex_components_radix/themes/layout/flex.pyi": "855c9d0c3c2e79e7d3811cfec74d6379",
100-
"packages/reflex-components-radix/src/reflex_components_radix/themes/layout/grid.pyi": "bd2c31d4e3d61743b72327f071969e05",
101-
"packages/reflex-components-radix/src/reflex_components_radix/themes/layout/list.pyi": "eee53b418ff0e0660c8cf9d8a0a59386",
102-
"packages/reflex-components-radix/src/reflex_components_radix/themes/layout/section.pyi": "1aa57142797597d65d840eb1d3cc7de7",
103-
"packages/reflex-components-radix/src/reflex_components_radix/themes/layout/spacer.pyi": "c774f0a1384f983e6d73bde603c341ca",
104-
"packages/reflex-components-radix/src/reflex_components_radix/themes/layout/stack.pyi": "894dcd5945123c1c8aa34cb77602fead",
105-
"packages/reflex-components-radix/src/reflex_components_radix/themes/typography/__init__.pyi": "3926877c04f74fc2acf4a398bee9da06",
106-
"packages/reflex-components-radix/src/reflex_components_radix/themes/typography/blockquote.pyi": "305a8932078e4af48e44489e7ce74060",
107-
"packages/reflex-components-radix/src/reflex_components_radix/themes/typography/code.pyi": "fad43053747fb84229cc35296c7028b5",
108-
"packages/reflex-components-radix/src/reflex_components_radix/themes/typography/heading.pyi": "5901c7202a5b135f60cc1407878b4859",
109-
"packages/reflex-components-radix/src/reflex_components_radix/themes/typography/link.pyi": "d567c1242672d125015920f7ae6e6999",
110-
"packages/reflex-components-radix/src/reflex_components_radix/themes/typography/text.pyi": "76f100da40d0e18ad4f7b3387dec1d4a",
111-
"packages/reflex-components-react-player/src/reflex_components_react_player/audio.pyi": "a981a6031015c3a384e6255be88885f1",
112-
"packages/reflex-components-react-player/src/reflex_components_react_player/react_player.pyi": "1f66ea4fa34e8a8fa7473d312daf84b8",
113-
"packages/reflex-components-react-player/src/reflex_components_react_player/video.pyi": "8c1ea5bf4ec27ec6ff2dce462021b094",
114-
"packages/reflex-components-recharts/src/reflex_components_recharts/__init__.pyi": "2610c28416f80e2254bd10dde8c29bdf",
115-
"packages/reflex-components-recharts/src/reflex_components_recharts/cartesian.pyi": "597b9eb86c57f5293c13c128fb972c27",
116-
"packages/reflex-components-recharts/src/reflex_components_recharts/charts.pyi": "303d4b1dc72c08339154907b9b095365",
117-
"packages/reflex-components-recharts/src/reflex_components_recharts/general.pyi": "6e9371bddea95f8e2491d9b3c7e250cd",
118-
"packages/reflex-components-recharts/src/reflex_components_recharts/polar.pyi": "1ce679c002336c7bdbdd6c8ff6f2413c",
119-
"packages/reflex-components-recharts/src/reflex_components_recharts/recharts.pyi": "1b92135de4ea79cb7d94eaaec55b9ab7",
120-
"packages/reflex-components-sonner/src/reflex_components_sonner/toast.pyi": "f09c503c4ab880c13c13d6fa67d708b8",
1212
"reflex/__init__.pyi": "7696c38fd9c04a598518b49c5185c414",
1223
"reflex/components/__init__.pyi": "55bb242d5e5428db329b88b4923c2ba5",
1234
"reflex/experimental/memo.pyi": "d16eccf33993c781e2f8bc2dd8bbd4d4"

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ asyncio_mode = "auto"
230230

231231
[tool.codespell]
232232
skip = "docs/*,*.html,examples/*, *.pyi, poetry.lock, uv.lock"
233-
ignore-words-list = "te, TreeE, selectin"
233+
ignore-words-list = "te, TreeE, selectin, asend"
234234

235235

236236
[tool.coverage.run]

reflex/app.py

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@
8585
compile_theme,
8686
readable_name_from_component,
8787
)
88+
from reflex.compiler.plugins import collect_component_tree_artifacts
8889
from reflex.experimental.memo import EXPERIMENTAL_MEMOS
8990
from reflex.istate.manager import StateManager, StateModificationContext
9091
from reflex.istate.proxy import StateProxy
@@ -1293,11 +1294,19 @@ def memoized_toast_provider():
12931294
# This has to happen before compiling stateful components as that
12941295
# prevents recursive functions from reaching all components.
12951296
for component in self._pages.values():
1296-
# Add component._get_all_imports() to all_imports.
1297-
all_imports.update(component._get_all_imports())
1297+
collected = collect_component_tree_artifacts(
1298+
component,
1299+
collect_hooks=False,
1300+
collect_custom_code=False,
1301+
collect_dynamic_imports=False,
1302+
collect_refs=False,
1303+
)
1304+
1305+
# Add the page imports discovered during a single tree walk.
1306+
all_imports.update(collected["imports"])
12981307

12991308
# Add the app wrappers from this component.
1300-
app_wrappers.update(component._get_all_app_wrap_components())
1309+
app_wrappers.update(collected["app_wrap_components"])
13011310

13021311
progress.advance(task)
13031312

@@ -1421,7 +1430,16 @@ def _submit_work_without_advancing(
14211430
app_root = self._app_root(app_wrappers=app_wrappers)
14221431

14231432
# Get imports from AppWrap components.
1424-
all_imports.update(app_root._get_all_imports())
1433+
all_imports.update(
1434+
collect_component_tree_artifacts(
1435+
app_root,
1436+
collect_hooks=False,
1437+
collect_custom_code=False,
1438+
collect_dynamic_imports=False,
1439+
collect_refs=False,
1440+
collect_app_wrap_components=False,
1441+
)["imports"]
1442+
)
14251443

14261444
progress.advance(task)
14271445

0 commit comments

Comments
 (0)