Commit 2c4c98e
committed
feat(core): SSR property bindings via data-webjs-prop-* side-channel
A property hole (.prop=${val}) on any element used to be dropped
silently at SSR. The data was lost between page function and
child component, breaking the natural "fetch data, pass to
component" pattern unless authors manually JSON.stringify into
an attribute.
This commit makes property bindings round-trip through SSR.
Server-side emit. The renderer encodes each property hole via
the wire serializer (handles Array, Object, Date, Map, Set,
BigInt, cycles via @webjskit/core/serialize) and emits as
data-webjs-prop-<kebab>="<encoded>" on the element. Event
holes (@click) still drop because they are client-only by
design; boolean holes (?disabled) keep their existing behaviour.
Server-side consume. The component walker reads data-webjs-prop-*
attributes, decodes them via the wire format, and sets them on
the instance with priority over the string-typed attribute path.
Render() now sees the original JS reference, not a coerced
string. Async work inside render still works (Promise values
are awaited before serialization at the hole site).
Unserializable values (functions, class instances with private
state, DOM nodes) drop with a single-line console warning
instead of crashing the SSR pass. Same constraint as Next.js
Server Components.
Updated the existing 'drops properties on server' test to assert
the new behaviour: the attribute is present and contains the
serialized value.1 parent c686452 commit 2c4c98e
2 files changed
Lines changed: 77 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| 8 | + | |
8 | 9 | | |
9 | 10 | | |
10 | 11 | | |
| |||
195 | 196 | | |
196 | 197 | | |
197 | 198 | | |
198 | | - | |
| 199 | + | |
| 200 | + | |
199 | 201 | | |
200 | 202 | | |
201 | 203 | | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
202 | 226 | | |
203 | 227 | | |
204 | 228 | | |
| |||
256 | 280 | | |
257 | 281 | | |
258 | 282 | | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
259 | 289 | | |
| 290 | + | |
260 | 291 | | |
261 | 292 | | |
262 | 293 | | |
| |||
643 | 674 | | |
644 | 675 | | |
645 | 676 | | |
| 677 | + | |
| 678 | + | |
| 679 | + | |
| 680 | + | |
| 681 | + | |
| 682 | + | |
| 683 | + | |
| 684 | + | |
| 685 | + | |
| 686 | + | |
| 687 | + | |
| 688 | + | |
| 689 | + | |
| 690 | + | |
| 691 | + | |
| 692 | + | |
| 693 | + | |
| 694 | + | |
| 695 | + | |
| 696 | + | |
| 697 | + | |
| 698 | + | |
| 699 | + | |
| 700 | + | |
| 701 | + | |
| 702 | + | |
| 703 | + | |
| 704 | + | |
| 705 | + | |
| 706 | + | |
| 707 | + | |
| 708 | + | |
| 709 | + | |
| 710 | + | |
| 711 | + | |
| 712 | + | |
| 713 | + | |
| 714 | + | |
| 715 | + | |
646 | 716 | | |
647 | 717 | | |
648 | 718 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
26 | 26 | | |
27 | 27 | | |
28 | 28 | | |
29 | | - | |
30 | | - | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
31 | 35 | | |
32 | 36 | | |
33 | 37 | | |
| |||
0 commit comments