Releases: fsecada01/component-framework
v0.4.1-beta
What's Fixed in 0.4.1-beta
HTMX Form-Encoded Request Support (#15)
FastAPI and Litestar adapters now accept both application/json and application/x-www-form-urlencoded requests. Previously, HTMX's default form-encoded POSTs caused 400 Bad Request errors.
- Both adapters detect
content-typeand parse accordingly - JSON string values in form fields (
payload,params,state) are auto-parsed - Matches the existing Django adapter behavior
- Added
python-multipartto[fastapi]extras (required by Starlette for form parsing)
CI Fix
- Suppressed
tyinvalid-method-overridewarnings for intentional Django CBV/Channels Liskov violations - Applied
ruff formatto SSE test files
Docs
- Added Litestar setup guide (
docs/site-pages/litestar-guide.html) - Replaced JS
EventSourcesnippet with HTMX SSE extension markup - Updated all site page navigation to include Litestar Guide
- Updated version badges and framework references across docs
Install: pip install "component-framework[fastapi,litestar,django]==0.4.1b0"
Full Changelog: v0.4.0b0...v0.4.1b0
v0.4.0-beta
What's New in 0.4.0-beta
Litestar Adapter (#6)
First-class Litestar adapter with the same ergonomics as FastAPI and Django:
component_endpoint+create_component_routes()for HTTPLitestarWebSocketConnection+ WebSocket endpoint[litestar]optional extras group:pip install "component-framework[litestar]"- Example app in
examples/litestar_example.py
Async Event Handlers (#10)
async def on_* handlers are now properly awaited:
Component.async_dispatch()— async entry point for async adaptersComponent.async_handle_event()— awaits coroutine handlers, works with sync too- FastAPI, Litestar, and WebSocket adapters updated to use
async_dispatch - Sync
handle_event()now raisesComponentErrorif the handler is async (fail-fast instead of silently dropping the coroutine)
SSE Streaming (#12)
StreamingComponent subclass for long-running operations that emit intermediate renders via Server-Sent Events:
class RagQueryComponent(StreamingComponent):
async def on_analyze(self, query: str):
async for step in rag_service.stream(query):
self.state["step"] = step
yield # emit intermediate SSE frame
self.state["done"] = TruePOST /components/{name}/streamendpoint for FastAPI and Litestar- Each
yieldtriggers a render and emitsdata: {"html": ..., "state": ...} - Non-generator handlers gracefully produce a single frame
State Size Guard (#14)
StateSerializer.serialize() now checks serialised state size:
- Warning at 64 KB (configurable via
StateSerializer.warn_bytes) - Hard error at 512 KB (configurable via
StateSerializer.max_bytes) - Both thresholds can be disabled by setting to
0
Bug Fix: JS Double-Serialisation (#11)
Fixed component-client.js double-stringifying the payload field. Added server-side guards in FastAPI and Litestar adapters for backward compatibility with cached older JS.
Install: pip install "component-framework[fastapi,litestar,django]==0.4.0b0"
Full Changelog: v0.3.1b0...v0.4.0b0
v0.3.1b0 — Registry idempotency, static file namespacing
What's new in 0.3.1
Patch release fixing two bugs surfaced by real-world Django integration (closes #8, #9).
Fix: registry idempotency (#8)
registry.register() previously raised ValueError any time the same component name was seen a second time — including during Django test discovery, where the test runner adds multiple paths to sys.path and the same module file ends up imported under two different dotted names (e.g. core.components.counter and backend.core.components.counter).
registry.register() now accepts re-registration of the same class under the same name as a silent no-op. Genuine conflicts — a different class trying to claim an already-registered name — still raise ValueError with a clearer message.
Before (workaround required):
# Had to abandon the decorator API entirely
class Counter(Component):
...
if registry.get("counter") is None:
registry.register("counter")(Counter)After (clean decorator API works again):
@registry.register("counter")
class Counter(Component):
...Fix: static file namespacing (#9)
component-client.js was shipped at static/js/component-client.js inside the package. Django's AppDirectoriesFinder strips the static/ prefix, so collectstatic placed the file at js/component-client.js in STATIC_ROOT — a bare path that collides with any other app shipping files into js/ and does not match the documented {% static 'component_framework/js/component-client.js' %} tag.
The file is now at static/component_framework/js/component-client.js, following the Django app static file namespacing convention. collectstatic now produces component_framework/js/component-client.js.
Update your base template if you used the workaround path:
<!-- Before (workaround) -->
<script src="{% static 'js/component-client.js' %}"></script>
<!-- After (correct, documented path) -->
<script src="{% static 'component_framework/js/component-client.js' %}"></script>Upgrading
pip install "component-framework==0.3.1b0"
# or via uv:
uv add "component-framework==0.3.1b0"Full changelog: v0.3.0b0...v0.3.1b0
v0.3.0b0 — Optional extras, docs overhaul
What's new in 0.3.0
Breaking change — optional extras
FastAPI, Uvicorn, and JinjaX are no longer installed by default. Django-only projects no longer pull in the FastAPI stack as a dependency.
Before (0.2.x):
pip install component-frameworkAfter (0.3.0+):
# Django only (default)
pip install component-framework
# FastAPI + JinjaX
pip install "component-framework[fastapi]"
# Everything
pip install "component-framework[all]"Docs site
A full API reference site is now published via GitHub Pages, built with pdoc and a custom dark-themed template. Includes worked examples for e-commerce, admin panels, customer support, LMS, and financial dashboards.
Changes since 0.2.0-beta
Features
feat(deps): Make FastAPI/Uvicorn/JinjaX optional extras — Django projects install a significantly smaller dependency footprint (#7)
Fixes
fix(ci): Use full install for test job soconftest.pyDjango imports resolve correctlyfix(tests): Restore original adapter modules after_reload_adapterin test teardown to prevent state leakage between testsfix(docs): Correct JS URL detection, root index links, and lint errors in docs pipelinefix(docs): Bridge nav-dropdown hover gap with::afterpseudo-element to prevent menu flicker
Docs
- Ratify project constitution v1.0.0 and propagate to speckit templates
- Overhaul pdoc template: full dark theme, fixed version bar, highlight.js colour palette
- Add Terminal Modern UI, home page, e-commerce example, and site-pages pipeline
- Add admin panel, customer support, LMS, and financial dashboard examples
- Update version references and install commands throughout
Full changelog: 0.2.0-beta...v0.3.0b0