bun-plugin-stx 0.2.86 → 0.2.87

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.
@@ -657,18 +657,24 @@ function getRouterScript() {
657
657
  // rather than a Map to keep the diff localized and the runtime
658
658
  // hand-minified shape consistent.
659
659
  var cacheOrder=[];
660
- function setCache(key,html,layout,group){
660
+ function setCache(key,html,layout,group,title){
661
661
  if(!(key in cache))cacheOrder.push(key);
662
662
  cache[key]=html;
663
663
  layoutCache[key]=layout;
664
664
  layoutGroupCache[key]=group;
665
+ titleCache[key]=title||'';
665
666
  while(cacheOrder.length>o.prefetchCacheMax){
666
667
  var oldest=cacheOrder.shift();
667
668
  delete cache[oldest];
668
669
  delete layoutCache[oldest];
669
670
  delete layoutGroupCache[oldest];
671
+ delete titleCache[oldest];
670
672
  }
671
673
  }
674
+ // Apply a page title captured from the fragment response's X-STX-Title
675
+ // header (URI-encoded) so SPA swaps keep document.title in sync with the
676
+ // page \u2014 full-document swaps set the title from the <title> tag directly.
677
+ function applyTitle(t){if(t){try{document.title=decodeURIComponent(t)}catch(e){document.title=t}}}
672
678
  function touchCache(key){
673
679
  var i=cacheOrder.indexOf(key);
674
680
  if(i>=0){cacheOrder.splice(i,1);cacheOrder.push(key)}
@@ -679,6 +685,7 @@ function getRouterScript() {
679
685
  delete cache[key];
680
686
  delete layoutCache[key];
681
687
  delete layoutGroupCache[key];
688
+ delete titleCache[key];
682
689
  }
683
690
 
684
691
  // Extract top-level CSS blocks (rules AND @media blocks with nested braces).
@@ -731,6 +738,7 @@ function getRouterScript() {
731
738
  // Only truly different layout groups trigger a full page reload.
732
739
  var layoutCache={};
733
740
  var layoutGroupCache={};
741
+ var titleCache={};
734
742
  // Track executed script hashes to prevent redeclaration errors on navigation.
735
743
  // Layout-level scripts (theme, nav setup) execute on initial page load and
736
744
  // should NOT re-execute when navigating to another page with the same layout.
@@ -851,6 +859,7 @@ function getRouterScript() {
851
859
  return;
852
860
  }
853
861
  swap(cache[targetPath],targetPath,pushState,targetHash);
862
+ applyTitle(titleCache[targetPath]);
854
863
  done();
855
864
  }
856
865
  else {
@@ -864,6 +873,7 @@ else {
864
873
  var isFragment=wantsFragment&&r.headers.get('X-STX-Fragment')==='true';
865
874
  var newLayout=r.headers.get('X-STX-Layout')||'';
866
875
  var newGroup=r.headers.get('X-STX-Layout-Group')||'';
876
+ var newTitle=r.headers.get('X-STX-Title')||'';
867
877
  // Layout change? Fetch the FULL page (no X-STX-Router header) and do full document swap
868
878
  if(isFragment&&checkLayoutChange(newLayout,url,newGroup)){
869
879
  log('[router] layout change \u2014 fetching full page for document swap');
@@ -872,16 +882,19 @@ else {
872
882
  if(!fullRes.ok)throw new Error(fullRes.status);
873
883
  return fullRes.text().then(function(html){
874
884
  log('[router] full page html length:',html.length);
875
- return{html:html,isFragment:false,layout:newLayout,layoutGroup:newGroup};
885
+ return{html:html,isFragment:false,layout:newLayout,layoutGroup:newGroup,title:newTitle};
876
886
  });
877
887
  });
878
888
  }
879
- return r.text().then(function(html){return{html:html,isFragment:isFragment,layout:newLayout,layoutGroup:newGroup}});
889
+ return r.text().then(function(html){return{html:html,isFragment:isFragment,layout:newLayout,layoutGroup:newGroup,title:newTitle}});
880
890
  }).then(function(result){
881
891
  if(!result)return;
882
892
  if(result.isFragment)result.html='<!--stx-fragment-->'+result.html;
883
- if(o.cache)setCache(targetPath,result.html,result.layout,result.layoutGroup);
893
+ if(o.cache)setCache(targetPath,result.html,result.layout,result.layoutGroup,result.title);
884
894
  swap(result.html,targetPath,pushState,targetHash);
895
+ // Fragment swaps carry no <head>; apply the title from the header.
896
+ // Full-document swaps already set document.title from the <title> tag.
897
+ if(result.isFragment)applyTitle(result.title);
885
898
  }).catch(function(err){
886
899
  console.error('[router] fetch error:',err);
887
900
  location.href=url;
@@ -1316,9 +1329,10 @@ else {
1316
1329
  var isFrag=wantsFragment&&r.headers.get('X-STX-Fragment')==='true';
1317
1330
  var pLayout=r.headers.get('X-STX-Layout')||'';
1318
1331
  var pGroup=r.headers.get('X-STX-Layout-Group')||'';
1319
- return r.text().then(function(html){return{html:isFrag?'<!--stx-fragment-->'+html:html,layout:pLayout,layoutGroup:pGroup}});
1332
+ var pTitle=r.headers.get('X-STX-Title')||'';
1333
+ return r.text().then(function(html){return{html:isFrag?'<!--stx-fragment-->'+html:html,layout:pLayout,layoutGroup:pGroup,title:pTitle}});
1320
1334
  }).then(function(result){
1321
- if(o.cache)setCache(key,result.html,result.layout,result.layoutGroup);
1335
+ if(o.cache)setCache(key,result.html,result.layout,result.layoutGroup,result.title);
1322
1336
  }).catch(function(){}).finally(function(){delete prefetching[key]});
1323
1337
  },true);
1324
1338
  }
