Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
bed2372
Serve the Reflex chart data plane as a channel on the app websocket, …
benedikt-bartscher Sep 12, 2026
7c7de9a
Address PR review: per-app channel attachment, pinned Reflex commit, …
benedikt-bartscher Sep 12, 2026
651e2c1
Bump the pinned Reflex channel commit to ea517ec4
benedikt-bartscher Sep 12, 2026
e8d11f6
Fail the data plane tests when the reader broke but nothing read the …
benedikt-bartscher Sep 12, 2026
c4154ca
Bump the pinned Reflex channel commit to b8580ed1
benedikt-bartscher Sep 12, 2026
875fa44
Check upload conditions structurally, align the browser gate, and exe…
benedikt-bartscher Sep 12, 2026
ebcd098
Keep the browser harness app in a self-deleting temp dir
benedikt-bartscher Sep 12, 2026
62ebcf3
Reject duplicate workflow step names; bump the pinned Reflex commit t…
benedikt-bartscher Sep 12, 2026
353f32f
Normalize workflow step names before comparing them
benedikt-bartscher Sep 12, 2026
16ec8fe
Bump the pinned Reflex channel commit to 609b2f51
benedikt-bartscher Sep 12, 2026
e98352f
Merge remote-tracking branch 'origin/main' into reflex-channels-port
benedikt-bartscher Oct 17, 2026
001b776
Bump the pinned Reflex channel commit to 7ff41648
benedikt-bartscher Oct 17, 2026
116f00b
Fan a cache-miss rebuild out to every attached app
benedikt-bartscher Oct 17, 2026
fd4cbed
Fail data plane test setup at once when the reader stops
benedikt-bartscher Oct 17, 2026
1b63ca8
Describe the app-wide rebuild fan-out on the new-sub path too
benedikt-bartscher Oct 17, 2026
bd25f59
Keep a rebuilt generation another app received and find step names an…
benedikt-bartscher Oct 17, 2026
de704ce
Resync the apps that missed a fanned-out payload
benedikt-bartscher Oct 17, 2026
a750b78
Merge upstream main into reflex-channels-port
FarhanAliRaza Oct 27, 2026
95c0ff0
Remove local validation artifacts from the source tree
FarhanAliRaza Oct 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,9 @@ jobs:
timeout-minutes: 5
uses: ./.github/actions/setup-ci-chromium

- name: Install Chromium (Playwright, Python bindings)
run: .venv/bin/playwright install --with-deps chromium chromium-headless-shell

- name: Python tests (native core)
# Point PNG-export tests at the Playwright Chromium (not on PATH) so the
# full Figure.to_png path runs here rather than skipping.
Expand All @@ -419,8 +422,17 @@ jobs:
# defect: fail rather than skip, so the browser layer cannot pass by
# absence. (A crash or non-zero exit already fails unconditionally.)
export XY_REQUIRE_BROWSER=1
export XY_BROWSER_EVIDENCE="$PWD/browser-evidence"
.venv/bin/pytest -q

- name: Upload browser evidence
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: browser-evidence
if-no-files-found: warn
path: browser-evidence/

browser_smokes:
name: Browser rendering + integration
needs: [changes, build]
Expand Down Expand Up @@ -1086,7 +1098,12 @@ jobs:
XY_REQUIRE_CARGO: "1"
run: |
uv venv smoke-native
uv pip install --no-cache -p smoke-native dist/*.tar.gz numpy anywidget "reflex>=0.9.6"
# The adapter needs Reflex's channel transport, unreleased today, so
# there is no version floor to name here — and these smokes only
# `import reflex_xy` (which pulls no Reflex), so installing the
# framework at all would be theatre. Add `[reflex]` back once
# channels ship and the extra names a real floor again.
uv pip install --no-cache -p smoke-native dist/*.tar.gz numpy anywidget
./smoke-native/bin/python - <<'PY'
import importlib.metadata as metadata

Expand All @@ -1107,7 +1124,7 @@ jobs:
XY_SKIP_CARGO: "1"
run: |
uv venv smoke-no-rust
uv pip install --no-cache -p smoke-no-rust dist/*.tar.gz numpy anywidget "reflex>=0.9.6"
uv pip install --no-cache -p smoke-no-rust dist/*.tar.gz numpy anywidget
./smoke-no-rust/bin/python - <<'PY'
import importlib.metadata as metadata

Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,7 @@ node_modules/
python/xy/static/index.js
python/xy/static/standalone.js
**/assets/external/

# Browser evidence kept by the Reflex channel test when XY_BROWSER_EVIDENCE is
# set (CI uploads it as an artifact); local runs default to pytest's tmp_path.
/browser-evidence/
9 changes: 5 additions & 4 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,11 @@ control.
`tests/pyplot/corpus/` + `spec/matplotlib/compat.md`.
- `python/reflex_xy/` — the bundled Reflex integration (import namespace
`reflex_xy`; design: `spec/design/reflex-integration.md`). Chart
data rides the app's own websocket as a second socket.io namespace;
figures live in a per-process registry rebuilt from Reflex state on miss.
The source ships in every `xy` artifact; the `xy[reflex]` extra selects the
supported Reflex floor while plain `xy` keeps no Reflex runtime dependency.
data rides the app's own websocket as a dedicated Reflex channel (`/_xy`,
`data_plane.py`); figures live in a per-process registry rebuilt from Reflex
state on miss. The source ships in every `xy` artifact; the `xy[reflex]`
extra selects the supported Reflex while plain `xy` keeps no Reflex runtime
dependency.
The core `python/xy` package must never import Reflex. The render client is
linked out of that package at app compile (no second copy to drift).
Tests: `tests/reflex_adapter/` (skip unless Reflex is installed).
Expand Down
14 changes: 10 additions & 4 deletions docs/app/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,19 @@ name = "xy-docs-app"
version = "0.1.0"
description = "Documentation site for XY."
requires-python = ">=3.11"
# TEMPORARY: these four normally track reflex-dev/reflex@main, but `xy[reflex]`
# requires the unreleased channel transport (reflex-dev/reflex#6932) and uv
# refuses two URLs for one package. They therefore pin the same immutable
# commit the root pyproject does — all from one repo, so the framework is never
# half fork and half main, and no install can pick up unreviewed framework
# code. Restore `@main` when channels land there.
dependencies = [
"numpy",
"pillow>=13.0.0",
"reflex @ git+https://github.com/reflex-dev/reflex@main",
"reflex-components-internal @ git+https://github.com/reflex-dev/reflex@main#subdirectory=packages/reflex-components-internal",
"reflex-docgen @ git+https://github.com/reflex-dev/reflex@main#subdirectory=packages/reflex-docgen",
"reflex-site-shared @ git+https://github.com/reflex-dev/reflex@main#subdirectory=packages/reflex-site-shared",
"reflex @ git+https://github.com/benedikt-bartscher/reflex.git@7ff416484825edd118ef4182ffcd29583f8e2103",
"reflex-components-internal @ git+https://github.com/benedikt-bartscher/reflex.git@7ff416484825edd118ef4182ffcd29583f8e2103#subdirectory=packages/reflex-components-internal",
"reflex-docgen @ git+https://github.com/benedikt-bartscher/reflex.git@7ff416484825edd118ef4182ffcd29583f8e2103#subdirectory=packages/reflex-docgen",
"reflex-site-shared @ git+https://github.com/benedikt-bartscher/reflex.git@7ff416484825edd118ef4182ffcd29583f8e2103#subdirectory=packages/reflex-site-shared",
"xy[reflex]",
]

Expand Down
Loading
Loading