bun-plugin-stx 0.2.265 → 0.2.266

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.
@@ -756,6 +756,45 @@ function getRouterScript() {
756
756
  delete attrsCache[oldest];
757
757
  }
758
758
  }
759
+ // Read a prefetch response into the shape setCache stores, or null when this
760
+ // answer must not be cached at all.
761
+ //
762
+ // Both prefetch paths used to assemble this by hand, and both left out
763
+ // X-STX-Container-Attrs (#1947): setCache takes six arguments and they
764
+ // passed five, which JavaScript accepts without a word. The entry was
765
+ // cached with no container attributes, so a link that had been hovered
766
+ // before it was clicked applied '' on the cache hit, and setContainerAttrs
767
+ // stripped the class the previous navigation had put on the routed
768
+ // container. A dashboard lost its max-width, but only on links that
769
+ // happened to be hovered first, and a hard reload always fixed it \u2014 which
770
+ // made it read as a CSS problem.
771
+ //
772
+ // Hand-assembling it twice is what let them drift, so the two guards below
773
+ // live here rather than at the call sites \u2014 the hover path had one of them
774
+ // and the public router.prefetch() had neither:
775
+ //
776
+ // - a redirected body belongs to the URL it came FROM. A guarded route
777
+ // prefetched while logged out answers with /login's markup, and storing
778
+ // that under the guarded key poisons the cache: the later real
779
+ // navigation is a hit, so it swaps the login page in without ever
780
+ // reaching the network, where navigate's own redirect check would have
781
+ // caught it (#1849).
782
+ // - a fragment from a DIFFERENT build must not be handed to this page's
783
+ // runtime (#1772). navigate answers skew by reloading; a prefetch must
784
+ // not, because the user only hovered a link. Declining to cache is the
785
+ // whole fix \u2014 the click then goes to the network, where navigate does
786
+ // the reload properly.
787
+ function readPrefetchResponse(r,wantsFragment){
788
+ if(r.redirected)return Promise.resolve(null);
789
+ if(isBuildSkew(r.headers.get('X-STX-Build')||''))return Promise.resolve(null);
790
+ var isFrag=wantsFragment&&r.headers.get('X-STX-Fragment')==='true';
791
+ var layout=r.headers.get('X-STX-Layout')||'';
792
+ var group=r.headers.get('X-STX-Layout-Group')||'';
793
+ var title=r.headers.get('X-STX-Title')||'';
794
+ var cattrs=r.headers.get('X-STX-Container-Attrs')||'';
795
+ var runtime=r.headers.get('X-STX-Runtime')||'';
796
+ return r.text().then(function(html){return{html:isFrag?fragmentMarker(runtime)+html:html,layout:layout,layoutGroup:group,title:title,containerAttrs:cattrs}});
797
+ }
759
798
  // Apply a page title captured from the fragment response's X-STX-Title
760
799
  // header (URI-encoded) so SPA swaps keep document.title in sync with the
761
800
  // page \u2014 full-document swaps set the title from the <title> tag directly.
