@rshono/core 1.0.0-rc.16 → 1.0.0-rc.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -293,7 +293,11 @@ Every target streams, which is the bar a new one has to clear.
293
293
  round trip that Next.js and TanStack Start have usually already paid.
294
294
  - No incremental static regeneration: `render: 'static'` is decided at build time, and a static page changes
295
295
  when you rebuild.
296
- - Scroll restoration is the browser's (`history.scrollRestoration = 'auto'`).
296
+ - **Soft navigation needs the [Navigation API](https://developer.mozilla.org/en-US/docs/Web/API/Navigation_API)**
297
+ — Chrome/Edge 135, Firefox 147, Safari 26.2, [Baseline](https://web.dev/blog/baseline-navigation-api) since
298
+ January 2026. Where it is missing there is no interception at all and every link is a real browser load,
299
+ which a server-rendered app answers correctly; only the soft part is gone. Scroll restoration, the fragment
300
+ jump and the post-navigation focus reset are all the browser's.
297
301
  - The dev proxy doesn't forward WebSocket upgrades to a custom sub-app; production is unaffected.
298
302
  - Dev source maps embed the original source of `'use server'` modules (dev binds 127.0.0.1 only, and
299
303
  production ships no client source maps).
@@ -100,6 +100,184 @@ function showFatal(error, componentStack) {
100
100
  function requestPayload(href, signal) {
101
101
  return createFromFetch(fetch(createRscRequest(new URL(href, location.href).href, undefined, signal)));
102
102
  }
103
+ /**
104
+ * Whether the browser hands us its navigations. Gated on `sourceElement` rather than on `navigation` itself:
105
+ * Chrome shipped the event in 102 and that property only in 135, and without it a `data-native` link cannot
106
+ * be told from any other — so the older window would soft-navigate the very links that asked not to be.
107
+ *
108
+ * Where this is false there is no interception at all and every navigation is a real browser load, which a
109
+ * server-rendered app answers correctly on its own. Only the soft part is missing.
110
+ *
111
+ * Both globals are tested, and neither is touched before: this runs at module scope, where a ReferenceError
112
+ * would take the whole client runtime down with it rather than degrading anything.
113
+ */
114
+ const canSoftNavigate = typeof navigation !== 'undefined' && typeof NavigateEvent !== 'undefined' && 'sourceElement' in NavigateEvent.prototype;
115
+ /**
116
+ * Drops a navigation's result promises. Both reject when a navigation is superseded or cancelled — routine
117
+ * here, since a second click is meant to abandon the first — and unhandled they would be reported as faults.
118
+ */
119
+ function settle(result) {
120
+ const ignore = () => { };
121
+ void result.committed?.catch(ignore);
122
+ void result.finished?.catch(ignore);
123
+ }
124
+ // The imperative actions behind `useNavigation().router`. Each one only *asks*: the browser turns it into a
125
+ // `navigate` event, which is where `listenNavigation` answers it — so a `router.push` and a link click reach
126
+ // the same code by the same route, and inherit the same fetch, scroll and `pending` flag.
127
+ function push(href) {
128
+ if (canSoftNavigate)
129
+ settle(navigation.navigate(href, { history: 'push' }));
130
+ else
131
+ window.location.assign(href);
132
+ }
133
+ function replace(href) {
134
+ if (canSoftNavigate)
135
+ settle(navigation.navigate(href, { history: 'replace' }));
136
+ else
137
+ window.location.replace(href);
138
+ }
139
+ // A traversal is the browser's to perform either way — `navigation` only hands it back as an interceptable
140
+ // event first. Nothing to go back to is a rejection there and a no-op here; both amount to the same thing.
141
+ function back() {
142
+ if (canSoftNavigate)
143
+ settle(navigation.back());
144
+ else
145
+ window.history.back();
146
+ }
147
+ function forward() {
148
+ if (canSoftNavigate)
149
+ settle(navigation.forward());
150
+ else
151
+ window.history.forward();
152
+ }
153
+ // A refresh keeps the URL, and is still a navigation: it arrives as `navigationType: 'reload'`, which is what
154
+ // tells the listener to leave scroll and focus where the user left them.
155
+ function refresh() {
156
+ if (canSoftNavigate)
157
+ settle(navigation.reload());
158
+ else
159
+ window.location.reload();
160
+ }
161
+ /**
162
+ * Turns a control-signal digest — how `redirect()` / `notFound()` reach the browser — into a real
163
+ * navigation. Returns false for anything else, so callers fall through to their own handling.
164
+ *
165
+ * `hard` forces a full document load, for signals that surfaced *through React*: it unmounts the root on
166
+ * an uncaught error, leaving no live tree to soft-navigate with.
167
+ */
168
+ function handleControlDigest(error, { hard = false } = {}) {
169
+ const digest = error?.digest;
170
+ if (!isControlDigest(digest))
171
+ return false;
172
+ const redirect = parseRedirectDigest(digest);
173
+ if (!redirect) {
174
+ window.location.reload();
175
+ }
176
+ else if (hard) {
177
+ window.location.assign(new URL(redirect.location, window.location.href).href);
178
+ }
179
+ else {
180
+ push(redirect.location);
181
+ }
182
+ return true;
183
+ }
184
+ /**
185
+ * Puts a payload on screen, resolving once React has committed it. Replaced by `BrowserRoot`'s own on mount;
186
+ * the default covers the window before hydration, where `setServerCallback` is already registered but there
187
+ * is no root to update — a reload is the honest answer, and nothing after it needs to run.
188
+ */
189
+ let setPayload = () => {
190
+ window.location.reload();
191
+ return new Promise(() => { });
192
+ };
193
+ /** Runs work inside the nav transition so `useNavigation().pending` stays true across the round-trip. */
194
+ let startNav = (run) => {
195
+ void run();
196
+ };
197
+ /**
198
+ * Fetches the payload for `url` and puts it on screen.
199
+ *
200
+ * Resolves once React has **committed** it rather than when the fetch lands: an intercepted navigation
201
+ * scrolls and moves focus when this promise settles, and a `#hash` target does not exist until the new tree
202
+ * does. Rejects only on a genuine failure — being superseded is not one, and resolves quietly, because the
203
+ * navigation that replaced this one owns the screen from then on.
204
+ */
205
+ function loadPayload(url, signal) {
206
+ // Deliberately not awaited inside the transition: the scope ends once the payload is handed to React, and
207
+ // React holds `pending` until the update it scheduled commits. Awaiting the commit *inside* the scope would
208
+ // work too, but only because React happens not to gate a commit on its async scope settling — an internal
209
+ // this has no reason to depend on across the whole `^19.1.0` peer range.
210
+ let committed;
211
+ const run = async () => {
212
+ const payload = await requestPayload(url, signal);
213
+ // The browser aborts a navigation the moment a newer one starts. Checked again after the await because
214
+ // the fetch may already have resolved by then, and applying it would repaint a page the user has left.
215
+ if (signal?.aborted)
216
+ return;
217
+ if (payload.redirect) {
218
+ push(payload.redirect);
219
+ return;
220
+ }
221
+ committed = setPayload(payload);
222
+ };
223
+ // `startTransition` runs the work but hands nothing back, so the promise carrying a failure is caught here
224
+ // instead. Assigned synchronously: React invokes the callback before `startNav` returns.
225
+ let work;
226
+ startNav(() => (work = run()));
227
+ return work.then(
228
+ // Undefined whenever nothing was applied — an abort, or a redirect — and there is then nothing to wait for.
229
+ () => committed, (error) => {
230
+ // Checked before the error is read: an abort is this navigation being replaced, and the one that
231
+ // replaced it owns the outcome.
232
+ if (signal?.aborted || handleControlDigest(error))
233
+ return;
234
+ throw error;
235
+ });
236
+ }
237
+ /**
238
+ * Navigations the browser can hand over but shouldn't:
239
+ *
240
+ * - a fragment jump, which is same-document already and needs no payload — the browser's own jump is the one
241
+ * that honours `scroll-padding-top`, and re-rendering would pull the target out from under it;
242
+ * - a download, which is not a navigation of this page at all;
243
+ * - a `POST` form, which is a submission and the server's to answer (a `GET` form carries its fields in the
244
+ * URL, has no `formData`, and soft-navigates like any other link);
245
+ * - a link marked `data-native`, the documented opt-out.
246
+ */
247
+ function leaveToBrowser(event) {
248
+ return event.hashChange || event.downloadRequest !== null || event.formData !== null || event.sourceElement?.hasAttribute('data-native') === true;
249
+ }
250
+ /**
251
+ * The whole router, in one listener.
252
+ *
253
+ * Every navigation the page can make arrives as a `navigate` event — a link click, a `GET` form, a
254
+ * `history.pushState`, the back button, `navigation.reload()` — already filtered by the browser: it does not
255
+ * fire for a middle-click, a modified click or a new tab, and reports `canIntercept: false` for anything
256
+ * cross-origin, or for a traversal that leaves the app. Those need no handling here; they are left alone, and
257
+ * the browser performs them as it always would.
258
+ */
259
+ function listenNavigation() {
260
+ if (!canSoftNavigate)
261
+ return () => { };
262
+ const onNavigate = (event) => {
263
+ if (!event.canIntercept || leaveToBrowser(event))
264
+ return;
265
+ // A push or a traversal lands on a new page, so the browser resets the scroll offset — or restores the
266
+ // one it remembers — and moves focus, which is what makes a soft navigation announce itself to a screen
267
+ // reader. A replace or a refresh stays where it is, so neither should move. Both wait on the handler,
268
+ // which is the point of resolving it at commit rather than at fetch.
269
+ const inPlace = event.navigationType === 'replace' || event.navigationType === 'reload';
270
+ event.intercept({
271
+ scroll: inPlace ? 'manual' : 'after-transition',
272
+ focusReset: inPlace ? 'manual' : 'after-transition',
273
+ // The URL commits before the handler runs, so a failure leaves the address bar describing a page the
274
+ // document is not showing. A real load is the only way back to agreement.
275
+ handler: () => loadPayload(event.destination.url, event.signal).catch(() => window.location.reload()),
276
+ });
277
+ };
278
+ navigation.addEventListener('navigate', onNavigate);
279
+ return () => navigation.removeEventListener('navigate', onNavigate);
280
+ }
103
281
  async function main() {
104
282
  // The assertion is load-bearing under the compiler that builds this: TypeScript 7 declares `nonce` on
105
283
  // HTMLElement, 6 declares it on Element. ESLint runs the older lib — where the narrowing is redundant —
@@ -108,149 +286,32 @@ async function main() {
108
286
  const cspMeta = document.querySelector('meta[property="csp-nonce"]');
109
287
  if (cspMeta?.nonce)
110
288
  __webpack_nonce__ = cspMeta.nonce;
111
- // Both are replaced by BrowserRoot's own on mount. The defaults cover the window before hydration, where
112
- // `setServerCallback` is already registered but there is no root to update — a reload is the honest answer.
113
- let setPayload = () => {
114
- window.location.reload();
115
- };
116
- // Runs work inside the nav transition so useNavigation().pending stays true across the round-trip.
117
- let startNav = (run) => {
118
- void run();
119
- };
120
289
  const initialPayload = await createFromReadableStream(flightStream);
121
- function push(href) {
122
- const target = new URL(href, window.location.href);
123
- if (target.origin !== window.location.origin) {
124
- window.location.assign(target.href);
125
- return;
126
- }
127
- window.history.pushState(null, '', target.href);
128
- }
129
- function replace(href) {
130
- const target = new URL(href, window.location.href);
131
- if (target.origin !== window.location.origin) {
132
- window.location.replace(target.href);
133
- return;
134
- }
135
- window.history.replaceState(null, '', target.href);
136
- }
137
- // A traversal is the browser's to perform: it moves the entry itself and fires `popstate`, which is where
138
- // `listenNavigation` picks the new document up — so these need no more than to ask, and inherit the same
139
- // fetch, scroll restoration and `pending` flag a back-button press already got.
140
- const back = () => window.history.back();
141
- const forward = () => window.history.forward();
142
- // A refresh keeps the URL, so it can't ride the history patch like push/replace and drives the re-fetch itself.
143
- const refresh = () => startNav(async () => {
144
- try {
145
- await fetchRscPayload();
146
- }
147
- catch {
148
- window.location.reload();
149
- }
150
- });
151
- /**
152
- * Turns a control-signal digest — how `redirect()` / `notFound()` reach the browser — into a real
153
- * navigation. Returns false for anything else, so callers fall through to their own handling.
154
- *
155
- * `hard` forces a full document load, for signals that surfaced *through React*: it unmounts the root on
156
- * an uncaught error, leaving no live tree to soft-navigate with.
157
- */
158
- function handleControlDigest(error, { hard = false } = {}) {
159
- const digest = error?.digest;
160
- if (!isControlDigest(digest))
161
- return false;
162
- const redirect = parseRedirectDigest(digest);
163
- if (!redirect) {
164
- window.location.reload();
165
- }
166
- else if (hard) {
167
- window.location.assign(new URL(redirect.location, window.location.href).href);
168
- }
169
- else {
170
- push(redirect.location);
171
- }
172
- return true;
173
- }
174
- /**
175
- * The navigation whose payload the screen is allowed to show. React runs async transitions concurrently, so
176
- * two overlapping navigations are two live fetches with no ordering between them — without this, a slow
177
- * first response landing after a fast second one renders the page the user already left while the address
178
- * bar shows the one they asked for.
179
- */
180
- let currentNavigation = 0;
181
- /** The in-flight navigation's fetch, so a newer one can stop paying for it. */
182
- let navigationFetch = null;
183
- /**
184
- * Fetches the payload for the current URL and applies it, unless a newer navigation started meanwhile.
185
- *
186
- * @returns `true` when this navigation is the one that settled the screen, `false` when it was superseded.
187
- * The distinction is what keeps a stale response from scrolling a page it is no longer rendering — and
188
- * why being superseded resolves rather than throws: both callers answer a rejection with a full reload,
189
- * so surfacing the abort would turn every fast second click into one.
190
- */
191
- async function fetchRscPayload() {
192
- const navigation = ++currentNavigation;
193
- navigationFetch?.abort();
194
- const controller = (navigationFetch = new AbortController());
195
- const superseded = () => navigation !== currentNavigation;
196
- let payload;
197
- try {
198
- payload = await requestPayload(window.location.href, controller.signal);
199
- }
200
- catch (error) {
201
- // Checked before the error is read: an abort is this navigation being replaced, and the one that
202
- // replaced it owns the outcome.
203
- if (superseded())
204
- return false;
205
- if (handleControlDigest(error))
206
- return true;
207
- throw error;
208
- }
209
- if (superseded())
210
- return false;
211
- if (payload.redirect) {
212
- push(payload.redirect);
213
- return true;
214
- }
215
- setPayload(payload);
216
- return true;
217
- }
218
290
  function BrowserRoot() {
219
291
  const [payload, setPayloadState] = React.useState(initialPayload);
220
292
  const [pending, startTransition] = React.useTransition();
221
- // The scroll a fetched navigation still owes, held until its payload is on screen.
222
- const pendingScroll = React.useRef(null);
293
+ // The resolver the payload on screen still owes see {@link loadPayload}.
294
+ const pendingCommit = React.useRef(null);
223
295
  React.useEffect(() => {
224
- setPayload = (v) => setPayloadState(v);
296
+ setPayload = (next) => new Promise((resolve) => {
297
+ // A payload replaced before it ever painted still has a navigation waiting on it. React commits
298
+ // only the newest, so the effect below never runs for the one it skipped: release it here.
299
+ pendingCommit.current?.();
300
+ pendingCommit.current = resolve;
301
+ setPayloadState(next);
302
+ });
225
303
  startNav = (run) => startTransition(run);
226
304
  }, [startTransition]);
227
305
  /**
228
- * Scrolls where the navigation asked, once React has put its payload in the DOM a `#hash` target does
229
- * not exist until the new tree does. A layout effect, so the pre-scroll position is never painted.
306
+ * Releases the navigation waiting on this payload, which is what lets the browser scroll and move focus
307
+ * now that their target exists. A layout effect, so the pre-scroll position is never painted.
230
308
  */
231
309
  React.useLayoutEffect(() => {
232
- const scroll = pendingScroll.current;
233
- pendingScroll.current = null;
234
- scroll?.();
310
+ const commit = pendingCommit.current;
311
+ pendingCommit.current = null;
312
+ commit?.();
235
313
  }, [payload]);
236
- React.useEffect(() => {
237
- const stopNavigating = listenNavigation((afterRender) => startNav(async () => {
238
- try {
239
- // Only the navigation that settled the screen owes a scroll — a superseded one would move the
240
- // page the navigation that replaced it is about to render.
241
- if (await fetchRscPayload())
242
- pendingScroll.current = afterRender;
243
- }
244
- catch {
245
- window.location.reload();
246
- }
247
- }));
248
- const stopUpgradingLinks = listenLinks();
249
- return () => {
250
- stopUpgradingLinks();
251
- stopNavigating();
252
- };
253
- }, []);
314
+ React.useEffect(() => listenNavigation(), []);
254
315
  const router = React.useMemo(() => ({ push, replace, back, forward, refresh, pending }), [pending]);
255
316
  return _jsx(RouterContext.Provider, { value: router, children: payload.root });
256
317
  }
@@ -279,7 +340,7 @@ async function main() {
279
340
  return undefined;
280
341
  }
281
342
  if (documentUrl() === calledFrom)
282
- React.startTransition(() => setPayload(payload));
343
+ React.startTransition(() => void setPayload(payload));
283
344
  if (payload.notFound)
284
345
  return undefined;
285
346
  const result = payload.returnValue;
@@ -309,144 +370,8 @@ async function main() {
309
370
  },
310
371
  });
311
372
  if (import.meta.webpackHot) {
312
- initDevRefresh(fetchRscPayload);
313
- }
314
- }
315
- /** Runs teardown in reverse and empties the list, so a second call is a no-op. */
316
- function disposeAll(undo) {
317
- for (const dispose of undo.splice(0).reverse())
318
- dispose();
319
- }
320
- // An `<a>` we intercept for soft navigation: same-origin, same tab, not a download,
321
- // and not explicitly opted out with `data-native` (which forces a full browser navigation).
322
- function isRouterLink(link) {
323
- return (!!link.href &&
324
- (!link.target || link.target === '_self') &&
325
- link.origin === location.origin &&
326
- !link.hasAttribute('download') &&
327
- !link.hasAttribute('data-native'));
328
- }
329
- /**
330
- * Upgrades the app's anchors: a plain left-click becomes a soft navigation. It shares no state with
331
- * `listenNavigation` — a click only calls `history.pushState`, which is where that picks the navigation up.
332
- */
333
- function listenLinks() {
334
- const undo = [];
335
- function onClick(e) {
336
- const link = e.target.closest('a');
337
- if (link &&
338
- link instanceof HTMLAnchorElement &&
339
- isRouterLink(link) &&
340
- e.button === 0 &&
341
- !e.metaKey &&
342
- !e.ctrlKey &&
343
- !e.altKey &&
344
- !e.shiftKey &&
345
- !e.defaultPrevented) {
346
- if (link.hash && link.pathname === location.pathname && link.search === location.search)
347
- return;
348
- e.preventDefault();
349
- history.pushState(null, '', link.href);
350
- }
351
- }
352
- document.addEventListener('click', onClick);
353
- undo.push(() => document.removeEventListener('click', onClick));
354
- return () => disposeAll(undo);
355
- }
356
- /**
357
- * The element the current `#fragment` names, if it is on the page. A fragment is percent-encoded and an `id`
358
- * is not, so it is decoded first — and taken literally when a hand-written `%` makes that throw.
359
- */
360
- function fragmentTarget() {
361
- const fragment = location.hash.slice(1);
362
- if (!fragment)
363
- return null;
364
- let id = fragment;
365
- try {
366
- id = decodeURIComponent(fragment);
367
- }
368
- catch {
369
- // Malformed escape — the literal fragment is the better guess at the id than nothing.
370
- }
371
- return document.getElementById(id);
372
- }
373
- function listenNavigation(onNavigation) {
374
- const undo = [];
375
- // Set explicitly as a statement of intent: the browser remembers a traversal's offset, and nothing here
376
- // tracks one.
377
- const prevRestoration = window.history.scrollRestoration;
378
- try {
379
- window.history.scrollRestoration = 'auto';
380
- }
381
- catch {
382
- // Not settable in every browser, and only a preference — the navigation still works without it.
373
+ initDevRefresh();
383
374
  }
384
- undo.push(() => {
385
- try {
386
- window.history.scrollRestoration = prevRestoration;
387
- }
388
- catch {
389
- // As above: if it could not be set, it cannot be put back either.
390
- }
391
- });
392
- /**
393
- * A push is not a real navigation to the browser, so nothing resets the scroll offset. A `#hash` names
394
- * where to land instead; `replace` keeps its position, and a traversal is the browser's to restore.
395
- *
396
- * `scrollIntoView` is the algorithm a browser's own fragment jump uses, so `scroll-padding-top` still
397
- * applies. Neither call passes a `behavior`, leaving `scroll-behavior: smooth` the app's to ask for.
398
- */
399
- const afterRenderFor = (type) => () => {
400
- if (type !== 'push')
401
- return;
402
- const target = fragmentTarget();
403
- if (target)
404
- target.scrollIntoView();
405
- else
406
- window.scrollTo(0, 0);
407
- };
408
- // What the payload on screen was rendered for. See {@link documentUrl}.
409
- let renderedUrl = documentUrl();
410
- /**
411
- * A navigation that moves only the fragment leaves the document unchanged, so the payload on screen is
412
- * already the right one — fetching another would re-render the page out from under the jump.
413
- * `router.refresh()` is unaffected, and remains the way to ask for fresh data at an unchanged URL.
414
- */
415
- const notify = (type) => {
416
- const afterRender = afterRenderFor(type);
417
- if (documentUrl() === renderedUrl) {
418
- afterRender();
419
- return;
420
- }
421
- renderedUrl = documentUrl();
422
- onNavigation(afterRender);
423
- };
424
- const onPopState = () => notify('pop');
425
- window.addEventListener('popstate', onPopState);
426
- undo.push(() => window.removeEventListener('popstate', onPopState));
427
- // Saved unbound on purpose, and called back with `.call(this, …)` below — patching `history` is the only
428
- // way to see a navigation the app makes itself, and the receiver is restored at every call site.
429
- // eslint-disable-next-line @typescript-eslint/unbound-method
430
- const oldPushState = window.history.pushState;
431
- window.history.pushState = function (state, unused, url) {
432
- const res = oldPushState.call(this, state, unused, url);
433
- notify('push');
434
- return res;
435
- };
436
- undo.push(() => {
437
- window.history.pushState = oldPushState;
438
- });
439
- // eslint-disable-next-line @typescript-eslint/unbound-method -- as with `pushState` above.
440
- const oldReplaceState = window.history.replaceState;
441
- window.history.replaceState = function (state, unused, url) {
442
- const res = oldReplaceState.call(this, state, unused, url);
443
- notify('replace');
444
- return res;
445
- };
446
- undo.push(() => {
447
- window.history.replaceState = oldReplaceState;
448
- });
449
- return () => disposeAll(undo);
450
375
  }
451
376
  /**
452
377
  * Dev-only refresh client, listening to the CLI's SSE endpoint:
@@ -455,9 +380,7 @@ function listenNavigation(onNavigation) {
455
380
  * rsc-update → server component code changed: re-fetch the flight payload, state preserved.
456
381
  * hello → sent on (re)connect with the latest build hash; a mismatch means a missed event.
457
382
  */
458
- // `Promise<unknown>`: the payload fetch reports whether its navigation was superseded, which matters to a
459
- // click and not to a rebuild — here only settling or rejecting does.
460
- function initDevRefresh(fetchRscPayload) {
383
+ function initDevRefresh() {
461
384
  const hot = import.meta.webpackHot;
462
385
  let connectedOnce = false;
463
386
  /** The newest build the dev server has announced — what {@link applyClientUpdate} walks towards. */
@@ -477,7 +400,7 @@ function initDevRefresh(fetchRscPayload) {
477
400
  targetHash = message.hash ?? targetHash;
478
401
  if (connectedOnce) {
479
402
  await applyClientUpdate();
480
- await fetchRscPayload().catch(() => window.location.reload());
403
+ await loadPayload(window.location.href).catch(() => window.location.reload());
481
404
  }
482
405
  connectedOnce = true;
483
406
  break;
@@ -487,7 +410,7 @@ function initDevRefresh(fetchRscPayload) {
487
410
  break;
488
411
  case 'rsc-update':
489
412
  console.log('[rshono] server components updated');
490
- await fetchRscPayload().catch(() => window.location.reload());
413
+ await loadPayload(window.location.href).catch(() => window.location.reload());
491
414
  break;
492
415
  }
493
416
  }
@@ -1 +1 @@
1
- {"version":3,"file":"entry.client.js","sourceRoot":"","sources":["../../src/runtime/entry.client.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react';\nimport { hydrateRoot } from 'react-dom/client';\nimport {\n createFromFetch,\n createFromReadableStream,\n createTemporaryReferenceSet,\n encodeReply,\n setServerCallback,\n} from 'react-server-dom-rspack/client.browser';\nimport { isControlDigest, parseRedirectDigest } from './control.js';\nimport type { DevMessage } from './dev-protocol.js';\nimport type { RscPayload } from './entry.rsc.js';\n// Dev-only: its one caller sits behind `import.meta.webpackHot`, which a production build compiles to\n// `false` — so this module is dropped there.\nimport { walkHotUpdates } from './hot-update.js';\nimport { RouterContext, type NavigationRouter } from './navigation.js';\nimport { createRscRequest } from './request.js';\n\nconst isDev = process.env.NODE_ENV === 'development';\n\ndeclare global {\n /** The array the payload `<script>` tags `flight-inject.ts` emits push their chunks into. */\n var __FLIGHT_DATA: Array<string | Uint8Array> | undefined;\n}\n\n/** The flight payload the document carried, read back out of `__FLIGHT_DATA` — see `flight-inject.ts`. */\nfunction readFlightPayload(): ReadableStream<Uint8Array> {\n const encoder = new TextEncoder();\n // Assigned synchronously by `start`, which `new ReadableStream` runs before it returns.\n let controller!: ReadableStreamDefaultController<Uint8Array>;\n const stream = new ReadableStream<Uint8Array>({\n start: (c) => void (controller = c),\n });\n const enqueue = (chunk: string | Uint8Array) => controller.enqueue(typeof chunk === 'string' ? encoder.encode(chunk) : chunk);\n\n // Payload scripts interleave with the document: the ones that already ran are in the array, the rest\n // arrive through `push`.\n const data = (self.__FLIGHT_DATA ??= []);\n for (const chunk of data) enqueue(chunk);\n data.push = enqueue as typeof data.push;\n\n // The last payload script lands before parsing finishes, so that is what closes the stream.\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', () => controller.close(), { once: true });\n } else {\n controller.close();\n }\n return stream;\n}\n\n/** Created at module evaluation, not inside `main()`, so no chunk can be pushed before it is watching. */\nconst flightStream = readFlightPayload();\n\n/**\n * The part of the location a payload is rendered for — the document, without the fragment, which the server\n * never sees. Two URLs that differ only by `#hash` describe the same payload.\n */\nconst documentUrl = (): string => location.pathname + location.search;\n\n/** Guarantees somewhere to attach the fatal overlay: the root container is `document`, so a teardown can take `<body>` with it. */\nfunction overlayHost(): HTMLElement {\n if (!document.documentElement) document.appendChild(document.createElement('html'));\n if (!document.body) document.documentElement.appendChild(document.createElement('body'));\n return document.body;\n}\n\n/**\n * Paints the reason for an uncaught render error over the blank page it leaves behind — the full stack in\n * dev, a generic notice and a reload button in production.\n *\n * DOM calls rather than React (the renderer is what just failed), and `textContent` rather than\n * `innerHTML` (an error message is untrusted input).\n */\nfunction showFatal(error: unknown, componentStack?: string | null): void {\n // Queued: React's teardown runs after this callback returns and would remove a node appended inline.\n setTimeout(() => {\n const host = overlayHost();\n host.querySelector('[data-rshono-fatal]')?.remove();\n\n const box = document.createElement('div');\n box.setAttribute('data-rshono-fatal', '');\n box.setAttribute('role', 'alert');\n box.style.cssText =\n 'position:fixed;inset:0;z-index:2147483647;overflow:auto;padding:1.5rem;background:#18181b;color:#f4f4f5;' +\n 'font:14px/1.6 ui-monospace,SFMono-Regular,Menlo,monospace;text-align:left';\n\n const title = document.createElement('div');\n title.textContent = isDev ? 'Unhandled error' : 'Something went wrong';\n title.style.cssText = 'font-size:1.0625rem;font-weight:700;color:#f87171;margin:0 0 0.75rem';\n box.appendChild(title);\n\n if (isDev) {\n const detail = document.createElement('pre');\n detail.style.cssText = 'margin:0;white-space:pre-wrap;word-break:break-word';\n detail.textContent =\n (error instanceof Error ? (error.stack ?? `${error.name}: ${error.message}`) : String(error)) +\n (componentStack ? `\\n\\nComponent stack:${componentStack}` : '');\n box.appendChild(detail);\n } else {\n const message = document.createElement('p');\n message.textContent = 'This page hit an unexpected error and can’t continue.';\n message.style.cssText = 'margin:0 0 1rem;color:#d4d4d8';\n box.appendChild(message);\n }\n\n const reload = document.createElement('button');\n reload.textContent = 'Reload page';\n reload.style.cssText =\n 'margin-top:1.25rem;padding:0.5rem 1rem;font:inherit;color:#18181b;background:#f4f4f5;border:0;border-radius:4px;cursor:pointer';\n reload.addEventListener('click', () => window.location.reload());\n box.appendChild(reload);\n\n host.appendChild(box);\n }, 0);\n}\n\n/**\n * Asks a URL for its flight payload. Deliberately uncached — a payload can never be staler than the click\n * that wanted it, and the browser's own HTTP cache is what makes a repeat visit cheap.\n */\nfunction requestPayload(href: string, signal: AbortSignal): Promise<RscPayload> {\n return createFromFetch<RscPayload>(fetch(createRscRequest(new URL(href, location.href).href, undefined, signal)));\n}\n\nasync function main() {\n // The assertion is load-bearing under the compiler that builds this: TypeScript 7 declares `nonce` on\n // HTMLElement, 6 declares it on Element. ESLint runs the older lib — where the narrowing is redundant —\n // so it reports an assertion that `tsc` requires. Believe `typecheck`, not the rule.\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n const cspMeta = document.querySelector('meta[property=\"csp-nonce\"]') as HTMLMetaElement | null;\n if (cspMeta?.nonce) __webpack_nonce__ = cspMeta.nonce;\n\n // Both are replaced by BrowserRoot's own on mount. The defaults cover the window before hydration, where\n // `setServerCallback` is already registered but there is no root to update — a reload is the honest answer.\n let setPayload: (v: RscPayload) => void = () => {\n window.location.reload();\n };\n // Runs work inside the nav transition so useNavigation().pending stays true across the round-trip.\n let startNav: (run: () => void | Promise<void>) => void = (run) => {\n void run();\n };\n\n const initialPayload = await createFromReadableStream<RscPayload>(flightStream);\n\n function push(href: string) {\n const target = new URL(href, window.location.href);\n if (target.origin !== window.location.origin) {\n window.location.assign(target.href);\n return;\n }\n window.history.pushState(null, '', target.href);\n }\n\n function replace(href: string) {\n const target = new URL(href, window.location.href);\n if (target.origin !== window.location.origin) {\n window.location.replace(target.href);\n return;\n }\n window.history.replaceState(null, '', target.href);\n }\n\n // A traversal is the browser's to perform: it moves the entry itself and fires `popstate`, which is where\n // `listenNavigation` picks the new document up — so these need no more than to ask, and inherit the same\n // fetch, scroll restoration and `pending` flag a back-button press already got.\n const back = () => window.history.back();\n const forward = () => window.history.forward();\n\n // A refresh keeps the URL, so it can't ride the history patch like push/replace and drives the re-fetch itself.\n const refresh = () =>\n startNav(async () => {\n try {\n await fetchRscPayload();\n } catch {\n window.location.reload();\n }\n });\n\n /**\n * Turns a control-signal digest — how `redirect()` / `notFound()` reach the browser — into a real\n * navigation. Returns false for anything else, so callers fall through to their own handling.\n *\n * `hard` forces a full document load, for signals that surfaced *through React*: it unmounts the root on\n * an uncaught error, leaving no live tree to soft-navigate with.\n */\n function handleControlDigest(error: unknown, { hard = false }: { hard?: boolean } = {}): boolean {\n const digest = (error as { digest?: unknown } | null)?.digest;\n if (!isControlDigest(digest)) return false;\n const redirect = parseRedirectDigest(digest);\n if (!redirect) {\n window.location.reload();\n } else if (hard) {\n window.location.assign(new URL(redirect.location, window.location.href).href);\n } else {\n push(redirect.location);\n }\n return true;\n }\n\n /**\n * The navigation whose payload the screen is allowed to show. React runs async transitions concurrently, so\n * two overlapping navigations are two live fetches with no ordering between them — without this, a slow\n * first response landing after a fast second one renders the page the user already left while the address\n * bar shows the one they asked for.\n */\n let currentNavigation = 0;\n /** The in-flight navigation's fetch, so a newer one can stop paying for it. */\n let navigationFetch: AbortController | null = null;\n\n /**\n * Fetches the payload for the current URL and applies it, unless a newer navigation started meanwhile.\n *\n * @returns `true` when this navigation is the one that settled the screen, `false` when it was superseded.\n * The distinction is what keeps a stale response from scrolling a page it is no longer rendering — and\n * why being superseded resolves rather than throws: both callers answer a rejection with a full reload,\n * so surfacing the abort would turn every fast second click into one.\n */\n async function fetchRscPayload(): Promise<boolean> {\n const navigation = ++currentNavigation;\n navigationFetch?.abort();\n const controller = (navigationFetch = new AbortController());\n const superseded = () => navigation !== currentNavigation;\n\n let payload: RscPayload;\n try {\n payload = await requestPayload(window.location.href, controller.signal);\n } catch (error) {\n // Checked before the error is read: an abort is this navigation being replaced, and the one that\n // replaced it owns the outcome.\n if (superseded()) return false;\n if (handleControlDigest(error)) return true;\n throw error;\n }\n if (superseded()) return false;\n if (payload.redirect) {\n push(payload.redirect);\n return true;\n }\n setPayload(payload);\n return true;\n }\n\n function BrowserRoot() {\n const [payload, setPayloadState] = React.useState(initialPayload);\n const [pending, startTransition] = React.useTransition();\n // The scroll a fetched navigation still owes, held until its payload is on screen.\n const pendingScroll = React.useRef<(() => void) | null>(null);\n\n React.useEffect(() => {\n setPayload = (v) => setPayloadState(v);\n startNav = (run) => startTransition(run);\n }, [startTransition]);\n\n /**\n * Scrolls where the navigation asked, once React has put its payload in the DOM — a `#hash` target does\n * not exist until the new tree does. A layout effect, so the pre-scroll position is never painted.\n */\n React.useLayoutEffect(() => {\n const scroll = pendingScroll.current;\n pendingScroll.current = null;\n scroll?.();\n }, [payload]);\n\n React.useEffect(() => {\n const stopNavigating = listenNavigation((afterRender) =>\n startNav(async () => {\n try {\n // Only the navigation that settled the screen owes a scroll — a superseded one would move the\n // page the navigation that replaced it is about to render.\n if (await fetchRscPayload()) pendingScroll.current = afterRender;\n } catch {\n window.location.reload();\n }\n }),\n );\n const stopUpgradingLinks = listenLinks();\n return () => {\n stopUpgradingLinks();\n stopNavigating();\n };\n }, []);\n\n const router = React.useMemo<NavigationRouter>(() => ({ push, replace, back, forward, refresh, pending }), [pending]);\n\n return <RouterContext.Provider value={router}>{payload.root}</RouterContext.Provider>;\n }\n\n setServerCallback(async (id, args) => {\n const temporaryReferences = createTemporaryReferenceSet();\n // The document the action is being called from. Every action response carries a fresh payload for that\n // page, so if a navigation has moved on by the time it arrives the payload describes a page the user has\n // left — the return value is still theirs, but painting it is not. Compared without the fragment, which\n // the server never saw.\n const calledFrom = documentUrl();\n const request = createRscRequest(window.location.href, {\n id,\n body: await encodeReply(args, { temporaryReferences }),\n });\n let payload: RscPayload;\n try {\n payload = await createFromFetch<RscPayload>(fetch(request), { temporaryReferences });\n } catch (error) {\n if (handleControlDigest(error)) return undefined;\n throw error;\n }\n if (payload.redirect) {\n push(payload.redirect);\n return undefined;\n }\n if (documentUrl() === calledFrom) React.startTransition(() => setPayload(payload));\n if (payload.notFound) return undefined;\n const result = payload.returnValue!;\n if (!result.ok) throw result.error;\n return result.value;\n });\n\n // A `redirect()` / `notFound()` from a component below the page root reaches us through React: it rides the\n // flight payload as an error, and boundaries re-throw it so it lands here rather than in a fallback.\n //\n // Installing these hooks opts out of React's own defaults, so everything that isn't a control signal has to\n // be put back by hand — `reportError` rather than a bare log, so error-reporting tools still see it.\n hydrateRoot(document, <BrowserRoot />, {\n formState: initialPayload.formState,\n onCaughtError: (error, errorInfo) => {\n if (handleControlDigest(error, { hard: true })) return;\n // A boundary handled it and the tree is intact, so no overlay over the app's own fallback.\n console.error(error, errorInfo.componentStack ?? '');\n },\n onUncaughtError: (error, errorInfo) => {\n if (handleControlDigest(error, { hard: true })) return;\n // Nothing caught it, so React tears the root down — and the root is `document`.\n globalThis.reportError(error);\n showFatal(error, errorInfo.componentStack);\n },\n });\n\n if (import.meta.webpackHot) {\n initDevRefresh(fetchRscPayload);\n }\n}\n\ntype NavigationType = 'push' | 'replace' | 'pop';\n\n/** Runs teardown in reverse and empties the list, so a second call is a no-op. */\nfunction disposeAll(undo: Array<() => void>): void {\n for (const dispose of undo.splice(0).reverse()) dispose();\n}\n\n// An `<a>` we intercept for soft navigation: same-origin, same tab, not a download,\n// and not explicitly opted out with `data-native` (which forces a full browser navigation).\nfunction isRouterLink(link: HTMLAnchorElement): boolean {\n return (\n !!link.href &&\n (!link.target || link.target === '_self') &&\n link.origin === location.origin &&\n !link.hasAttribute('download') &&\n !link.hasAttribute('data-native')\n );\n}\n\n/**\n * Upgrades the app's anchors: a plain left-click becomes a soft navigation. It shares no state with\n * `listenNavigation` — a click only calls `history.pushState`, which is where that picks the navigation up.\n */\nfunction listenLinks(): () => void {\n const undo: Array<() => void> = [];\n\n function onClick(e: MouseEvent) {\n const link = (e.target as Element).closest('a');\n if (\n link &&\n link instanceof HTMLAnchorElement &&\n isRouterLink(link) &&\n e.button === 0 &&\n !e.metaKey &&\n !e.ctrlKey &&\n !e.altKey &&\n !e.shiftKey &&\n !e.defaultPrevented\n ) {\n if (link.hash && link.pathname === location.pathname && link.search === location.search) return;\n e.preventDefault();\n history.pushState(null, '', link.href);\n }\n }\n document.addEventListener('click', onClick);\n undo.push(() => document.removeEventListener('click', onClick));\n\n return () => disposeAll(undo);\n}\n\n/**\n * The element the current `#fragment` names, if it is on the page. A fragment is percent-encoded and an `id`\n * is not, so it is decoded first — and taken literally when a hand-written `%` makes that throw.\n */\nfunction fragmentTarget(): HTMLElement | null {\n const fragment = location.hash.slice(1);\n if (!fragment) return null;\n let id = fragment;\n try {\n id = decodeURIComponent(fragment);\n } catch {\n // Malformed escape — the literal fragment is the better guess at the id than nothing.\n }\n return document.getElementById(id);\n}\n\nfunction listenNavigation(onNavigation: (afterRender: () => void) => void): () => void {\n const undo: Array<() => void> = [];\n\n // Set explicitly as a statement of intent: the browser remembers a traversal's offset, and nothing here\n // tracks one.\n const prevRestoration = window.history.scrollRestoration;\n try {\n window.history.scrollRestoration = 'auto';\n } catch {\n // Not settable in every browser, and only a preference — the navigation still works without it.\n }\n undo.push(() => {\n try {\n window.history.scrollRestoration = prevRestoration;\n } catch {\n // As above: if it could not be set, it cannot be put back either.\n }\n });\n\n /**\n * A push is not a real navigation to the browser, so nothing resets the scroll offset. A `#hash` names\n * where to land instead; `replace` keeps its position, and a traversal is the browser's to restore.\n *\n * `scrollIntoView` is the algorithm a browser's own fragment jump uses, so `scroll-padding-top` still\n * applies. Neither call passes a `behavior`, leaving `scroll-behavior: smooth` the app's to ask for.\n */\n const afterRenderFor = (type: NavigationType) => () => {\n if (type !== 'push') return;\n const target = fragmentTarget();\n if (target) target.scrollIntoView();\n else window.scrollTo(0, 0);\n };\n\n // What the payload on screen was rendered for. See {@link documentUrl}.\n let renderedUrl = documentUrl();\n\n /**\n * A navigation that moves only the fragment leaves the document unchanged, so the payload on screen is\n * already the right one — fetching another would re-render the page out from under the jump.\n * `router.refresh()` is unaffected, and remains the way to ask for fresh data at an unchanged URL.\n */\n const notify = (type: NavigationType) => {\n const afterRender = afterRenderFor(type);\n if (documentUrl() === renderedUrl) {\n afterRender();\n return;\n }\n renderedUrl = documentUrl();\n onNavigation(afterRender);\n };\n\n const onPopState = () => notify('pop');\n window.addEventListener('popstate', onPopState);\n undo.push(() => window.removeEventListener('popstate', onPopState));\n\n // Saved unbound on purpose, and called back with `.call(this, …)` below — patching `history` is the only\n // way to see a navigation the app makes itself, and the receiver is restored at every call site.\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const oldPushState = window.history.pushState;\n window.history.pushState = function (state, unused, url) {\n const res = oldPushState.call(this, state, unused, url as string);\n notify('push');\n return res;\n };\n undo.push(() => {\n window.history.pushState = oldPushState;\n });\n\n // eslint-disable-next-line @typescript-eslint/unbound-method -- as with `pushState` above.\n const oldReplaceState = window.history.replaceState;\n window.history.replaceState = function (state, unused, url) {\n const res = oldReplaceState.call(this, state, unused, url as string);\n notify('replace');\n return res;\n };\n undo.push(() => {\n window.history.replaceState = oldReplaceState;\n });\n\n return () => disposeAll(undo);\n}\n\n/**\n * Dev-only refresh client, listening to the CLI's SSE endpoint:\n *\n * client-built → hot-apply the waiting updates; anything the page can't be patched up to reloads.\n * rsc-update → server component code changed: re-fetch the flight payload, state preserved.\n * hello → sent on (re)connect with the latest build hash; a mismatch means a missed event.\n */\n// `Promise<unknown>`: the payload fetch reports whether its navigation was superseded, which matters to a\n// click and not to a rebuild — here only settling or rejecting does.\nfunction initDevRefresh(fetchRscPayload: () => Promise<unknown>) {\n const hot = import.meta.webpackHot!;\n let connectedOnce = false;\n /** The newest build the dev server has announced — what {@link applyClientUpdate} walks towards. */\n let targetHash: string | undefined;\n\n function reload(reason: string, error?: unknown): void {\n console.warn(`[rshono] ${reason} — reloading`, ...(error === undefined ? [] : [error]));\n window.location.reload();\n }\n\n async function applyClientUpdate(): Promise<void> {\n const giveUp = await walkHotUpdates(\n hot,\n () => __webpack_hash__,\n () => targetHash,\n );\n if (giveUp) reload(giveUp.reason, giveUp.error);\n }\n\n async function handle(message: DevMessage): Promise<void> {\n switch (message.type) {\n case 'hello':\n targetHash = message.hash ?? targetHash;\n if (connectedOnce) {\n await applyClientUpdate();\n await fetchRscPayload().catch(() => window.location.reload());\n }\n connectedOnce = true;\n break;\n case 'client-built':\n targetHash = message.hash;\n await applyClientUpdate();\n break;\n case 'rsc-update':\n console.log('[rshono] server components updated');\n await fetchRscPayload().catch(() => window.location.reload());\n break;\n }\n }\n\n const source = new EventSource('/_rshono/hmr');\n // Chained rather than handled as they arrive: `hot.check` may only run from `idle`, and a burst of saves\n // puts several frames on the wire inside the time one takes. Queueing drops nothing, because `targetHash`\n // is shared — whichever handler runs next walks to the newest build.\n let queue: Promise<void> = Promise.resolve();\n source.onmessage = (event: MessageEvent<string>) => {\n const message = JSON.parse(event.data) as DevMessage;\n queue = queue.then(() => handle(message)).catch((error) => reload('the dev client failed', error));\n };\n}\n\n// A bootstrap failure — a truncated initial payload, most likely — would otherwise be an unhandled\n// rejection: nothing hydrates, nothing is reported, and the page just sits there.\nmain().catch((error) => {\n console.error('[rshono] the client runtime failed to start:', error);\n showFatal(error);\n});\n"]}
1
+ {"version":3,"file":"entry.client.js","sourceRoot":"","sources":["../../src/runtime/entry.client.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react';\nimport { hydrateRoot } from 'react-dom/client';\nimport {\n createFromFetch,\n createFromReadableStream,\n createTemporaryReferenceSet,\n encodeReply,\n setServerCallback,\n} from 'react-server-dom-rspack/client.browser';\nimport { isControlDigest, parseRedirectDigest } from './control.js';\nimport type { DevMessage } from './dev-protocol.js';\nimport type { RscPayload } from './entry.rsc.js';\n// Dev-only: its one caller sits behind `import.meta.webpackHot`, which a production build compiles to\n// `false` — so this module is dropped there.\nimport { walkHotUpdates } from './hot-update.js';\nimport { RouterContext, type NavigationRouter } from './navigation.js';\nimport { createRscRequest } from './request.js';\n\nconst isDev = process.env.NODE_ENV === 'development';\n\ndeclare global {\n /** The array the payload `<script>` tags `flight-inject.ts` emits push their chunks into. */\n var __FLIGHT_DATA: Array<string | Uint8Array> | undefined;\n}\n\n/** The flight payload the document carried, read back out of `__FLIGHT_DATA` — see `flight-inject.ts`. */\nfunction readFlightPayload(): ReadableStream<Uint8Array> {\n const encoder = new TextEncoder();\n // Assigned synchronously by `start`, which `new ReadableStream` runs before it returns.\n let controller!: ReadableStreamDefaultController<Uint8Array>;\n const stream = new ReadableStream<Uint8Array>({\n start: (c) => void (controller = c),\n });\n const enqueue = (chunk: string | Uint8Array) => controller.enqueue(typeof chunk === 'string' ? encoder.encode(chunk) : chunk);\n\n // Payload scripts interleave with the document: the ones that already ran are in the array, the rest\n // arrive through `push`.\n const data = (self.__FLIGHT_DATA ??= []);\n for (const chunk of data) enqueue(chunk);\n data.push = enqueue as typeof data.push;\n\n // The last payload script lands before parsing finishes, so that is what closes the stream.\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', () => controller.close(), { once: true });\n } else {\n controller.close();\n }\n return stream;\n}\n\n/** Created at module evaluation, not inside `main()`, so no chunk can be pushed before it is watching. */\nconst flightStream = readFlightPayload();\n\n/**\n * The part of the location a payload is rendered for — the document, without the fragment, which the server\n * never sees. Two URLs that differ only by `#hash` describe the same payload.\n */\nconst documentUrl = (): string => location.pathname + location.search;\n\n/** Guarantees somewhere to attach the fatal overlay: the root container is `document`, so a teardown can take `<body>` with it. */\nfunction overlayHost(): HTMLElement {\n if (!document.documentElement) document.appendChild(document.createElement('html'));\n if (!document.body) document.documentElement.appendChild(document.createElement('body'));\n return document.body;\n}\n\n/**\n * Paints the reason for an uncaught render error over the blank page it leaves behind — the full stack in\n * dev, a generic notice and a reload button in production.\n *\n * DOM calls rather than React (the renderer is what just failed), and `textContent` rather than\n * `innerHTML` (an error message is untrusted input).\n */\nfunction showFatal(error: unknown, componentStack?: string | null): void {\n // Queued: React's teardown runs after this callback returns and would remove a node appended inline.\n setTimeout(() => {\n const host = overlayHost();\n host.querySelector('[data-rshono-fatal]')?.remove();\n\n const box = document.createElement('div');\n box.setAttribute('data-rshono-fatal', '');\n box.setAttribute('role', 'alert');\n box.style.cssText =\n 'position:fixed;inset:0;z-index:2147483647;overflow:auto;padding:1.5rem;background:#18181b;color:#f4f4f5;' +\n 'font:14px/1.6 ui-monospace,SFMono-Regular,Menlo,monospace;text-align:left';\n\n const title = document.createElement('div');\n title.textContent = isDev ? 'Unhandled error' : 'Something went wrong';\n title.style.cssText = 'font-size:1.0625rem;font-weight:700;color:#f87171;margin:0 0 0.75rem';\n box.appendChild(title);\n\n if (isDev) {\n const detail = document.createElement('pre');\n detail.style.cssText = 'margin:0;white-space:pre-wrap;word-break:break-word';\n detail.textContent =\n (error instanceof Error ? (error.stack ?? `${error.name}: ${error.message}`) : String(error)) +\n (componentStack ? `\\n\\nComponent stack:${componentStack}` : '');\n box.appendChild(detail);\n } else {\n const message = document.createElement('p');\n message.textContent = 'This page hit an unexpected error and can’t continue.';\n message.style.cssText = 'margin:0 0 1rem;color:#d4d4d8';\n box.appendChild(message);\n }\n\n const reload = document.createElement('button');\n reload.textContent = 'Reload page';\n reload.style.cssText =\n 'margin-top:1.25rem;padding:0.5rem 1rem;font:inherit;color:#18181b;background:#f4f4f5;border:0;border-radius:4px;cursor:pointer';\n reload.addEventListener('click', () => window.location.reload());\n box.appendChild(reload);\n\n host.appendChild(box);\n }, 0);\n}\n\n/**\n * Asks a URL for its flight payload. Deliberately uncached — a payload can never be staler than the click\n * that wanted it, and the browser's own HTTP cache is what makes a repeat visit cheap.\n */\nfunction requestPayload(href: string, signal?: AbortSignal): Promise<RscPayload> {\n return createFromFetch<RscPayload>(fetch(createRscRequest(new URL(href, location.href).href, undefined, signal)));\n}\n\n/**\n * Whether the browser hands us its navigations. Gated on `sourceElement` rather than on `navigation` itself:\n * Chrome shipped the event in 102 and that property only in 135, and without it a `data-native` link cannot\n * be told from any other — so the older window would soft-navigate the very links that asked not to be.\n *\n * Where this is false there is no interception at all and every navigation is a real browser load, which a\n * server-rendered app answers correctly on its own. Only the soft part is missing.\n *\n * Both globals are tested, and neither is touched before: this runs at module scope, where a ReferenceError\n * would take the whole client runtime down with it rather than degrading anything.\n */\nconst canSoftNavigate = typeof navigation !== 'undefined' && typeof NavigateEvent !== 'undefined' && 'sourceElement' in NavigateEvent.prototype;\n\n/**\n * Drops a navigation's result promises. Both reject when a navigation is superseded or cancelled — routine\n * here, since a second click is meant to abandon the first — and unhandled they would be reported as faults.\n */\nfunction settle(result: NavigationResult): void {\n const ignore = () => {};\n void result.committed?.catch(ignore);\n void result.finished?.catch(ignore);\n}\n\n// The imperative actions behind `useNavigation().router`. Each one only *asks*: the browser turns it into a\n// `navigate` event, which is where `listenNavigation` answers it — so a `router.push` and a link click reach\n// the same code by the same route, and inherit the same fetch, scroll and `pending` flag.\nfunction push(href: string): void {\n if (canSoftNavigate) settle(navigation.navigate(href, { history: 'push' }));\n else window.location.assign(href);\n}\n\nfunction replace(href: string): void {\n if (canSoftNavigate) settle(navigation.navigate(href, { history: 'replace' }));\n else window.location.replace(href);\n}\n\n// A traversal is the browser's to perform either way — `navigation` only hands it back as an interceptable\n// event first. Nothing to go back to is a rejection there and a no-op here; both amount to the same thing.\nfunction back(): void {\n if (canSoftNavigate) settle(navigation.back());\n else window.history.back();\n}\n\nfunction forward(): void {\n if (canSoftNavigate) settle(navigation.forward());\n else window.history.forward();\n}\n\n// A refresh keeps the URL, and is still a navigation: it arrives as `navigationType: 'reload'`, which is what\n// tells the listener to leave scroll and focus where the user left them.\nfunction refresh(): void {\n if (canSoftNavigate) settle(navigation.reload());\n else window.location.reload();\n}\n\n/**\n * Turns a control-signal digest — how `redirect()` / `notFound()` reach the browser — into a real\n * navigation. Returns false for anything else, so callers fall through to their own handling.\n *\n * `hard` forces a full document load, for signals that surfaced *through React*: it unmounts the root on\n * an uncaught error, leaving no live tree to soft-navigate with.\n */\nfunction handleControlDigest(error: unknown, { hard = false }: { hard?: boolean } = {}): boolean {\n const digest = (error as { digest?: unknown } | null)?.digest;\n if (!isControlDigest(digest)) return false;\n const redirect = parseRedirectDigest(digest);\n if (!redirect) {\n window.location.reload();\n } else if (hard) {\n window.location.assign(new URL(redirect.location, window.location.href).href);\n } else {\n push(redirect.location);\n }\n return true;\n}\n\n/**\n * Puts a payload on screen, resolving once React has committed it. Replaced by `BrowserRoot`'s own on mount;\n * the default covers the window before hydration, where `setServerCallback` is already registered but there\n * is no root to update — a reload is the honest answer, and nothing after it needs to run.\n */\nlet setPayload: (payload: RscPayload) => Promise<void> = () => {\n window.location.reload();\n return new Promise<void>(() => {});\n};\n\n/** Runs work inside the nav transition so `useNavigation().pending` stays true across the round-trip. */\nlet startNav: (run: () => void | Promise<void>) => void = (run) => {\n void run();\n};\n\n/**\n * Fetches the payload for `url` and puts it on screen.\n *\n * Resolves once React has **committed** it rather than when the fetch lands: an intercepted navigation\n * scrolls and moves focus when this promise settles, and a `#hash` target does not exist until the new tree\n * does. Rejects only on a genuine failure — being superseded is not one, and resolves quietly, because the\n * navigation that replaced this one owns the screen from then on.\n */\nfunction loadPayload(url: string, signal?: AbortSignal): Promise<void> {\n // Deliberately not awaited inside the transition: the scope ends once the payload is handed to React, and\n // React holds `pending` until the update it scheduled commits. Awaiting the commit *inside* the scope would\n // work too, but only because React happens not to gate a commit on its async scope settling — an internal\n // this has no reason to depend on across the whole `^19.1.0` peer range.\n let committed: Promise<void> | undefined;\n\n const run = async () => {\n const payload = await requestPayload(url, signal);\n // The browser aborts a navigation the moment a newer one starts. Checked again after the await because\n // the fetch may already have resolved by then, and applying it would repaint a page the user has left.\n if (signal?.aborted) return;\n if (payload.redirect) {\n push(payload.redirect);\n return;\n }\n committed = setPayload(payload);\n };\n\n // `startTransition` runs the work but hands nothing back, so the promise carrying a failure is caught here\n // instead. Assigned synchronously: React invokes the callback before `startNav` returns.\n let work!: Promise<void>;\n startNav(() => (work = run()));\n\n return work.then(\n // Undefined whenever nothing was applied — an abort, or a redirect — and there is then nothing to wait for.\n () => committed,\n (error: unknown) => {\n // Checked before the error is read: an abort is this navigation being replaced, and the one that\n // replaced it owns the outcome.\n if (signal?.aborted || handleControlDigest(error)) return;\n throw error;\n },\n );\n}\n\n/**\n * Navigations the browser can hand over but shouldn't:\n *\n * - a fragment jump, which is same-document already and needs no payload — the browser's own jump is the one\n * that honours `scroll-padding-top`, and re-rendering would pull the target out from under it;\n * - a download, which is not a navigation of this page at all;\n * - a `POST` form, which is a submission and the server's to answer (a `GET` form carries its fields in the\n * URL, has no `formData`, and soft-navigates like any other link);\n * - a link marked `data-native`, the documented opt-out.\n */\nfunction leaveToBrowser(event: NavigateEvent): boolean {\n return event.hashChange || event.downloadRequest !== null || event.formData !== null || event.sourceElement?.hasAttribute('data-native') === true;\n}\n\n/**\n * The whole router, in one listener.\n *\n * Every navigation the page can make arrives as a `navigate` event — a link click, a `GET` form, a\n * `history.pushState`, the back button, `navigation.reload()` — already filtered by the browser: it does not\n * fire for a middle-click, a modified click or a new tab, and reports `canIntercept: false` for anything\n * cross-origin, or for a traversal that leaves the app. Those need no handling here; they are left alone, and\n * the browser performs them as it always would.\n */\nfunction listenNavigation(): () => void {\n if (!canSoftNavigate) return () => {};\n\n const onNavigate = (event: NavigateEvent) => {\n if (!event.canIntercept || leaveToBrowser(event)) return;\n\n // A push or a traversal lands on a new page, so the browser resets the scroll offset — or restores the\n // one it remembers — and moves focus, which is what makes a soft navigation announce itself to a screen\n // reader. A replace or a refresh stays where it is, so neither should move. Both wait on the handler,\n // which is the point of resolving it at commit rather than at fetch.\n const inPlace = event.navigationType === 'replace' || event.navigationType === 'reload';\n\n event.intercept({\n scroll: inPlace ? 'manual' : 'after-transition',\n focusReset: inPlace ? 'manual' : 'after-transition',\n // The URL commits before the handler runs, so a failure leaves the address bar describing a page the\n // document is not showing. A real load is the only way back to agreement.\n handler: () => loadPayload(event.destination.url, event.signal).catch(() => window.location.reload()),\n });\n };\n\n navigation.addEventListener('navigate', onNavigate);\n return () => navigation.removeEventListener('navigate', onNavigate);\n}\n\nasync function main() {\n // The assertion is load-bearing under the compiler that builds this: TypeScript 7 declares `nonce` on\n // HTMLElement, 6 declares it on Element. ESLint runs the older lib — where the narrowing is redundant —\n // so it reports an assertion that `tsc` requires. Believe `typecheck`, not the rule.\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n const cspMeta = document.querySelector('meta[property=\"csp-nonce\"]') as HTMLMetaElement | null;\n if (cspMeta?.nonce) __webpack_nonce__ = cspMeta.nonce;\n\n const initialPayload = await createFromReadableStream<RscPayload>(flightStream);\n\n function BrowserRoot() {\n const [payload, setPayloadState] = React.useState(initialPayload);\n const [pending, startTransition] = React.useTransition();\n // The resolver the payload on screen still owes — see {@link loadPayload}.\n const pendingCommit = React.useRef<(() => void) | null>(null);\n\n React.useEffect(() => {\n setPayload = (next) =>\n new Promise<void>((resolve) => {\n // A payload replaced before it ever painted still has a navigation waiting on it. React commits\n // only the newest, so the effect below never runs for the one it skipped: release it here.\n pendingCommit.current?.();\n pendingCommit.current = resolve;\n setPayloadState(next);\n });\n startNav = (run) => startTransition(run);\n }, [startTransition]);\n\n /**\n * Releases the navigation waiting on this payload, which is what lets the browser scroll and move focus\n * now that their target exists. A layout effect, so the pre-scroll position is never painted.\n */\n React.useLayoutEffect(() => {\n const commit = pendingCommit.current;\n pendingCommit.current = null;\n commit?.();\n }, [payload]);\n\n React.useEffect(() => listenNavigation(), []);\n\n const router = React.useMemo<NavigationRouter>(() => ({ push, replace, back, forward, refresh, pending }), [pending]);\n\n return <RouterContext.Provider value={router}>{payload.root}</RouterContext.Provider>;\n }\n\n setServerCallback(async (id, args) => {\n const temporaryReferences = createTemporaryReferenceSet();\n // The document the action is being called from. Every action response carries a fresh payload for that\n // page, so if a navigation has moved on by the time it arrives the payload describes a page the user has\n // left — the return value is still theirs, but painting it is not. Compared without the fragment, which\n // the server never saw.\n const calledFrom = documentUrl();\n const request = createRscRequest(window.location.href, {\n id,\n body: await encodeReply(args, { temporaryReferences }),\n });\n let payload: RscPayload;\n try {\n payload = await createFromFetch<RscPayload>(fetch(request), { temporaryReferences });\n } catch (error) {\n if (handleControlDigest(error)) return undefined;\n throw error;\n }\n if (payload.redirect) {\n push(payload.redirect);\n return undefined;\n }\n if (documentUrl() === calledFrom) React.startTransition(() => void setPayload(payload));\n if (payload.notFound) return undefined;\n const result = payload.returnValue!;\n if (!result.ok) throw result.error;\n return result.value;\n });\n\n // A `redirect()` / `notFound()` from a component below the page root reaches us through React: it rides the\n // flight payload as an error, and boundaries re-throw it so it lands here rather than in a fallback.\n //\n // Installing these hooks opts out of React's own defaults, so everything that isn't a control signal has to\n // be put back by hand — `reportError` rather than a bare log, so error-reporting tools still see it.\n hydrateRoot(document, <BrowserRoot />, {\n formState: initialPayload.formState,\n onCaughtError: (error, errorInfo) => {\n if (handleControlDigest(error, { hard: true })) return;\n // A boundary handled it and the tree is intact, so no overlay over the app's own fallback.\n console.error(error, errorInfo.componentStack ?? '');\n },\n onUncaughtError: (error, errorInfo) => {\n if (handleControlDigest(error, { hard: true })) return;\n // Nothing caught it, so React tears the root down — and the root is `document`.\n globalThis.reportError(error);\n showFatal(error, errorInfo.componentStack);\n },\n });\n\n if (import.meta.webpackHot) {\n initDevRefresh();\n }\n}\n\n/**\n * Dev-only refresh client, listening to the CLI's SSE endpoint:\n *\n * client-built → hot-apply the waiting updates; anything the page can't be patched up to reloads.\n * rsc-update → server component code changed: re-fetch the flight payload, state preserved.\n * hello → sent on (re)connect with the latest build hash; a mismatch means a missed event.\n */\nfunction initDevRefresh() {\n const hot = import.meta.webpackHot!;\n let connectedOnce = false;\n /** The newest build the dev server has announced — what {@link applyClientUpdate} walks towards. */\n let targetHash: string | undefined;\n\n function reload(reason: string, error?: unknown): void {\n console.warn(`[rshono] ${reason} — reloading`, ...(error === undefined ? [] : [error]));\n window.location.reload();\n }\n\n async function applyClientUpdate(): Promise<void> {\n const giveUp = await walkHotUpdates(\n hot,\n () => __webpack_hash__,\n () => targetHash,\n );\n if (giveUp) reload(giveUp.reason, giveUp.error);\n }\n\n async function handle(message: DevMessage): Promise<void> {\n switch (message.type) {\n case 'hello':\n targetHash = message.hash ?? targetHash;\n if (connectedOnce) {\n await applyClientUpdate();\n await loadPayload(window.location.href).catch(() => window.location.reload());\n }\n connectedOnce = true;\n break;\n case 'client-built':\n targetHash = message.hash;\n await applyClientUpdate();\n break;\n case 'rsc-update':\n console.log('[rshono] server components updated');\n await loadPayload(window.location.href).catch(() => window.location.reload());\n break;\n }\n }\n\n const source = new EventSource('/_rshono/hmr');\n // Chained rather than handled as they arrive: `hot.check` may only run from `idle`, and a burst of saves\n // puts several frames on the wire inside the time one takes. Queueing drops nothing, because `targetHash`\n // is shared — whichever handler runs next walks to the newest build.\n let queue: Promise<void> = Promise.resolve();\n source.onmessage = (event: MessageEvent<string>) => {\n const message = JSON.parse(event.data) as DevMessage;\n queue = queue.then(() => handle(message)).catch((error) => reload('the dev client failed', error));\n };\n}\n\n// A bootstrap failure — a truncated initial payload, most likely — would otherwise be an unhandled\n// rejection: nothing hydrates, nothing is reported, and the page just sits there.\nmain().catch((error) => {\n console.error('[rshono] the client runtime failed to start:', error);\n showFatal(error);\n});\n"]}
@@ -6,6 +6,10 @@ import { type ReactNode } from 'react';
6
6
  * client component state outside the changed subtree survives. Off-site hrefs — and a traversal that leaves
7
7
  * the app — fall back to a full load.
8
8
  *
9
+ * Soft navigation is the browser's
10
+ * {@link https://developer.mozilla.org/en-US/docs/Web/API/Navigation_API | Navigation API}; where that is
11
+ * missing, every action below is still correct and simply performs a real browser load.
12
+ *
9
13
  * @example
10
14
  * ```tsx
11
15
  * const { router } = useNavigation();
@@ -1 +1 @@
1
- {"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../../src/runtime/navigation.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAsC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAE3E;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,gBAAgB;IAC/B,0DAA0D;IAC1D,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,sFAAsF;IACtF,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,+FAA+F;IAC/F,IAAI,IAAI,IAAI,CAAC;IACb,6FAA6F;IAC7F,OAAO,IAAI,IAAI,CAAC;IAChB,sFAAsF;IACtF,OAAO,IAAI,IAAI,CAAC;IAChB,kGAAkG;IAClG,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,oGAAoG;AACpG,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,GAAG,EAAE,GAAG,CAAC;IACT,yFAAyF;IACzF,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,4DAA4D;IAC5D,MAAM,EAAE,gBAAgB,CAAC;CAC1B;AAMD;;;;GAIG;AACH,eAAO,MAAM,aAAa,2CAAiD,CAAC;AAI5E;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,QAAQ,EAAE,SAAS,CAAA;CAAE,+BAK/H;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,aAAa,IAAI,eAAe,CAQ/C"}
1
+ {"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../../src/runtime/navigation.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAsC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAE3E;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,WAAW,gBAAgB;IAC/B,0DAA0D;IAC1D,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,sFAAsF;IACtF,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,+FAA+F;IAC/F,IAAI,IAAI,IAAI,CAAC;IACb,6FAA6F;IAC7F,OAAO,IAAI,IAAI,CAAC;IAChB,sFAAsF;IACtF,OAAO,IAAI,IAAI,CAAC;IAChB,kGAAkG;IAClG,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,oGAAoG;AACpG,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,GAAG,EAAE,GAAG,CAAC;IACT,yFAAyF;IACzF,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,4DAA4D;IAC5D,MAAM,EAAE,gBAAgB,CAAC;CAC1B;AAMD;;;;GAIG;AACH,eAAO,MAAM,aAAa,2CAAiD,CAAC;AAI5E;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,QAAQ,EAAE,SAAS,CAAA;CAAE,+BAK/H;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,aAAa,IAAI,eAAe,CAQ/C"}
@@ -1 +1 @@
1
- {"version":3,"file":"navigation.js","sourceRoot":"","sources":["../../src/runtime/navigation.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,OAAO,EAAkB,MAAM,OAAO,CAAC;AA+C3E,MAAM,IAAI,GAAG,GAAG,EAAE,GAAE,CAAC,CAAC;AAEtB,MAAM,aAAa,GAAqB,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AAEhI;;;;GAIG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,aAAa,CAAmB,aAAa,CAAC,CAAC;AAE5E,MAAM,iBAAiB,GAAG,aAAa,CAAyB,IAAI,CAAC,CAAC;AAEtE;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAyE;IAC9H,MAAM,MAAM,GAAG,UAAU,CAAC,aAAa,CAAC,CAAC;IACzC,MAAM,KAAK,GAAG,OAAO,CAAkB,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAE/G,OAAO,KAAC,iBAAiB,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,YAAG,QAAQ,GAA8B,CAAC;AAC3F,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,MAAM,UAAU,aAAa;IAC3B,MAAM,KAAK,GAAG,UAAU,CAAC,iBAAiB,CAAC,CAAC;IAC5C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CACb,mKAAmK,CACpK,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC","sourcesContent":["'use client';\n\nimport { createContext, useContext, useMemo, type ReactNode } from 'react';\n\n/**\n * Imperative navigation actions, reached as `useNavigation().router`.\n *\n * Every action is a **soft** navigation: the page's flight payload is fetched and applied in place, so\n * client component state outside the changed subtree survives. Off-site hrefs — and a traversal that leaves\n * the app — fall back to a full load.\n *\n * @example\n * ```tsx\n * const { router } = useNavigation();\n * router.push('/dashboard'); // navigate, new history entry\n * router.replace('/login'); // navigate, no new entry\n * router.back(); // one entry back, as the browser's button does\n * router.forward(); // one entry forward\n * router.refresh(); // re-run this route's server components\n * ```\n */\nexport interface NavigationRouter {\n /** Navigates to `href` and pushes a new history entry. */\n push(href: string): void;\n /** Navigates to `href`, replacing the current history entry instead of adding one. */\n replace(href: string): void;\n /** Steps one entry back in the browser's session history. Nothing to go back to is a no-op. */\n back(): void;\n /** Steps one entry forward in the browser's session history. A no-op on the newest entry. */\n forward(): void;\n /** Re-fetches the current route from the server, re-running its server components. */\n refresh(): void;\n /** `true` while a soft navigation is in flight — use it to disable controls or show a spinner. */\n pending: boolean;\n}\n\n/** The current location plus the {@link NavigationRouter}, as returned by {@link useNavigation}. */\nexport interface NavigationState {\n /**\n * The full current {@link URL}. A fresh instance per navigation, so mutating it affects nothing else\n * — it is not written back to the address bar.\n */\n url: URL;\n /** Matched route params for the current page, e.g. `{ id: '42' }` for `/profile/:id`. */\n params: Record<string, string>;\n /** Imperative navigation actions and the `pending` flag. */\n router: NavigationRouter;\n}\n\nconst noop = () => {};\n\nconst defaultRouter: NavigationRouter = { push: noop, replace: noop, back: noop, forward: noop, refresh: noop, pending: false };\n\n/**\n * Carries the live {@link NavigationRouter} from the hydration runtime down to {@link RouterProvider}.\n *\n * @internal\n */\nexport const RouterContext = createContext<NavigationRouter>(defaultRouter);\n\nconst NavigationContext = createContext<NavigationState | null>(null);\n\n/**\n * Publishes the per-render location and params for {@link useNavigation} to read. The RSC entry wraps\n * every page in one.\n *\n * @internal\n */\nexport function RouterProvider({ href, params, children }: { href: string; params: Record<string, string>; children: ReactNode }) {\n const router = useContext(RouterContext);\n const value = useMemo<NavigationState>(() => ({ url: new URL(href), params, router }), [href, params, router]);\n\n return <NavigationContext.Provider value={value}>{children}</NavigationContext.Provider>;\n}\n\n/**\n * Reactive access to the current URL and programmatic navigation, in one hook. Call it from a\n * `'use client'` component.\n *\n * `url` and `params` are computed on the server and travel in the flight payload, so they are correct\n * during SSR — no hydration flicker — and update on every navigation. `router` holds the imperative\n * actions plus a `pending` flag, `true` while a soft navigation is in flight.\n *\n * Hooks can't run in a server component; read the same data there from `getRequestContext()`.\n *\n * @example\n * ```tsx\n * 'use client';\n * import { useNavigation } from '@rshono/core/client';\n *\n * export function NextPage() {\n * const { url, router } = useNavigation();\n * const page = Number(url.searchParams.get('page') ?? '1');\n * return (\n * <button disabled={router.pending} onClick={() => router.push(`${url.pathname}?page=${page + 1}`)}>\n * Next {router.pending ? '…' : ''}\n * </button>\n * );\n * }\n * ```\n *\n * @returns The current {@link NavigationState}: `url` and `params`, plus `router`\n * ({@link NavigationRouter}) with `push` / `replace` / `back` / `forward` / `refresh` / `pending`.\n * @throws If called outside a page's React tree, where there is no navigation\n * context to read.\n *\n * @see {@link https://www.rshono.com/docs/api#rshonocoreclient | Docs — `@rshono/core/client`}\n * @see {@link https://www.rshono.com/docs/pages#client-components | Docs — client components}\n */\nexport function useNavigation(): NavigationState {\n const value = useContext(NavigationContext);\n if (!value) {\n throw new Error(\n \"[rshono] useNavigation() must be called inside a 'use client' component rendered by a page. In a server component, read the URL from getRequestContext() instead.\",\n );\n }\n return value;\n}\n"]}
1
+ {"version":3,"file":"navigation.js","sourceRoot":"","sources":["../../src/runtime/navigation.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,OAAO,EAAkB,MAAM,OAAO,CAAC;AAmD3E,MAAM,IAAI,GAAG,GAAG,EAAE,GAAE,CAAC,CAAC;AAEtB,MAAM,aAAa,GAAqB,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AAEhI;;;;GAIG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,aAAa,CAAmB,aAAa,CAAC,CAAC;AAE5E,MAAM,iBAAiB,GAAG,aAAa,CAAyB,IAAI,CAAC,CAAC;AAEtE;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAyE;IAC9H,MAAM,MAAM,GAAG,UAAU,CAAC,aAAa,CAAC,CAAC;IACzC,MAAM,KAAK,GAAG,OAAO,CAAkB,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAE/G,OAAO,KAAC,iBAAiB,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,YAAG,QAAQ,GAA8B,CAAC;AAC3F,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,MAAM,UAAU,aAAa;IAC3B,MAAM,KAAK,GAAG,UAAU,CAAC,iBAAiB,CAAC,CAAC;IAC5C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CACb,mKAAmK,CACpK,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC","sourcesContent":["'use client';\n\nimport { createContext, useContext, useMemo, type ReactNode } from 'react';\n\n/**\n * Imperative navigation actions, reached as `useNavigation().router`.\n *\n * Every action is a **soft** navigation: the page's flight payload is fetched and applied in place, so\n * client component state outside the changed subtree survives. Off-site hrefs — and a traversal that leaves\n * the app — fall back to a full load.\n *\n * Soft navigation is the browser's\n * {@link https://developer.mozilla.org/en-US/docs/Web/API/Navigation_API | Navigation API}; where that is\n * missing, every action below is still correct and simply performs a real browser load.\n *\n * @example\n * ```tsx\n * const { router } = useNavigation();\n * router.push('/dashboard'); // navigate, new history entry\n * router.replace('/login'); // navigate, no new entry\n * router.back(); // one entry back, as the browser's button does\n * router.forward(); // one entry forward\n * router.refresh(); // re-run this route's server components\n * ```\n */\nexport interface NavigationRouter {\n /** Navigates to `href` and pushes a new history entry. */\n push(href: string): void;\n /** Navigates to `href`, replacing the current history entry instead of adding one. */\n replace(href: string): void;\n /** Steps one entry back in the browser's session history. Nothing to go back to is a no-op. */\n back(): void;\n /** Steps one entry forward in the browser's session history. A no-op on the newest entry. */\n forward(): void;\n /** Re-fetches the current route from the server, re-running its server components. */\n refresh(): void;\n /** `true` while a soft navigation is in flight — use it to disable controls or show a spinner. */\n pending: boolean;\n}\n\n/** The current location plus the {@link NavigationRouter}, as returned by {@link useNavigation}. */\nexport interface NavigationState {\n /**\n * The full current {@link URL}. A fresh instance per navigation, so mutating it affects nothing else\n * — it is not written back to the address bar.\n */\n url: URL;\n /** Matched route params for the current page, e.g. `{ id: '42' }` for `/profile/:id`. */\n params: Record<string, string>;\n /** Imperative navigation actions and the `pending` flag. */\n router: NavigationRouter;\n}\n\nconst noop = () => {};\n\nconst defaultRouter: NavigationRouter = { push: noop, replace: noop, back: noop, forward: noop, refresh: noop, pending: false };\n\n/**\n * Carries the live {@link NavigationRouter} from the hydration runtime down to {@link RouterProvider}.\n *\n * @internal\n */\nexport const RouterContext = createContext<NavigationRouter>(defaultRouter);\n\nconst NavigationContext = createContext<NavigationState | null>(null);\n\n/**\n * Publishes the per-render location and params for {@link useNavigation} to read. The RSC entry wraps\n * every page in one.\n *\n * @internal\n */\nexport function RouterProvider({ href, params, children }: { href: string; params: Record<string, string>; children: ReactNode }) {\n const router = useContext(RouterContext);\n const value = useMemo<NavigationState>(() => ({ url: new URL(href), params, router }), [href, params, router]);\n\n return <NavigationContext.Provider value={value}>{children}</NavigationContext.Provider>;\n}\n\n/**\n * Reactive access to the current URL and programmatic navigation, in one hook. Call it from a\n * `'use client'` component.\n *\n * `url` and `params` are computed on the server and travel in the flight payload, so they are correct\n * during SSR — no hydration flicker — and update on every navigation. `router` holds the imperative\n * actions plus a `pending` flag, `true` while a soft navigation is in flight.\n *\n * Hooks can't run in a server component; read the same data there from `getRequestContext()`.\n *\n * @example\n * ```tsx\n * 'use client';\n * import { useNavigation } from '@rshono/core/client';\n *\n * export function NextPage() {\n * const { url, router } = useNavigation();\n * const page = Number(url.searchParams.get('page') ?? '1');\n * return (\n * <button disabled={router.pending} onClick={() => router.push(`${url.pathname}?page=${page + 1}`)}>\n * Next {router.pending ? '…' : ''}\n * </button>\n * );\n * }\n * ```\n *\n * @returns The current {@link NavigationState}: `url` and `params`, plus `router`\n * ({@link NavigationRouter}) with `push` / `replace` / `back` / `forward` / `refresh` / `pending`.\n * @throws If called outside a page's React tree, where there is no navigation\n * context to read.\n *\n * @see {@link https://www.rshono.com/docs/api#rshonocoreclient | Docs — `@rshono/core/client`}\n * @see {@link https://www.rshono.com/docs/pages#client-components | Docs — client components}\n */\nexport function useNavigation(): NavigationState {\n const value = useContext(NavigationContext);\n if (!value) {\n throw new Error(\n \"[rshono] useNavigation() must be called inside a 'use client' component rendered by a page. In a server component, read the URL from getRequestContext() instead.\",\n );\n }\n return value;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rshono/core",
3
- "version": "1.0.0-rc.16",
3
+ "version": "1.0.0-rc.17",
4
4
  "description": "Minimalist web framework — Hono + Rspack + React Server Components",
5
5
  "author": "Lasse <lasse@lassetange.com> (https://www.lassetange.com)",
6
6
  "license": "MIT",
@@ -52,17 +52,17 @@
52
52
  },
53
53
  "dependencies": {
54
54
  "@hono/node-server": "^2.1.1",
55
- "@rspack/core": "2.1.7",
55
+ "@rspack/core": "2.2.0",
56
56
  "@rspack/plugin-react-refresh": "2.0.2",
57
57
  "react-refresh": "0.18.0",
58
- "react-server-dom-rspack": "0.0.3"
58
+ "react-server-dom-rspack": "0.1.0"
59
59
  },
60
60
  "devDependencies": {
61
61
  "@playwright/test": "^1.62.1",
62
62
  "@types/node": "^26.2.0",
63
63
  "@types/react": "^19.2.18",
64
64
  "@types/react-dom": "^19.2.4",
65
- "hono": "^4.13.1",
65
+ "hono": "^4.13.5",
66
66
  "react": "19.2.8",
67
67
  "react-dom": "19.2.8",
68
68
  "typescript": "^7.0.2"