Skip to content

feat(ssr): graduate SSR toward Stable — directive parity, production hydration, resumable boundaries (#127–#130) - #151

Merged
JosunLP merged 2 commits into
devfrom
feat/ssr-stable-127-130
Jun 27, 2026
Merged

feat(ssr): graduate SSR toward Stable — directive parity, production hydration, resumable boundaries (#127–#130)#151
JosunLP merged 2 commits into
devfrom
feat/ssr-stable-127-130

Conversation

@JosunLP

@JosunLP JosunLP commented Jun 27, 2026

Copy link
Copy Markdown
Collaborator

Collected implementation of all four open ssr tickets, on one branch, targeting dev.

Closes #128 · Closes #129 · Closes #130 · Advances #127 (tracking)

What & why

ssr is the last foundational module marked Experimental. This PR resolves the three substantive prerequisites for promotion and publishes the stability contract.

#128 — Interactive directive parity (bq-model / bq-on)

  • RenderOptions.directives: 'full' | 'static' (default 'static' — byte-for-byte backwards compatible).
    • 'full' renders bq-model initial state (value / checked / selected <option> / <textarea> body) and emits a data-bq-on hydration marker for bq-on:*. Handlers are never executed on the server; inline on* attrs / javascript: URLs are still stripped.
  • RenderOptions.onUnsupportedDirective: 'warn' | 'throw' | 'ignore' (default 'ignore') — formalizes the "static-render subset" into an explicit, enforced, documented boundary (option b of the ticket) while parity (option a) is delivered via 'full'.
  • New shared src/ssr/directive-support.ts keeps the pure (DOM-free) and DOM backends in lock-step; options also flow through renderToStringAsync / renderToStream / renderToStreamSuspense / renderToResponse.

#130 — Guaranteed hydration correctness

  • hydrate(selector, context, { onMismatch, onError }) — boundary-scoped recovery: warn (dev default) · repair (rewrite the boundary from client state) · error (route to onError, else throw before mounting).
  • detectHydrationMismatches(root, context) — content-level diff over bq-text / bq-show / bq-bind:* / bq-model plus the structural data-bq-h signature, using the CSP-safe evaluator. Skips expressions whose root identifier is absent from the context, so bq-for loop variables never false-positive.

#129 — True resumability model (resume, not replay)

  • createResumableBoundary / createResumableGraph (server) serialize signals (values), handlers (ids only — no code), and store slices.
  • resume() (client) seeds existing signals, wires handlers by id from a caller-supplied registry (no eval), and rehydrates store slices in place — pairs with island hydration. Opt-in, tree-shakeable, prototype-pollution-filtered, <script>-escaped.

#127 — Stability (tracking)

  • SSR guide gains a Stability section: exit-criteria checklist (3/3 prerequisites resolved here; the freeze-for-one-minor item remains open by definition), frozen surface list, and a per-runtime support matrix. introduction.md notes the 1.15.0 target. Public exports are now frozen for the cycle.

New public API

Runtime: hydrate, detectHydrationMismatches, createResumableBoundary, createResumableGraph, resume, SSR_ON_MARKER_ATTR, RESUMABLE_BOUNDARY_ATTR, RESUMABLE_HANDLER_ATTR, RESUMABLE_EVENT_ATTR — all re-exported from src/full.ts and documented in docs/guide/ssr.md.

Verification

  • bun test2743 pass / 0 fail (incl. new tests/ssr-stable.test.ts, both backends).
  • bun run test:types + bun run lint:types (tsc src + tests) — clean.
  • bunx eslint . — clean.
  • bun run build — succeeds; check:full-bundle in sync; ssr doc-export coverage 54/54 (100%).
  • Cross-runtime smoke (tests/cross-runtime/run.mjs) extended for 'full' mode + resumable boundaries — 13/13 on Node 24 & Bun.

Compatibility

Defaults preserve prior output exactly (no value/checked/data-bq-on, no warnings). All additions are optional. No version bump (release handled separately).

🤖 Generated with Claude Code

…hydration, resumable boundaries (#127 #128 #129 #130)

Collected work to move the `ssr` module out of Experimental.

#128 — Interactive directive parity (`bq-model` / `bq-on`):
- New `RenderOptions.directives: 'full' | 'static'` (default `'static'`, fully
  backwards compatible). `'full'` server-renders `bq-model` (value/checked/
  selected option/textarea body) and emits a `data-bq-on` hydration marker for
  `bq-on:*` (handlers are never executed server-side).
- New `RenderOptions.onUnsupportedDirective: 'warn' | 'throw' | 'ignore'`
  (default `'ignore'`) enforces an explicit, documented SSR directive boundary.
- Shared `directive-support.ts` keeps the pure (DOM-free) and DOM backends in
  lock-step; options flow through async/stream/suspense/response paths too.

#130 — Production hydration correctness:
- `hydrate(selector, context, { onMismatch, onError })` with boundary-scoped
  `warn` | `repair` | `error` recovery.
- `detectHydrationMismatches()` does a content-level diff (text/show/bind/model
  + structural signature) using the CSP-safe evaluator, skipping unresolved
  `bq-for` loop variables to avoid false positives.

#129 — Resumable boundaries (resume, not replay):
- `createResumableBoundary` / `createResumableGraph` (server) serialize signals,
  handler ids, and store slices; `resume()` (client) seeds existing signals,
  wires handlers by id (no eval), and rehydrates stores in place.
- Opt-in, tree-shakeable, prototype-pollution-filtered, `<script>`-escaped.

#127 — Stability docs: SSR guide gains a Stability section (exit criteria,
frozen surface, per-runtime support matrix); introduction notes the 1.15.0
target.

Tests: tests/ssr-stable.test.ts (both backends) + cross-runtime smoke coverage.
All suites, tsc (src + tests), eslint, build, and cross-runtime (Node/Bun) pass.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
@coderabbitai

coderabbitai Bot commented Jun 27, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: fe5ea4d3-2a3f-4078-9c5f-7935d75461e9

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/ssr-stable-127-130

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added docs Changes to the documentation tests Chenges to the tests ssr Changes to the ssr module labels Jun 27, 2026
@JosunLP JosunLP self-assigned this Jun 27, 2026
JosunLP added a commit that referenced this pull request Jun 27, 2026
)

## Problem
The **Greetings** workflow fails on every first-time issue/PR:

```
Error: Input required and not supplied: issue_message
##[warning]Unexpected input(s) 'repo-token', 'issue-message', 'pr-message',
valid inputs are ['issue_message', 'pr_message', 'repo_token']
```

`actions/first-interaction@v3` renamed its inputs to snake_case, but
`.github/workflows/greetings.yml` still passes the old kebab-case names
(`repo-token`, `issue-message`, `pr-message`). The action reads them as
missing and aborts before posting the greeting.

## Fix
Rename the three inputs to the v3 names: `repo_token`, `issue_message`,
`pr_message`. Message content is unchanged.

Surfaced by the Greetings run on #151.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.8 <[email protected]>
@JosunLP
JosunLP merged commit e659ca1 into dev Jun 27, 2026
9 checks passed
@JosunLP
JosunLP deleted the feat/ssr-stable-127-130 branch June 27, 2026 22:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs Changes to the documentation ssr Changes to the ssr module tests Chenges to the tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant