Chirp 0.8.1
A third signal binding helper (signal_attrs), signal emit/derived deduplication, a reactive Lucky Cat showcase wave (auth + Markets IA), and a batch of framework auth/streaming and contract fixes.
Focus: round out thesignal()reactive primitive shipped in 0.8.0 and prove
it end to end in the flagship example.
This is a patch release on top of 0.8.0. It adds the third signal binding helper, makes coalescing signals skip redundant work, and lands a large Lucky Cat showcase wave (an authentication walkthrough and a four-destination Markets information architecture) that exercises the reactive and auth subsystems against a realistic app. It also fixes a batch of framework auth/streaming papercuts and tightens two startup contracts. No breaking changes.
Highlights
signal_attrs() — bind a signal on an element you already have
A third binding helper alongsidesignal() / signal_block(). It emits the
binding attributes only (sse-swap="name" hx-target="this") for placement
inside an existing element:
<section class="board" {{ signal_attrs('market_stats') }}>
{{ stat_strip_body(stats) }}
</section>
A layout's own CSS-grid / flex container (or a <ul>) becomes a live sink without
an injected wrapper<span>/<div>breaking its layout. Unlike a hand-written
sse-swap, the signal_attrs('x')call is recorded for topic scoping and
recognized by thesignal_dead_bindingcontract by its call-site — so the binding
is validated even though thesse-swapattribute is produced at render time.
Signals skip redundant emits
A coalescing signal (coalesce=True, the default) now skips the wire event and
the derived cascade when its new value equals the current one — a purerender
maps equal values to equal payloads, so the swap would be byte-identical. Derived
signals dedup the same way: an unchanged projection no longer re-emits or
propagates. This makes the compute-once / broadcast-many dashboard pattern cheap.
Append-style / drop-sensitive topics opt out withcoalesce=False.
Lucky Cat — reactive + authenticated showcase
The flagship ChirpUI example grew into a full demonstration of the auth subsystem
(three gating levels: full-page@login_required, current_user()component
chrome, and action-route backstops) and a four-destination Markets information
architecture (Home lobby, Favorites, Trending, Research) backed by a shared query
seam. The lobby is fully reactive off a single source signal plus derived
projections, and the example's inline docs were rewritten for newcomers. See the
examples/chirpui/lucky_cat README and DESIGN.md.
Also in this release
- Framework auth / streaming fixes — assorted correctness fixes across the auth flows and streaming context preservation (the example no longer needs to manually re-capture auth/CSRF across streamed responses).
- DX —
AppConfig.from_env()now accepts keyword overrides applied after env loading (no moredataclasses.replace(...)), andapp.check()dead-template detection scans route-handler modules forFragment(...)/Template(...)string literals and module-level*.htmlconstants, so Python-referenced templates are no longer false-positive orphans. - Contracts — signal dead-binding checks now validate hand-written
sse-swapon pages composed under asignal_connect()layout (with an INFO nudge to prefersignal_attrs()), while pages that open their ownsse_scope()stream are excluded. - chirp-ui floor bumped to
>=0.10.0across theuiextra, dev group, and thechirp newscaffold.
See the full changelog for the complete list.
Dependencies
No dependency floor changes from 0.8.0 (bengal-pounce>=0.8.0, kida-templates,
anyio). The ui extra now pins chirp-ui>=0.10.0.
Upgrading
pip install --upgrade bengal-chirp
0.8.1 is a drop-in upgrade from 0.8.0 — no code changes required.