bun-plugin-stx 0.2.396 → 0.2.397

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.
@@ -989,6 +989,7 @@ function routerSource() {
989
989
 
990
990
  var cache={};
991
991
  var prefetching={};
992
+ var awaitingKey='';
992
993
  var isNavigating=false;
993
994
 
994
995
  // LRU bookkeeping for cache/layoutCache/layoutGroupCache. Pre-fix
@@ -1580,6 +1581,19 @@ function routerSource() {
1580
1581
  // forward-navigation page.
1581
1582
  if(pushState!==false&&t.href===location.href&&!t.hash&&!force)return Promise.resolve(false);
1582
1583
 
1584
+ // Its prefetch is on the way: wait for that answer rather than asking the
1585
+ // server a second time. A later tap elsewhere wins.
1586
+ var awaitedKey=cacheKey(url);
1587
+ if(o.cache&&!force&&!cache[awaitedKey]&&prefetching[awaitedKey]&&prefetching[awaitedKey].then){
1588
+ awaitingKey=awaitedKey;
1589
+ return prefetching[awaitedKey].then(function(){
1590
+ if(awaitingKey!==awaitedKey)return false;
1591
+ awaitingKey='';
1592
+ return navigate(url,pushState,force);
1593
+ });
1594
+ }
1595
+ awaitingKey='';
1596
+
1583
1597
  isNavigating=true;
1584
1598
  instantNav=instantNext;
1585
1599
  instantNext=false;
@@ -2868,24 +2882,70 @@ else {
2868
2882
  // \u2500\u2500 Prefetch \u2500\u2500
2869
2883
  // A link's page, fetched before it is followed into the cache navigate
2870
2884
  // reads, so following it is a swap rather than a round trip.
2871
- function prefetchLink(link){
2885
+ // 'prefetching' holds each fetch in flight, so a tap that lands before its
2886
+ // prefetch has finished waits for that answer instead of asking again.
2887
+ // 'fresh' refetches a page that is cached, for an entry restored from an
2888
+ // earlier launch that is shown at once and replaced behind it.
2889
+ function prefetchLink(link,fresh){
2872
2890
  // Same opt-out set as the click path. Without it, hovering a link the
2873
2891
  // router is not allowed to claim still fired a real GET at it \u2014 a
2874
2892
  // logout or OAuth URL was requested on hover alone.
2875
2893
  if(isRouterExcluded(link))return;
2876
2894
  var href=withCurrentLocale(link.getAttribute('href'));
2877
2895
  var key=cacheKey(href);
2878
- if(cache[key]||prefetching[key])return;
2879
- prefetching[key]=true;
2896
+ if((cache[key]&&!fresh)||prefetching[key])return;
2897
+ var eager=link.getAttribute('data-stx-prefetch')==='eager';
2880
2898
  var wantsFragment=shouldUseFragmentResponse();
2881
- fetch(href,{headers:wantsFragment?{'X-STX-Router':'true','Accept':'text/html'}:{'Accept':'text/html'}}).then(function(r){
2899
+ prefetching[key]=fetch(href,{headers:wantsFragment?{'X-STX-Router':'true','Accept':'text/html'}:{'Accept':'text/html'}}).then(function(r){
2882
2900
  return readPrefetchResponse(r,wantsFragment);
2883
2901
  }).then(function(result){
2884
- if(result&&o.cache)setCache(key,result.html,result.layout,result.layoutGroup,result.title,result.containerAttrs);
2902
+ if(result&&o.cache){
2903
+ setCache(key,result.html,result.layout,result.layoutGroup,result.title,result.containerAttrs);
2904
+ if(eager)keepPage(key,result);
2905
+ }
2885
2906
  if(result)loadModuleRegistries(result.html,href);
2886
2907
  }).catch(function(){}).finally(function(){delete prefetching[key]});
2887
2908
  }
2888
2909
 
2910
+ // \u2500\u2500 Pages kept between launches \u2500\u2500
2911
+ // An eager link's page (a tab bar's) is kept in localStorage under the build
2912
+ // that rendered it, and put back into the cache when the next launch of the
2913
+ // same build starts. The first tap after opening the app is then a swap,
2914
+ // not a round trip, however far the server is; the eager prefetch replaces
2915
+ // the kept copy behind it. Pages of any other build are dropped, since a
2916
+ // runtime must never be handed another build's fragment (#1772).
2917
+ var KEPT_PREFIX='stx:pages:';
2918
+ var KEPT_MAX_BYTES=400000;
2919
+ function keptStore(){try{return window.localStorage||null}catch(e){return null}}
2920
+ function keepPage(key,result){
2921
+ var store=keptStore();
2922
+ if(!store||!loadedBuild||!result||!result.html||result.html.length>KEPT_MAX_BYTES)return;
2923
+ try{
2924
+ var all=JSON.parse(store.getItem(KEPT_PREFIX+loadedBuild)||'{}');
2925
+ all[key]={h:result.html,l:result.layout,g:result.layoutGroup,t:result.title,a:result.containerAttrs};
2926
+ store.setItem(KEPT_PREFIX+loadedBuild,JSON.stringify(all));
2927
+ }catch(e){}
2928
+ }
2929
+ function restoreKeptPages(){
2930
+ var store=keptStore();
2931
+ if(!store||!o.cache||!loadedBuild)return;
2932
+ try{
2933
+ for(var i=store.length-1;i>=0;i--){
2934
+ var name=store.key(i);
2935
+ if(name&&name.indexOf(KEPT_PREFIX)===0&&name!==KEPT_PREFIX+loadedBuild)store.removeItem(name);
2936
+ }
2937
+ var all=JSON.parse(store.getItem(KEPT_PREFIX+loadedBuild)||'{}');
2938
+ for(var key in all){
2939
+ var page=all[key];
2940
+ if(!Object.prototype.hasOwnProperty.call(all,key)||!page||!page.h||cache[key])continue;
2941
+ setCache(key,page.h,page.l||'',page.g||'',page.t||'',page.a||'');
2942
+ restored[key]=true;
2943
+ loadModuleRegistries(page.h,key);
2944
+ }
2945
+ }catch(e){}
2946
+ }
2947
+ var restored={};
2948
+
2889
2949
  // A prefetched page's module registry (the file its imports are bundled
2890
2950
  // into, one per page) is loaded with the prefetch, not on the tap. It only
2891
2951
  // registers modules, once, so loading it early changes nothing but timing,
@@ -2912,15 +2972,21 @@ else {
2912
2972
  eagerQueued=false;
2913
2973
  var connection=navigator.connection;
2914
2974
  if(connection&&(connection.saveData||/2g/.test(connection.effectiveType||'')))return;
2915
- var here=cacheKey(location.pathname+location.search);
2975
+ // The page it is on too: it was loaded as a whole document, so without
2976
+ // its fragment the way back to it went to the network.
2916
2977
  var links=document.querySelectorAll('[data-stx-link][data-stx-prefetch="eager"]');
2917
2978
  for(var i=0;i<links.length;i++){
2918
2979
  var href=links[i].getAttribute('href');
2919
- if(href&&cacheKey(withCurrentLocale(href))!==here)prefetchLink(links[i]);
2980
+ if(!href)continue;
2981
+ var key=cacheKey(withCurrentLocale(href));
2982
+ prefetchLink(links[i],restored[key]);
2983
+ delete restored[key];
2920
2984
  }
2921
2985
  };
2922
- if(window.requestIdleCallback)window.requestIdleCallback(run,{timeout:2000});
2923
- else setTimeout(run,300);
2986
+ // Soon after the first paint rather than whenever the page next idles: on
2987
+ // a distant server each page is a second away, and the first tap comes fast.
2988
+ if(window.requestIdleCallback)window.requestIdleCallback(run,{timeout:500});
2989
+ else setTimeout(run,100);
2924
2990
  }
2925
2991
 
2926
2992
  if(o.prefetch){
@@ -3179,6 +3245,7 @@ else {
3179
3245
  injectStyles();
3180
3246
  injectViewTransitionCSS();
3181
3247
  refreshCurrentLinks();
3248
+ restoreKeptPages();
3182
3249
  prefetchEager();
3183
3250
  }
3184
3251
 
package/dist/serve.js CHANGED
@@ -9800,7 +9800,7 @@ function __stxOverlay(errs){
9800
9800
  rebuildDiscoveredPagePaths(kept);
9801
9801
  await indexPageMiddleware(kept);
9802
9802
  try {
9803
- const { Router } = await import("./chunk-ap1t4j02.js");
9803
+ const { Router } = await import("./chunk-9z4zav9s.js");
9804
9804
  const pagesDirs = patterns.map((p) => p.replace(/\/$/, "")).filter(Boolean);
9805
9805
  const router = new Router(process19.cwd(), { pagesDirs, stateDir: stateDirName(), exclude: options.exclude });
9806
9806
  if (!options.quiet)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "bun-plugin-stx",
3
3
  "type": "module",
4
- "version": "0.2.396",
4
+ "version": "0.2.397",
5
5
  "description": "A Bun plugin that allows for using Laravel Blade-like syntax.",
6
6
  "author": "Chris Breuer <chris@stacksjs.org>",
7
7
  "license": "MIT",
@@ -74,7 +74,7 @@
74
74
  "typecheck": "bun tsc --noEmit"
75
75
  },
76
76
  "dependencies": {
77
- "@stacksjs/stx": "0.2.396",
78
- "stx-router": "0.2.396"
77
+ "@stacksjs/stx": "0.2.397",
78
+ "stx-router": "0.2.397"
79
79
  }
80
80
  }