|
1 | 1 | # Changelog |
2 | 2 |
|
| 3 | +## 0.17.0 - 2026-07-08 |
| 4 | + |
| 5 | +- Memoized boundary-element lookup in the loader: `loader.swap(...)` resolved |
| 6 | + its boundary id by walking the entire document on every swap (visible as a |
| 7 | + full-document traversal per History selection); the element is now cached |
| 8 | + weakly per id and re-resolved only when it leaves the document or loses its |
| 9 | + boundary id. |
| 10 | +- Activation now scans a scope with a single tree traversal: pseudo-event |
| 11 | + dispatch (attach/visible/intersect) reuses the shared element collection |
| 12 | + instead of a second walk. Component-mounted children keep their own nested |
| 13 | + scan. |
| 14 | +- The Vite plugin excludes the framework entrypoints from |
| 15 | + `optimizeDeps` (opt out with `optimizeFrameworkDeps: true`): the published |
| 16 | + entrypoints are flat ESM bundles, and Vite's prebundle cache does not watch |
| 17 | + `file:`/`link:` dependency contents — local framework rebuilds were served |
| 18 | + stale until `node_modules/.vite` was deleted by hand. |
| 19 | +- Navigation failures from intercepted links, forms, and history events are |
| 20 | + now logged with `console.error` (they have no caller to reject to), and |
| 21 | + unmatched navigation without `fallback: "document"` logs a `console.warn` |
| 22 | + with guidance — previously both failed silently. |
| 23 | +- Added a commit stall watchdog: `loader._whenCommitted(...)` warns |
| 24 | + (`commitStallWarningMs`, default 2000ms, `0`/`false` disables) when a |
| 25 | + boundary commit has not settled, naming the await-inside-`scheduler.batch` |
| 26 | + deadlock composition so it is diagnosable instead of a silent freeze. |
| 27 | +- `router.prefetch(...)` on `server: true` routes now caches the fetched |
| 28 | + envelope briefly (`prefetchTtlMs` option, default 5000ms); the next |
| 29 | + navigation with a matching URL and boundary consumes it single-use instead |
| 30 | + of refetching. |
| 31 | +- Added `tests/performance/`: deterministic hot-path performance contracts |
| 32 | + (activation scan traversal counts, attribute-config memoization, swap |
| 33 | + rescan scoping, scheduler/signal write coalescing, single frame wait per |
| 34 | + commit batch, router fast-path work counts) plus a hot-path registry |
| 35 | + (`tests/performance/hot-paths.json`). A coverage guardrail keeps the |
| 36 | + registry, the `// @hot-paths:` headers in contract tests, and the |
| 37 | + `test.performance` pipeline task inputs in sync, so changes to a registered |
| 38 | + hot-path source automatically re-run the suite. The swap-rescan contracts |
| 39 | + caught the boundary-lookup walk fixed above. |
| 40 | +- Categorized the test tree into suites — `tests/unit/`, `tests/runtime/`, |
| 41 | + `tests/router/`, `tests/server/`, `tests/timing/`, `tests/performance/`, |
| 42 | + `tests/build/`, and `tests/examples/` — with matching `test:<suite>` |
| 43 | + scripts (see `tests/README.md`). Added a dedicated `tests/timing/` suite covering |
| 44 | + rendering and `requestAnimationFrame` gotchas under explicit frame-timed |
| 45 | + schedulers: suspended-frame fallbacks, exactly-once frame/fallback races, |
| 46 | + FIFO commit ordering, commits scheduled inside open batches, loader swaps |
| 47 | + with rebinding and ordering, handler-initiated swaps, signal/swap |
| 48 | + coalescing, and router navigation (local partials, server partials with |
| 49 | + sub-boundaries, suspended frames, popstate). |
| 50 | +- Bundle size from bundled TypeScript source: `browser.ts` raw 261,577 B (261.6 KB / 0.262 MB), gzip 50,018 B (50.0 KB / 0.050 MB), br 41,211 B (41.2 KB / 0.041 MB) -> `browser.min.js` raw 108,975 B (109.0 KB / 0.109 MB), gzip 32,004 B (32.0 KB / 0.032 MB), br 28,111 B (28.1 KB / 0.028 MB); delta raw -152,602 B (-152.6 KB / -0.153 MB), gzip -18,014 B (-18.0 KB / -0.018 MB), br -13,100 B (-13.1 KB / -0.013 MB). |
| 51 | + |
3 | 52 | ## 0.16.0 - 2026-07-08 |
4 | 53 |
|
5 | 54 | - Added server route partials: `defineRoute({ server: true })` makes CSR/SPA |
|
54 | 103 | in hidden tabs, which froze boundary commits — and anything awaiting them, |
55 | 104 | including router navigation — until the tab became visible again. Visible |
56 | 105 | tabs stay frame-aligned; hidden tabs fall back to timer cadence. |
57 | | -- Memoized boundary-element lookup in the loader: `loader.swap(...)` resolved |
58 | | - its boundary id by walking the entire document on every swap (visible as a |
59 | | - full-document traversal per History selection); the element is now cached |
60 | | - weakly per id and re-resolved only when it leaves the document or loses its |
61 | | - boundary id. |
62 | | -- Activation now scans a scope with a single tree traversal: pseudo-event |
63 | | - dispatch (attach/visible/intersect) reuses the shared element collection |
64 | | - instead of a second walk. Component-mounted children keep their own nested |
65 | | - scan. |
66 | | -- The Vite plugin excludes the framework entrypoints from |
67 | | - `optimizeDeps` (opt out with `optimizeFrameworkDeps: true`): the published |
68 | | - entrypoints are flat ESM bundles, and Vite's prebundle cache does not watch |
69 | | - `file:`/`link:` dependency contents — local framework rebuilds were served |
70 | | - stale until `node_modules/.vite` was deleted by hand. |
71 | | -- Navigation failures from intercepted links, forms, and history events are |
72 | | - now logged with `console.error` (they have no caller to reject to), and |
73 | | - unmatched navigation without `fallback: "document"` logs a `console.warn` |
74 | | - with guidance — previously both failed silently. |
75 | | -- Added a commit stall watchdog: `loader._whenCommitted(...)` warns |
76 | | - (`commitStallWarningMs`, default 2000ms, `0`/`false` disables) when a |
77 | | - boundary commit has not settled, naming the await-inside-`scheduler.batch` |
78 | | - deadlock composition so it is diagnosable instead of a silent freeze. |
79 | | -- `router.prefetch(...)` on `server: true` routes now caches the fetched |
80 | | - envelope briefly (`prefetchTtlMs` option, default 5000ms); the next |
81 | | - navigation with a matching URL and boundary consumes it single-use instead |
82 | | - of refetching. |
83 | | -- Added `tests/performance/`: deterministic hot-path performance contracts |
84 | | - (activation scan traversal counts, attribute-config memoization, swap |
85 | | - rescan scoping, scheduler/signal write coalescing, single frame wait per |
86 | | - commit batch, router fast-path work counts) plus a hot-path registry |
87 | | - (`tests/performance/hot-paths.json`). A coverage guardrail keeps the |
88 | | - registry, the `// @hot-paths:` headers in contract tests, and the |
89 | | - `test.performance` pipeline task inputs in sync, so changes to a registered |
90 | | - hot-path source automatically re-run the suite. The swap-rescan contracts |
91 | | - caught the boundary-lookup walk fixed above. |
92 | | -- Categorized the test tree into suites — `tests/unit/`, `tests/runtime/`, |
93 | | - `tests/router/`, `tests/server/`, `tests/timing/`, `tests/performance/`, |
94 | | - `tests/build/`, and `tests/examples/` — with matching `test:<suite>` |
95 | | - scripts (see `tests/README.md`). Added a dedicated `tests/timing/` suite covering |
96 | | - rendering and `requestAnimationFrame` gotchas under explicit frame-timed |
97 | | - schedulers: suspended-frame fallbacks, exactly-once frame/fallback races, |
98 | | - FIFO commit ordering, commits scheduled inside open batches, loader swaps |
99 | | - with rebinding and ordering, handler-initiated swaps, signal/swap |
100 | | - coalescing, and router navigation (local partials, server partials with |
101 | | - sub-boundaries, suspended frames, popstate). |
102 | | -- Bundle size from bundled TypeScript source: `browser.ts` raw 261,577 B (261.6 KB / 0.262 MB), gzip 50,018 B (50.0 KB / 0.050 MB), br 41,211 B (41.2 KB / 0.041 MB) -> `browser.min.js` raw 108,975 B (109.0 KB / 0.109 MB), gzip 32,004 B (32.0 KB / 0.032 MB), br 28,111 B (28.1 KB / 0.028 MB); delta raw -152,602 B (-152.6 KB / -0.153 MB), gzip -18,014 B (-18.0 KB / -0.018 MB), br -13,100 B (-13.1 KB / -0.013 MB). |
| 106 | +- Bundle size from bundled TypeScript source: `browser.ts` raw 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.js` raw 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). |
103 | 107 |
|
104 | 108 | ## 0.15.3 - 2026-07-06 |
105 | 109 |
|
|
0 commit comments