You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- Streaming actions: async generator handlers push incremental updates
over WebSocket (skeleton→content, progress, AI-style text, modals/drawers)
- beam-cloak: hide elements until reactivity initializes (prevents flash)
- Auto-reconnect: indefinite retry with stepped backoff (1s, 3s, 5s+)
configurable via <meta name="beam-reconnect-interval">
- beam-disconnected: show element while WebSocket is disconnected
- Upgrade capnweb to 0.6.1 for native ReadableStream support
- beam-init: support expressions on child elements (not just beam-state root)
- Fix Hono generic type constraint in beam.init() (Hono<E extends HonoEnv>)
- README: document streaming, beam-cloak, auto-reconnect
-**Cloak** - Hide elements until reactivity initializes (no flash of unprocessed content)
37
+
-**Auto-Reconnect** - Automatically reconnects on WebSocket disconnect with configurable interval
36
38
-**Multi-Render** - Update multiple targets in a single action response
37
39
-**Async Components** - Full support for HonoX async components in `ctx.render()`
40
+
-**Streaming Actions** - Async generator handlers push incremental updates over WebSocket (skeleton → content, live progress, AI-style text)
38
41
39
42
## Installation
40
43
@@ -361,6 +364,105 @@ Async components are awaited automatically - no manual `Promise.resolve()` or he
361
364
362
365
---
363
366
367
+
### Streaming Actions
368
+
369
+
Turn any action into a streaming action by making it an **async generator** (`async function*`). Each `yield` pushes an update to the browser immediately — no waiting for the full response.
370
+
371
+
```tsx
372
+
exportasyncfunction* loadProfile(ctx:BeamContext<Env>, { id }:Record<string, unknown>) {
373
+
// First yield: show skeleton immediately
374
+
yieldctx.render(<divid="profile">Loading…</div>)
375
+
376
+
// Simulate slow API call
377
+
awaitdelay(1800)
378
+
379
+
const user =awaitdb.getUser(idasstring)
380
+
381
+
// Second yield: replace with real content
382
+
yieldctx.render(
383
+
<divid="profile">
384
+
<h3>{user.name}</h3>
385
+
<p>{user.role}</p>
386
+
</div>
387
+
)
388
+
}
389
+
```
390
+
391
+
Use it in HTML exactly like a regular action — no special attribute needed:
**Streaming into Modals and Drawers** — yield `ctx.modal()` or `ctx.drawer()` calls. The first yield opens the overlay; subsequent yields update its content:
442
+
443
+
```tsx
444
+
exportasyncfunction* openProfileModal(ctx:BeamContext<Env>, { id }:Record<string, unknown>) {
Toggle element visibility based on form field values (no server round-trip):
@@ -1506,6 +1669,29 @@ Fine-grained reactivity for UI components like carousels, tabs, accordions, and
1506
1669
1507
1670
**Note:**`beam-init` only works inside a `beam-state` scope — it has no effect on elements without a state ancestor.
1508
1671
1672
+
#### beam-cloak — Prevent Flash of Unprocessed Content
1673
+
1674
+
`beam-cloak` hides an element until its reactive scope has fully initialized. Without it, elements with `beam-show` may briefly appear before Beam processes them.
1675
+
1676
+
Add it to the same element as `beam-state`. Beam removes the attribute automatically after setup.
1677
+
1678
+
```html
1679
+
<!-- Without beam-cloak: the "Dropdown" content may flash visible on load -->
1680
+
<!-- With beam-cloak: hidden until reactivity is ready, then shown correctly -->
1681
+
<divbeam-state="open: false"beam-cloak>
1682
+
<buttonbeam-state-toggle="open">Toggle</button>
1683
+
<divbeam-show="open">Dropdown content</div>
1684
+
</div>
1685
+
```
1686
+
1687
+
Beam ships a CSS rule that does the hiding:
1688
+
1689
+
```css
1690
+
[beam-cloak] { display: none!important; }
1691
+
```
1692
+
1693
+
This rule is included in `@benqoder/beam/styles`. If you are not importing the beam stylesheet, add it yourself.
1694
+
1509
1695
#### Named State (Cross-Component)
1510
1696
1511
1697
Share state between different parts of the page. Named states (with `beam-id`) persist across server-driven updates:
0 commit comments