@rsc-kit/core 0.20.5 → 0.20.6

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.
@@ -13,8 +13,9 @@
13
13
  * hydration commits - not when the runtime's script runs, which is
14
14
  * seconds earlier on a phone whose chunks are still downloading, and where
15
15
  * a click is nobody's yet - the last one held is navigated to. A click
16
- * held for three seconds without hydration is given to the browser as a
17
- * document load, so nothing is lost if the runtime never comes.
16
+ * held for three seconds with no runtime started is given to the browser
17
+ * as a document load, so nothing is lost if the runtime never comes; one
18
+ * held while the runtime is running waits for hydration, up to fifteen.
18
19
  *
19
20
  * Only this package's links, marked `data-rsc`: a plain anchor to a file, a
20
21
  * route.ts, a mailto or a foreign origin is not a page the router swaps in.
@@ -13,8 +13,9 @@
13
13
  * hydration commits - not when the runtime's script runs, which is
14
14
  * seconds earlier on a phone whose chunks are still downloading, and where
15
15
  * a click is nobody's yet - the last one held is navigated to. A click
16
- * held for three seconds without hydration is given to the browser as a
17
- * document load, so nothing is lost if the runtime never comes.
16
+ * held for three seconds with no runtime started is given to the browser
17
+ * as a document load, so nothing is lost if the runtime never comes; one
18
+ * held while the runtime is running waits for hydration, up to fifteen.
18
19
  *
19
20
  * Only this package's links, marked `data-rsc`: a plain anchor to a file, a
20
21
  * route.ts, a mailto or a foreign origin is not a page the router swaps in.
@@ -27,9 +28,14 @@ export const EARLY_CLICKS = "(function(){var q=[];function h(e){" +
27
28
  "var u;try{u=new URL(a.getAttribute('href'),location.href)}catch(x){return}" +
28
29
  "if(u.origin!==location.origin)return;" +
29
30
  "e.preventDefault();q.push(u.pathname+u.search+u.hash);a.setAttribute('data-pending','');" +
30
- // A tap held for longer than a page should take to hydrate is given to
31
- // the browser: three seconds from the tap, not from the script.
32
- "setTimeout(function(){if(q.length&&!w.__rsc_hydrated)location.href=q[q.length-1]},3000)}" +
31
+ // Given to the browser only when the runtime has not even started three
32
+ // seconds after the tap - a script blocked, a chunk that failed. While it
33
+ // is running, hydration is coming, and a phone's takes longer than three
34
+ // seconds: a tap given up at three landed as a document load half a
35
+ // second before the page would have handled it. Fifteen seconds is the
36
+ // hard limit for a runtime that started and never finished.
37
+ "setTimeout(function(){if(q.length&&!w.__rsc_hydrated&&!w.__rsc_navigate)location.href=q[q.length-1]},3000);" +
38
+ "setTimeout(function(){if(q.length&&!w.__rsc_hydrated)location.href=q[q.length-1]},15000)}" +
33
39
  "var w=window;document.addEventListener('click',h,true);" +
34
40
  "w.__rsc_early={q:q,stop:function(){document.removeEventListener('click',h,true)}}})();";