@@ -1415,7 +1429,7 @@ else {
1415
1429
  var key=cacheKey(url);
1416
1430
  if(!cache[key]){
1417
1431
  var wantsFragment=shouldUseFragmentResponse();
1418
- 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')||'';return r.text().then(function(html){return{html:isFrag?'<!--stx-fragment-->'+html:html,layout:pLayout,layoutGroup:pGroup}})}).then(function(result){setCache(key,result.html,result.layout,result.layoutGroup)}).catch(function(){});
1432
+ 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')||'';return r.text().then(function(html){return{html:isFrag?'<!--stx-fragment-->'+html:html,layout:pLayout,layoutGroup:pGroup,title:pTitle}})}).then(function(result){setCache(key,result.html,result.layout,result.layoutGroup,result.title)}).catch(function(){});
1419
1433
  }
1420
1434
  },
1421
1435
  clearCache:function(){for(var k in cache)delete cache[k];for(var lk in layoutCache)delete layoutCache[lk];for(var gk in layoutGroupCache)delete layoutGroupCache[gk];cacheOrder.length=0},
package/dist/serve.js CHANGED
@@ -9275,7 +9275,7 @@ After installing: bun add bun-plugin-stx`);
9275
9275
  pageMiddlewarePatterns.length = 0;
9276
9276
  await Promise.all(files.map((f) => detectPageMiddleware(f)));
9277
9277
  try {
9278
- const { Router } = await import("./chunk-394anrmt.js");
9278
+ const { Router } = await import("./chunk-kgzhgwc6.js");
9279
9279
  const pagesDirs = patterns.map((p) => p.replace(/\/$/, "")).filter(Boolean);
9280
9280
  const router = new Router(process19.cwd(), { pagesDirs });
9281
9281
  if (!options.quiet)
@@ -10151,12 +10151,15 @@ ${fragment}
10151
10151
  ${clearStale}
10152
10152
  ${pageSetupScripts.join(`
10153
10153
  `)}`;
10154
+ const titleMatch = content.match(/<title[^>]*>([\s\S]*?)<\/title>/i);
10155
+ const pageTitle = titleMatch ? titleMatch[1].trim() : "";
10154
10156
  return new Response(fragment, {
10155
10157
  headers: {
10156
10158
  "Content-Type": "text/html; charset=utf-8",
10157
10159
  "X-STX-Fragment": "true",
10158
10160
  "X-STX-Layout": pageLayout,
10159
10161
  "X-STX-Layout-Group": pageLayoutGroup,
10162
+ ...pageTitle && { "X-STX-Title": encodeURIComponent(pageTitle) },
10160
10163
  "Cache-Control": "no-store",
10161
10164
  ...corsHeaders
10162
10165
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "bun-plugin-stx",
3
3
  "type": "module",
4
- "version": "0.2.86",
4
+ "version": "0.2.87",
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",