v0.16.0
Release notes from CHANGELOG.md for @async/framework@0.16.0 (2026-07-08).
- Added server route partials:
defineRoute({ server: true })makes CSR/SPA
navigation fetch the target URL withAccept: application/x-async-partial
(plus anx-async-boundaryrequest header naming the boundary the
transition plan wants filled) and apply the returned wire server envelope
({ __async_server_result__: 1, html, signals, cache, boundary, redirect, title }) through the existing navigation pipeline. HTTP redirects followed
by the fetch update router state, the route snapshot, and browser history to
the final URL.createRouter(...)accepts afetchoption to override the
window fetch (tests, custom transports); ambientglobalThis.fetchis never
used.prefetch(...)returns the fetched envelope without applying it. - Added a router
fallbackoption ("error"default,"document"): with
fallback: "document", unmatched navigation in client modes performs native
document navigation instead of dead-ending inrouter.error, enabling
incremental SPA adoption over server-rendered apps. Assigning the current
browser URL is refused to prevent reload loops. Server-partial responses
that are not envelopes (or fail) also fall back to document navigation in
this mode. - Added
render: "document"route definitions: matched routes can force
native document navigation (downloads, raw endpoints) while staying
registered. - Added multi-segment splat patterns:
/:org/:name/tree/*restcaptures the
remaining segments (decoded per segment) asparams.rest. Splat segments
must terminate the pattern and rank above*wildcard routes and below
single-segment params. - Added master-detail navigation:
viewKeymay now be a function of the route
match, and routes may declaresubBoundary. A same-view navigation (same
computedviewKey) on a route withsubBoundaryrenders/fetches into that
nested boundary instead of going state-only, so query-driven detail panes
(e.g.?commit=<sha>) swap without touching the surrounding view. Route
snapshots keep comparing view identity on the route-level boundary. - Partial results with a string
titlenow updatedocument.title, and
client navigations that swapped content scroll to the top (or to the URL
hash target) unless the router is created withscroll: false. Async.start(...)now forwardsurlMode,fallback, andscrollto the
runtime router and accepts arouterOptionsobject for the remaining
createRouter(...)options.- Server runtime
render(url, { document: false })returns the raw route
fragment without the boundary section or snapshot script, for building
server route partial envelopes whose swap target is an already-activated
document. - Fixed a navigation deadlock in CSR/SPA modes with frame-timed commits (real
browsers):applyNavigationResultawaited boundary commit completion inside
scheduler.batch(...), where automatic flushes are suppressed, so route
swaps could stall indefinitely and never updatedocument.title, history,
orrouter.pending. Commit awaits now happen outside the batch. Node test
environments commit synchronously, which is why the suite never caught it;
new regression tests force frame timing. - Frame-timed commits now race the animation frame against a timeout
(frameFallbackMs, default 50ms): browsers suspendrequestAnimationFrame
in hidden tabs, which froze boundary commits — and anything awaiting them,
including router navigation — until the tab became visible again. Visible
tabs stay frame-aligned; hidden tabs fall back to timer cadence. - Bundle size from bundled TypeScript source:
browser.tsraw 259,693 B (259.7 KB / 0.260 MB), gzip 49,336 B (49.3 KB / 0.049 MB), br 40,621 B (40.6 KB / 0.041 MB) ->browser.min.jsraw 108,501 B (108.5 KB / 0.109 MB), gzip 31,770 B (31.8 KB / 0.032 MB), br 27,913 B (27.9 KB / 0.028 MB); delta raw -151,192 B (-151.2 KB / -0.151 MB), gzip -17,566 B (-17.6 KB / -0.018 MB), br -12,708 B (-12.7 KB / -0.013 MB).
Release evidence
- Release type: stable
- Package profile: framework-browser
- npm pack files: 61
| File | Raw | Gzip | Brotli |
|---|---|---|---|
browser.d.ts |
42.8 KB | 7.8 KB | 6.9 KB |
browser.js |
253.5 KB | 48.5 KB | 39.7 KB |
browser.min.js |
106.0 KB | 31.1 KB | 27.3 KB |
browser.ts |
253.6 KB | 48.5 KB | 39.7 KB |
browser.umd.js |
269.3 KB | 49.6 KB | 40.2 KB |
browser.umd.min.js |
107.5 KB | 31.2 KB | 27.3 KB |
framework.d.ts |
47.0 KB | 8.6 KB | 7.6 KB |
framework.ts |
403.7 KB | 76.6 KB | 60.9 KB |
server.js |
403.6 KB | 76.5 KB | 60.9 KB |
Diff links:
- browser.d.ts: https://github.com/async/framework/compare/HEAD%5E...v0.16.0?diff=unified#diff-browser.d.ts
- browser.js: https://github.com/async/framework/compare/HEAD%5E...v0.16.0?diff=unified#diff-browser.js
- browser.ts: https://github.com/async/framework/compare/HEAD%5E...v0.16.0?diff=unified#diff-browser.ts
- browser.umd.js: https://github.com/async/framework/compare/HEAD%5E...v0.16.0?diff=unified#diff-browser.umd.js
- framework.d.ts: https://github.com/async/framework/compare/HEAD%5E...v0.16.0?diff=unified#diff-framework.d.ts
- framework.ts: https://github.com/async/framework/compare/HEAD%5E...v0.16.0?diff=unified#diff-framework.ts
- server.js: https://github.com/async/framework/compare/HEAD%5E...v0.16.0?diff=unified#diff-server.js
Source: CHANGELOG.md in tag v0.16.0.