35
41
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"earlyClicks.js","sourceRoot":"","sources":["../../src/js/earlyClicks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,8GAA8G;AAC9G,MAAM,CAAC,MAAM,YAAY,GACvB,qCAAqC;IACrC,yFAAyF;IACzF,kEAAkE;IAClE,+CAA+C;IAC/C,4EAA4E;IAC5E,uCAAuC;IACvC,0FAA0F;IAC1F,uEAAuE;IACvE,gEAAgE;IAChE,0FAA0F;IAC1F,yDAAyD;IACzD,wFAAwF,CAAC;AAO3F;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAAwC;IACxE,MAAM,KAAK,GAAI,MAAkC,CAAC,WAAW,CAAC;IAE9D,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IAExB,KAAK,CAAC,IAAI,EAAE,CAAC;IAEb,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC;IAEjD,KAAK,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;IAEnB,IAAI,IAAI;QAAE,KAAK,QAAQ,CAAC,IAAI,CAAC,CAAC;IAE9B,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,EAAc;IAC3C,MAAM,CAAC,GAAG,MAAsE,CAAC;IAEjF,IAAI,CAAC,CAAC,cAAc,EAAE,CAAC;QACrB,EAAE,EAAE,CAAC;QAEL,OAAO;IACT,CAAC;IAED,CAAC,CAAC,iBAAiB,GAAG,GAAG,EAAE;QACzB,CAAC,CAAC,iBAAiB,GAAG,SAAS,CAAC;QAChC,EAAE,EAAE,CAAC;IACP,CAAC,CAAC;AACJ,CAAC","sourcesContent":["/**\n * A tap before the page can navigate.\n *\n * The document arrives, the bootstrap script starts the runtime, and on a\n * phone the runtime takes a while to arrive and hydrate - seconds, with a\n * tag manager or two on the main thread. A tap on a link in that window is\n * the browser's: a document load, of a page the router would have swapped\n * in. The port's \"Sign in is slow from the home page, and sometimes a full\n * reload\" was this, and only on a phone, where the window is wide.\n *\n * The first thing the bootstrap script does is listen: a click on one of\n * this package's links, before the page has hydrated, is held. When\n * hydration commits - not when the runtime's script runs, which is\n * seconds earlier on a phone whose chunks are still downloading, and where\n * a click is nobody's yet - the last one held is navigated to. A click\n * held for three seconds without hydration is given to the browser as a\n * document load, so nothing is lost if the runtime never comes.\n *\n * Only this package's links, marked `data-rsc`: a plain anchor to a file, a\n * route.ts, a mailto or a foreign origin is not a page the router swaps in.\n */\n\n/** Written into the bootstrap script, ahead of the runtime's import. No backticks: it lives in a template. */\nexport const EARLY_CLICKS =\n \"(function(){var q=[];function h(e){\" +\n \"if(e.defaultPrevented||e.button!==0||e.metaKey||e.ctrlKey||e.shiftKey||e.altKey)return;\" +\n \"var t=e.target;var a=t&&t.closest?t.closest('a[data-rsc]'):null;\" +\n \"if(!a||(a.target&&a.target!=='_self'))return;\" +\n \"var u;try{u=new URL(a.getAttribute('href'),location.href)}catch(x){return}\" +\n \"if(u.origin!==location.origin)return;\" +\n \"e.preventDefault();q.push(u.pathname+u.search+u.hash);a.setAttribute('data-pending','');\" +\n // A tap held for longer than a page should take to hydrate is given to\n // the browser: three seconds from the tap, not from the script.\n \"setTimeout(function(){if(q.length&&!w.__rsc_hydrated)location.href=q[q.length-1]},3000)}\" +\n \"var w=window;document.addEventListener('click',h,true);\" +\n \"w.__rsc_early={q:q,stop:function(){document.removeEventListener('click',h,true)}}})();\";\n\ninterface Early {\n q: string[];\n stop(): void;\n}\n\n/**\n * Hand the clicks held before hydration to the router. The last one is the\n * page the visitor meant; the ones before it were on the way there.\n */\nexport function replayEarlyClicks(navigate: (url: string) => Promise<void>): string | null {\n const early = (window as { __rsc_early?: Early }).__rsc_early;\n\n if (!early) return null;\n\n early.stop();\n\n const last = early.q[early.q.length - 1] ?? null;\n\n early.q.length = 0;\n\n if (last) void navigate(last);\n\n return last;\n}\n\n/**\n * Run once hydration has committed - now, if it already has, or when the\n * outermost client component's first effect says so. Before that a click\n * is nobody's: the listener above is still holding them, and React has no\n * fibers to dispatch to.\n */\nexport function afterHydration(fn: () => void): void {\n const w = window as { __rsc_hydrated?: boolean; __rsc_on_hydrated?: () => void };\n\n if (w.__rsc_hydrated) {\n fn();\n\n return;\n }\n\n w.__rsc_on_hydrated = () => {\n w.__rsc_on_hydrated = undefined;\n fn();\n };\n}\n"]}
1
+ {"version":3,"file":"earlyClicks.js","sourceRoot":"","sources":["../../src/js/earlyClicks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,8GAA8G;AAC9G,MAAM,CAAC,MAAM,YAAY,GACvB,qCAAqC;IACrC,yFAAyF;IACzF,kEAAkE;IAClE,+CAA+C;IAC/C,4EAA4E;IAC5E,uCAAuC;IACvC,0FAA0F;IAC1F,wEAAwE;IACxE,0EAA0E;IAC1E,yEAAyE;IACzE,oEAAoE;IACpE,uEAAuE;IACvE,4DAA4D;IAC5D,6GAA6G;IAC7G,2FAA2F;IAC3F,yDAAyD;IACzD,wFAAwF,CAAC;AAO3F;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAAwC;IACxE,MAAM,KAAK,GAAI,MAAkC,CAAC,WAAW,CAAC;IAE9D,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IAExB,KAAK,CAAC,IAAI,EAAE,CAAC;IAEb,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC;IAEjD,KAAK,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;IAEnB,IAAI,IAAI;QAAE,KAAK,QAAQ,CAAC,IAAI,CAAC,CAAC;IAE9B,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,EAAc;IAC3C,MAAM,CAAC,GAAG,MAAsE,CAAC;IAEjF,IAAI,CAAC,CAAC,cAAc,EAAE,CAAC;QACrB,EAAE,EAAE,CAAC;QAEL,OAAO;IACT,CAAC;IAED,CAAC,CAAC,iBAAiB,GAAG,GAAG,EAAE;QACzB,CAAC,CAAC,iBAAiB,GAAG,SAAS,CAAC;QAChC,EAAE,EAAE,CAAC;IACP,CAAC,CAAC;AACJ,CAAC","sourcesContent":["/**\n * A tap before the page can navigate.\n *\n * The document arrives, the bootstrap script starts the runtime, and on a\n * phone the runtime takes a while to arrive and hydrate - seconds, with a\n * tag manager or two on the main thread. A tap on a link in that window is\n * the browser's: a document load, of a page the router would have swapped\n * in. The port's \"Sign in is slow from the home page, and sometimes a full\n * reload\" was this, and only on a phone, where the window is wide.\n *\n * The first thing the bootstrap script does is listen: a click on one of\n * this package's links, before the page has hydrated, is held. When\n * hydration commits - not when the runtime's script runs, which is\n * seconds earlier on a phone whose chunks are still downloading, and where\n * a click is nobody's yet - the last one held is navigated to. A click\n * held for three seconds with no runtime started is given to the browser\n * as a document load, so nothing is lost if the runtime never comes; one\n * held while the runtime is running waits for hydration, up to fifteen.\n *\n * Only this package's links, marked `data-rsc`: a plain anchor to a file, a\n * route.ts, a mailto or a foreign origin is not a page the router swaps in.\n */\n\n/** Written into the bootstrap script, ahead of the runtime's import. No backticks: it lives in a template. */\nexport const EARLY_CLICKS =\n \"(function(){var q=[];function h(e){\" +\n \"if(e.defaultPrevented||e.button!==0||e.metaKey||e.ctrlKey||e.shiftKey||e.altKey)return;\" +\n \"var t=e.target;var a=t&&t.closest?t.closest('a[data-rsc]'):null;\" +\n \"if(!a||(a.target&&a.target!=='_self'))return;\" +\n \"var u;try{u=new URL(a.getAttribute('href'),location.href)}catch(x){return}\" +\n \"if(u.origin!==location.origin)return;\" +\n \"e.preventDefault();q.push(u.pathname+u.search+u.hash);a.setAttribute('data-pending','');\" +\n // Given to the browser only when the runtime has not even started three\n // seconds after the tap - a script blocked, a chunk that failed. While it\n // is running, hydration is coming, and a phone's takes longer than three\n // seconds: a tap given up at three landed as a document load half a\n // second before the page would have handled it. Fifteen seconds is the\n // hard limit for a runtime that started and never finished.\n \"setTimeout(function(){if(q.length&&!w.__rsc_hydrated&&!w.__rsc_navigate)location.href=q[q.length-1]},3000);\" +\n \"setTimeout(function(){if(q.length&&!w.__rsc_hydrated)location.href=q[q.length-1]},15000)}\" +\n \"var w=window;document.addEventListener('click',h,true);\" +\n \"w.__rsc_early={q:q,stop:function(){document.removeEventListener('click',h,true)}}})();\";\n\ninterface Early {\n q: string[];\n stop(): void;\n}\n\n/**\n * Hand the clicks held before hydration to the router. The last one is the\n * page the visitor meant; the ones before it were on the way there.\n */\nexport function replayEarlyClicks(navigate: (url: string) => Promise<void>): string | null {\n const early = (window as { __rsc_early?: Early }).__rsc_early;\n\n if (!early) return null;\n\n early.stop();\n\n const last = early.q[early.q.length - 1] ?? null;\n\n early.q.length = 0;\n\n if (last) void navigate(last);\n\n return last;\n}\n\n/**\n * Run once hydration has committed - now, if it already has, or when the\n * outermost client component's first effect says so. Before that a click\n * is nobody's: the listener above is still holding them, and React has no\n * fibers to dispatch to.\n */\nexport function afterHydration(fn: () => void): void {\n const w = window as { __rsc_hydrated?: boolean; __rsc_on_hydrated?: () => void };\n\n if (w.__rsc_hydrated) {\n fn();\n\n return;\n }\n\n w.__rsc_on_hydrated = () => {\n w.__rsc_on_hydrated = undefined;\n fn();\n };\n}\n"]}
package/dist/vite.js CHANGED
@@ -5558,7 +5558,11 @@ export function rscKit(options = {}) {
5558
5558
  // documents, for as long as the browser holds the script.
5559
5559
  nitro.options.routeRules = {
5560
5560
  ...(nitro.options.routeRules ?? {}),
5561
- "/sw.js": { ...(nitro.options.routeRules?.["/sw.js"] ?? {}), headers: { "cache-control": "no-cache", ...(nitro.options.routeRules?.["/sw.js"]?.headers ?? {}) } },
5561
+ // Spelled with max-age=0 rather than no-cache: a CDN's browser
5562
+ // cache TTL - Cloudflare's, four hours - applies where the origin
5563
+ // names no max-age, and rewrote no-cache to max-age=14400; a
5564
+ // max-age of zero it leaves alone, as it leaves the documents'.
5565
+ "/sw.js": { ...(nitro.options.routeRules?.["/sw.js"] ?? {}), headers: { "cache-control": "public, max-age=0, must-revalidate", ...(nitro.options.routeRules?.["/sw.js"]?.headers ?? {}) } },
5562
5566
  };
5563
5567
  // The names of functions survive Nitro's bundle. The pages were
5564
5568
  // prerendered against Vite's own server bundles, where a dependency