@tsrx/ripple@0.1.52
Ripple-TS/ripple@tsrx/ripple@0.1.52Jul 28, 2026by github-actions[bot]
AI Summary
Fixes critical rendering bugs related to template elements, fragments, and expression merging, alongside a comprehensive type system cleanup.
Key Highlights
- Fixes template element lowering in expression and attribute positions
- Fixes fragment rendering to avoid extra DOM nodes
- Merges provably-primitive expressions into text runs
New Features
- Fixed template element lowering in expression containers
- Fixed fragment rendering to eliminate extra DOM nodes
- Improved expression merging for text runs
Full Release Notes
### Patch Changes
- [#1386](https://github.com/Ripple-TS/ripple/pull/1386)
[`6025176`](https://github.com/Ripple-TS/ripple/commit/6025176000cafa50d924add8e9a878fe37c0c22b)
Thanks [@leonidaz](https://github.com/leonidaz)! - fix(transform): lower
template elements in expression-container and attribute-value positions
An element inside a child expression container (`<div>{<h1>…</h1>}</div>`) or an
attribute value (`prop={<h1>…</h1>}`) now lowers to a `tsrx_element` value in
both client and server output — matching what the same element assigned to a
variable produces. Previously the client leaked raw JSX into the compiled output
(broken at runtime) and both modes crashed the printer when the element
contained control-flow directives. Ternary and directive-valued attributes on
the server are fixed by the same change.
Expression children are now classified by provable type: an expression that
provably evaluates to a text primitive (string, number, boolean, bigint,
null/undefined — literals, operators, `String()`/`Number()`/`Boolean()`, `as`
casts, typed bindings and members) keeps the inline text fast paths, and
everything else renders through the value-aware expression paths — so an element
passed as a prop and rendered via `{props.header}` produces its markup instead
of `[object Object]`. `<title>` expression children always use the escaping text
path, keeping hydration markers out of `document.title`.
Also fixes a latent client codegen crash: a text expression following inlined
text in the same template text run (e.g. `<div>label: {String(f())}</div>`)
anchored past the end of the coalesced text node; such expressions now render
through a comment-anchored `_$_.expression`.
- [#1386](https://github.com/Ripple-TS/ripple/pull/1386)
[`6025176`](https://github.com/Ripple-TS/ripple/commit/6025176000cafa50d924add8e9a878fe37c0c22b)
Thanks [@leonidaz](https://github.com/leonidaz)! - fix: render fragment children
inline with zero extra DOM
An authored `<>…</>` in children position previously compiled to a comment
anchor plus a runtime `tsrx_element` expression on the client while the server
inlined its content bare — an extra comment node and render unit per fragment,
and a client/server DOM shape mismatch that broke hydration of fragment
children. Template fragments in children position now flatten during child
normalization: their children render inline in the parent template (text runs
merge across the former fragment boundary), adding no DOM nodes at all.
Code-block chain fragments, generated value wrappers, and component root render
fragments keep their existing lowering; the to_ts view keeps authored fragments
verbatim. `<head>` extraction and value-position classification look through
flattened fragments.
- [#1386](https://github.com/Ripple-TS/ripple/pull/1386)
[`6025176`](https://github.com/Ripple-TS/ripple/commit/6025176000cafa50d924add8e9a878fe37c0c22b)
Thanks [@leonidaz](https://github.com/leonidaz)! - fix: merge provably-primitive
call-containing expressions into text runs
Adjacent text and expression children previously refused to merge whenever the
expression contained a call, leaving shapes like
`<div>label: {String(f())}</div>` split into a text run plus a separate anchor —
which crashed client rendering (the text anchor coalesced with the preceding
template text) and could not hydrate against the server's inlined output. An
expression that provably evaluates to a text primitive now merges into the run,
so both targets render one shared text node. Merged operands are nullish-guarded
(`String(v ?? '')`) so nullish values contribute nothing, except provably-string
operands and non-nullish primitive literals, which concatenate bare.
- [#1390](https://github.com/Ripple-TS/ripple/pull/1390)
[`9ffd4ba`](https://github.com/Ripple-TS/ripple/commit/9ffd4ba3e5982acb79a02efe0379abdc14c092a1)
Thanks [@leonidaz](https://github.com/leonidaz)! - Replace every `any` in
`@tsrx/core` with the real AST, CSS, parser and runtime types, move all
remaining `@typedef` blocks into the package's `types/` declarations, and
typecheck `packages/tsrx/tests` alongside `src` and `types`.
Public type declarations gained accuracy along the way: `TSModuleDeclaration.id`
accepts a string literal, `TSModuleBlock.body` allows imports and exports,
`AnalysisResult` declares its `module` field,
`ImportDeclaration`/`ImportExpression` declare their legacy
`assertions`/`arguments` slots, `Program` declares `tsrx_keyword_tokens`, and
`zimmerframe`'s `walk` plus esrap's `print`/`tsx` are generic over their state
instead of `any`. New builders (`ts_qualified_name`, `ts_import_equals`,
`assignment_prop`) and shared helpers (`node_children`, `is_style_element`)
replace hand-built nodes and duplicated predicates.
The published runtime declarations keep their reach: `normalize_spread_props`,
`normalize_spread_props_for_ref_attr` and `exclude_prop_from_object` accept any
object — an interface- or class-typed props bag included — rather than only an
index-signature type, and `exclude_prop_from_object` now returns `Omit<T, K>` so
the surviving props stay readable. `create_ref_prop` and `apply_ref_value` now
resolve their node type through a `RefTarget` overload that mirrors the
runtime's own resolution order, so a ref to an element carrying a `value`
property (`input`, `button`, `select`, `textarea`, `option`, `li`, `progress`,
`meter`, `output`, `data`) resolves to the element instead of to `string`.
Type-level tests pin the inferred types of every published ref and language
helper, so a signature change that degrades editor completion fails a test.
- Updated dependencies
[[`6404d3c`](https://github.com/Ripple-TS/ripple/commit/6404d3cc679fde2eb83ec85c9cd98b653f3f2fed),
[`6025176`](https://github.com/Ripple-TS/ripple/commit/6025176000cafa50d924add8e9a878fe37c0c22b),
[`7ad580e`](https://github.com/Ripple-TS/ripple/commit/7ad580efd24b338b4774add06afdcdd8876c954c),
[`6eaa2f3`](https://github.com/Ripple-TS/ripple/commit/6eaa2f3e6cd18973d57df06eae770313dd061a1a),
[`9ffd4ba`](https://github.com/Ripple-TS/ripple/commit/9ffd4ba3e5982acb79a02efe0379abdc14c092a1)]:
- @tsrx/core@0.1.51