@@ -776,7 +815,14 @@ function getRouterScript() {
776
815
  var probe=document.createElement('div');
777
816
  probe.innerHTML='<i '+attrStr+'></i>';
778
817
  var src=probe.firstChild;
779
- if(src&&src.attributes){
818
+ // getAttributeNames first: it is the same standard DOM answer and it is
819
+ // what the test DOM implements. Reading .attributes alone made this
820
+ // silently return {} there \u2014 so the whole container-attrs path, header to
821
+ // element, had no test coverage at all while #1947 sat in it.
822
+ if(src&&src.getAttributeNames){
823
+ src.getAttributeNames().forEach(function(n){map[n]=src.getAttribute(n)});
824
+ }
825
+ else if(src&&src.attributes){
780
826
  Array.prototype.forEach.call(src.attributes,function(a){map[a.name]=a.value});
781
827
  }
782
828
  return map;
@@ -2240,21 +2286,9 @@ else {
2240
2286
  prefetching[key]=true;
2241
2287
  var wantsFragment=shouldUseFragmentResponse();
2242
2288
  fetch(href,{headers:wantsFragment?{'X-STX-Router':'true','Accept':'text/html'}:{'Accept':'text/html'}}).then(function(r){
2243
- // Never cache a body that came from somewhere else. A guarded route
2244
- // prefetched while logged out answers with /login's markup, and
2245
- // storing it under the guarded key poisons the cache: the later real
2246
- // navigation is a cache hit, so it swaps the login page in without
2247
- // ever hitting the network, where the redirect check above would
2248
- // have caught it (#1849).
2249
- if(r.redirected)return null;
2250
- var isFrag=wantsFragment&&r.headers.get('X-STX-Fragment')==='true';
2251
- var pLayout=r.headers.get('X-STX-Layout')||'';
2252
- var pGroup=r.headers.get('X-STX-Layout-Group')||'';
2253
- var pTitle=r.headers.get('X-STX-Title')||'';
2254
- var pRuntime=r.headers.get('X-STX-Runtime')||'';
2255
- return r.text().then(function(html){return{html:isFrag?fragmentMarker(pRuntime)+html:html,layout:pLayout,layoutGroup:pGroup,title:pTitle}});
2289
+ return readPrefetchResponse(r,wantsFragment);
2256
2290
  }).then(function(result){
2257
- if(result&&o.cache)setCache(key,result.html,result.layout,result.layoutGroup,result.title);
2291
+ if(result&&o.cache)setCache(key,result.html,result.layout,result.layoutGroup,result.title,result.containerAttrs);
2258
2292
  }).catch(function(){}).finally(function(){delete prefetching[key]});
2259
2293
  },true);
2260
2294
  }
@@ -2370,7 +2404,7 @@ else {
2370
2404
  var key=cacheKey(url);
2371
2405
  if(!cache[key]){
2372
2406
  var wantsFragment=shouldUseFragmentResponse();
2373
- fetch(url,{headers:wantsFragment?{'X-STX-Router':'true'}:{'Accept':'text/html'}}).then(function(r){var isFrag=wantsFragment&&r.headers.get('X-STX-Fragment')==='true';var pLayout=r.headers.get('X-STX-Layout')||'';var pGroup=r.headers.get('X-STX-Layout-Group')||'';var pTitle=r.headers.get('X-STX-Title')||'';var pRuntime=r.headers.get('X-STX-Runtime')||'';return r.text().then(function(html){return{html:isFrag?fragmentMarker(pRuntime)+html:html,layout:pLayout,layoutGroup:pGroup,title:pTitle}})}).then(function(result){setCache(key,result.html,result.layout,result.layoutGroup,result.title)}).catch(function(){});
2407
+ fetch(url,{headers:wantsFragment?{'X-STX-Router':'true'}:{'Accept':'text/html'}}).then(function(r){return readPrefetchResponse(r,wantsFragment)}).then(function(result){if(result)setCache(key,result.html,result.layout,result.layoutGroup,result.title,result.containerAttrs)}).catch(function(){});
2374
2408
  }
2375
2409
  },
2376
2410
  // Re-run the CURRENT route against the server and swap the result.
package/dist/serve.js CHANGED
@@ -9592,7 +9592,7 @@ function __stxOverlay(errs){
9592
9592
  pageMiddlewarePatterns.length = 0;
9593
9593
  await Promise.all(files.map((f) => detectPageMiddleware(f)));
9594
9594
  try {
9595
- const { Router } = await import("./chunk-xg4124d4.js");
9595
+ const { Router } = await import("./chunk-cm8d5hgw.js");
9596
9596
  const pagesDirs = patterns.map((p) => p.replace(/\/$/, "")).filter(Boolean);
9597
9597
  const router = new Router(process19.cwd(), { pagesDirs, stateDir: stateDirName() });
9598
9598
  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.265",
4
+ "version": "0.2.266",
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",