bun-plugin-stx 0.2.51 → 0.2.57
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/dist/{chunk-0nwya50v.js → chunk-ap5bhr00.js} +57 -21
- package/dist/serve.d.ts +5 -1
- package/dist/serve.js +17 -3
- package/package.json +8 -8
|
@@ -591,6 +591,19 @@ function getRouterScript() {
|
|
|
591
591
|
var containerSel=o.container;
|
|
592
592
|
var debug=!!o.debug;
|
|
593
593
|
function log(){if(debug&&typeof console!=='undefined'&&console.log)console.log.apply(console,arguments)}
|
|
594
|
+
function runViewTransition(callback){
|
|
595
|
+
if(!o.viewTransitions||!document.startViewTransition)return false;
|
|
596
|
+
try{
|
|
597
|
+
var transition=document.startViewTransition(callback);
|
|
598
|
+
var onAbort=function(err){log('[router] view transition aborted:',err&&err.message?err.message:err)};
|
|
599
|
+
if(transition&&transition.finished&&transition.finished.catch)transition.finished.catch(onAbort);
|
|
600
|
+
if(transition&&transition.updateCallbackDone&&transition.updateCallbackDone.catch)transition.updateCallbackDone.catch(onAbort);
|
|
601
|
+
return true;
|
|
602
|
+
}catch(err){
|
|
603
|
+
log('[router] view transition unavailable:',err&&err.message?err.message:err);
|
|
604
|
+
return false;
|
|
605
|
+
}
|
|
606
|
+
}
|
|
594
607
|
|
|
595
608
|
// \u2500\u2500 Progress bar (0\u2192100% at top of viewport) \u2500\u2500
|
|
596
609
|
// Native loading indicator baked into the router. Starts when navigation
|
|
@@ -738,6 +751,10 @@ function getRouterScript() {
|
|
|
738
751
|
return false;
|
|
739
752
|
}
|
|
740
753
|
|
|
754
|
+
function shouldUseFragmentResponse(){
|
|
755
|
+
return containerSel==='main'||containerSel==='[data-stx-content]';
|
|
756
|
+
}
|
|
757
|
+
|
|
741
758
|
function navigate(url,pushState,force){
|
|
742
759
|
log('[router] navigate() called:',url,'isNavigating:',isNavigating);
|
|
743
760
|
if(isNavigating)return;
|
|
@@ -791,10 +808,13 @@ function getRouterScript() {
|
|
|
791
808
|
}
|
|
792
809
|
else {
|
|
793
810
|
if(force&&cache[targetPath])delete cache[targetPath];
|
|
794
|
-
// First fetch as fragment (SPA mode)
|
|
795
|
-
|
|
811
|
+
// First fetch as fragment (SPA mode) when the configured container is
|
|
812
|
+
// the page content. Custom app-shell containers need full documents so
|
|
813
|
+
// the router does not inject a <main> fragment into the wrong element.
|
|
814
|
+
var wantsFragment=shouldUseFragmentResponse();
|
|
815
|
+
fetch(url,{headers:wantsFragment?{'X-STX-Router':'true','Accept':'text/html'}:{'Accept':'text/html'}}).then(function(r){
|
|
796
816
|
if(!r.ok)throw new Error(r.status);
|
|
797
|
-
var isFragment=r.headers.get('X-STX-Fragment')==='true';
|
|
817
|
+
var isFragment=wantsFragment&&r.headers.get('X-STX-Fragment')==='true';
|
|
798
818
|
var newLayout=r.headers.get('X-STX-Layout')||'';
|
|
799
819
|
var newGroup=r.headers.get('X-STX-Layout-Group')||'';
|
|
800
820
|
// Layout change? Fetch the FULL page (no X-STX-Router header) and do full document swap
|
|
@@ -899,12 +919,18 @@ else {
|
|
|
899
919
|
}
|
|
900
920
|
executedScriptHashes[h]=1;
|
|
901
921
|
var ns=document.createElement('script');
|
|
922
|
+
var hasImport=code.indexOf('import ')!==-1;
|
|
923
|
+
if(hasImport){
|
|
924
|
+
ns.type='module';
|
|
925
|
+
}
|
|
902
926
|
// Wrap in block scope to prevent const/let collisions on re-navigation.
|
|
903
927
|
// Without this, navigating away and back throws "Identifier has already
|
|
904
928
|
// been declared" because the previous page's top-level const/let are
|
|
905
|
-
// still in the global scope.
|
|
929
|
+
// still in the global scope. Skip the wrap for module scripts \u2014
|
|
930
|
+
// they get their own scope from ESM, and top-level 'import' is
|
|
931
|
+
// illegal inside a block, which would throw SyntaxError.
|
|
906
932
|
var isAlreadyScoped=code.trimStart().charAt(0)==='('||code.trimStart().charAt(0)===';'||code.indexOf('window.stx.mount')>-1;
|
|
907
|
-
ns.textContent=isAlreadyScoped?code:'{'+code+'}';
|
|
933
|
+
ns.textContent=(hasImport||isAlreadyScoped)?code:'{'+code+'}';
|
|
908
934
|
ns.setAttribute('data-stx-page','');
|
|
909
935
|
document.body.appendChild(ns);
|
|
910
936
|
});
|
|
@@ -912,7 +938,7 @@ else {
|
|
|
912
938
|
// THEN fire stx:load \u2014 now _latestSetup is set and processElement has the right scope
|
|
913
939
|
window.dispatchEvent(new Event('stx:load'));
|
|
914
940
|
}
|
|
915
|
-
if(
|
|
941
|
+
if(runViewTransition(doFragSwap)){}
|
|
916
942
|
else{currentContent.style.transition='opacity 0.12s ease-out';currentContent.style.opacity='0';setTimeout(function(){doFragSwap();currentContent.style.opacity='1';setTimeout(function(){currentContent.style.transition=''},150)},120)}
|
|
917
943
|
return;
|
|
918
944
|
}
|
|
@@ -1032,6 +1058,9 @@ else {
|
|
|
1032
1058
|
document.querySelectorAll('script[data-stx-page]').forEach(function(s){s.remove()});
|
|
1033
1059
|
|
|
1034
1060
|
var scripts=[];
|
|
1061
|
+
function addScript(text, runAlways){
|
|
1062
|
+
scripts.push({text:text,runAlways:!!runAlways});
|
|
1063
|
+
}
|
|
1035
1064
|
if(isLayoutChange){
|
|
1036
1065
|
// Layout change: collect ALL scripts from the new document body
|
|
1037
1066
|
// (layout scripts, component mounts, setup functions \u2014 everything)
|
|
@@ -1044,7 +1073,7 @@ else {
|
|
|
1044
1073
|
// Skip the signals runtime IIFE \u2014 it's already loaded
|
|
1045
1074
|
if(text.indexOf("'use strict';var cloakStyle")!==-1)return;
|
|
1046
1075
|
if(text.indexOf('__stxRouter')!==-1)return;
|
|
1047
|
-
|
|
1076
|
+
addScript(text,true);
|
|
1048
1077
|
});
|
|
1049
1078
|
}
|
|
1050
1079
|
// Also collect setup functions from <head>
|
|
@@ -1052,7 +1081,7 @@ else {
|
|
|
1052
1081
|
var text=s.textContent||'';
|
|
1053
1082
|
if(s.hasAttribute('src'))return;
|
|
1054
1083
|
if(!text.trim())return;
|
|
1055
|
-
if(text.indexOf('__stx_setup_')!==-1)
|
|
1084
|
+
if(text.indexOf('__stx_setup_')!==-1)addScript(text,true);
|
|
1056
1085
|
});
|
|
1057
1086
|
} else {
|
|
1058
1087
|
// Same layout: collect scripts from the container
|
|
@@ -1060,26 +1089,27 @@ else {
|
|
|
1060
1089
|
var text=s.textContent||'';
|
|
1061
1090
|
if(s.hasAttribute('src'))return;
|
|
1062
1091
|
if(!text.trim())return;
|
|
1063
|
-
|
|
1092
|
+
addScript(text,true);
|
|
1064
1093
|
});
|
|
1065
|
-
// Collect
|
|
1094
|
+
// Collect page scripts from <head> AND <body> (outside container).
|
|
1066
1095
|
// SSG builds place the setup function in <body> before <main>, not
|
|
1067
1096
|
// in <head>. Without this, SPA navigation on static sites never
|
|
1068
1097
|
// runs the setup and reactive data stays empty.
|
|
1069
1098
|
var seenSetups={};
|
|
1070
|
-
scripts.forEach(function(
|
|
1099
|
+
scripts.forEach(function(entry){var t=entry.text;if(t.indexOf('__stx_setup_')!==-1)seenSetups[t.substring(0,80)]=1});
|
|
1071
1100
|
doc.querySelectorAll('script').forEach(function(s){
|
|
1072
1101
|
var text=s.textContent||'';
|
|
1073
1102
|
if(s.hasAttribute('src'))return;
|
|
1074
1103
|
if(!text.trim())return;
|
|
1075
|
-
if(text.indexOf('__stx_setup_')===-1)return;
|
|
1076
1104
|
// Skip signals runtime and router (they contain __stx_setup references but aren't setup functions)
|
|
1077
1105
|
if(text.indexOf("'use strict';var cloakStyle")!==-1)return;
|
|
1078
1106
|
if(text.indexOf('__stxRouter')!==-1)return;
|
|
1107
|
+
if(newContent.contains(s))return;
|
|
1108
|
+
if(text.indexOf('__stx_setup_')===-1&&!s.hasAttribute('data-stx-scoped')&&!s.hasAttribute('data-stx-page'))return;
|
|
1079
1109
|
var key=text.substring(0,80);
|
|
1080
1110
|
if(seenSetups[key])return;
|
|
1081
1111
|
seenSetups[key]=1;
|
|
1082
|
-
|
|
1112
|
+
addScript(text,true);
|
|
1083
1113
|
});
|
|
1084
1114
|
}
|
|
1085
1115
|
|
|
@@ -1109,7 +1139,9 @@ else {
|
|
|
1109
1139
|
|
|
1110
1140
|
// Execute page scripts FIRST \u2014 they define setup functions and set _latestSetup
|
|
1111
1141
|
function execScripts(){
|
|
1112
|
-
scripts.forEach(function(
|
|
1142
|
+
scripts.forEach(function(entry){
|
|
1143
|
+
var text=typeof entry==='string'?entry:entry.text;
|
|
1144
|
+
var runAlways=typeof entry==='string'?false:entry.runAlways;
|
|
1113
1145
|
// Skip scripts that were already executed (layout-level partials
|
|
1114
1146
|
// like theme.stx). Their top-level const/function declarations
|
|
1115
1147
|
// would throw "Identifier has already been declared" on re-execution.
|
|
@@ -1119,7 +1151,7 @@ else {
|
|
|
1119
1151
|
var h=hashScript(text);
|
|
1120
1152
|
var isSetup=text.indexOf('__stx_setup_')!==-1;
|
|
1121
1153
|
var hasImport=text.indexOf('import ')!==-1;
|
|
1122
|
-
if(!isSetup&&executedScriptHashes[h])return;
|
|
1154
|
+
if(!runAlways&&!isSetup&&executedScriptHashes[h])return;
|
|
1123
1155
|
executedScriptHashes[h]=1;
|
|
1124
1156
|
// Wrap scripts with import statements as modules (Bug 3 fix)
|
|
1125
1157
|
var ns=document.createElement('script');
|
|
@@ -1129,8 +1161,11 @@ else {
|
|
|
1129
1161
|
// Wrap in block scope to prevent const/let collisions on re-navigation.
|
|
1130
1162
|
// Top-level const/let in <script> tags are global-scoped in browsers
|
|
1131
1163
|
// and throw "Identifier has already been declared" on re-execution.
|
|
1164
|
+
// Skip the wrap for module scripts \u2014 they get their own scope from
|
|
1165
|
+
// ESM, and top-level 'import' is illegal inside a block, which
|
|
1166
|
+
// would throw SyntaxError before the script ever runs.
|
|
1132
1167
|
var alreadyScoped=text.trimStart().charAt(0)==='('||text.trimStart().charAt(0)===';'||text.indexOf('window.stx.mount')>-1;
|
|
1133
|
-
ns.textContent=alreadyScoped?text:'{'+text+'}';
|
|
1168
|
+
ns.textContent=(hasImport||alreadyScoped)?text:'{'+text+'}';
|
|
1134
1169
|
ns.setAttribute('data-stx-page','');
|
|
1135
1170
|
document.body.appendChild(ns);
|
|
1136
1171
|
});
|
|
@@ -1146,8 +1181,7 @@ else {
|
|
|
1146
1181
|
}
|
|
1147
1182
|
}
|
|
1148
1183
|
|
|
1149
|
-
if(
|
|
1150
|
-
document.startViewTransition(doSwap);
|
|
1184
|
+
if(runViewTransition(doSwap)){
|
|
1151
1185
|
}
|
|
1152
1186
|
else {
|
|
1153
1187
|
// Fallback fade for browsers without View Transitions API
|
|
@@ -1213,8 +1247,9 @@ else {
|
|
|
1213
1247
|
var key=cacheKey(href);
|
|
1214
1248
|
if(cache[key]||prefetching[key])return;
|
|
1215
1249
|
prefetching[key]=true;
|
|
1216
|
-
|
|
1217
|
-
|
|
1250
|
+
var wantsFragment=shouldUseFragmentResponse();
|
|
1251
|
+
fetch(href,{headers:wantsFragment?{'X-STX-Router':'true','Accept':'text/html'}:{'Accept':'text/html'}}).then(function(r){
|
|
1252
|
+
var isFrag=wantsFragment&&r.headers.get('X-STX-Fragment')==='true';
|
|
1218
1253
|
var pLayout=r.headers.get('X-STX-Layout')||'';
|
|
1219
1254
|
var pGroup=r.headers.get('X-STX-Layout-Group')||'';
|
|
1220
1255
|
return r.text().then(function(html){return{html:isFrag?'<!--stx-fragment-->'+html:html,layout:pLayout,layoutGroup:pGroup}});
|
|
@@ -1315,7 +1350,8 @@ else {
|
|
|
1315
1350
|
prefetch:function(url){
|
|
1316
1351
|
var key=cacheKey(url);
|
|
1317
1352
|
if(!cache[key]){
|
|
1318
|
-
|
|
1353
|
+
var wantsFragment=shouldUseFragmentResponse();
|
|
1354
|
+
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){cache[key]=result.html;layoutCache[key]=result.layout;layoutGroupCache[key]=result.layoutGroup}).catch(function(){});
|
|
1319
1355
|
}
|
|
1320
1356
|
},
|
|
1321
1357
|
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]},
|
package/dist/serve.d.ts
CHANGED
|
@@ -13,7 +13,11 @@ export declare interface ServeOptions {
|
|
|
13
13
|
quiet?: boolean
|
|
14
14
|
stxModule?: typeof import('@stacksjs/stx') | Promise<typeof import('@stacksjs/stx')>
|
|
15
15
|
routes?: Record<string, (req: Request) => Response | Promise<Response>>
|
|
16
|
-
onRequest?: (req: Request) =>
|
|
16
|
+
onRequest?: (req: Request) =>
|
|
17
|
+
| Response
|
|
18
|
+
| null
|
|
19
|
+
| undefined
|
|
20
|
+
| Promise<Response | null | undefined>
|
|
17
21
|
middleware?: Record<string, MiddlewareHandler>
|
|
18
22
|
globalMiddleware?: string[]
|
|
19
23
|
middlewareGroups?: Record<string, string[]>
|
package/dist/serve.js
CHANGED
|
@@ -8736,6 +8736,16 @@ async function serve(options) {
|
|
|
8736
8736
|
cwd: process19.cwd(),
|
|
8737
8737
|
defaultConfig: defaultStxConfig
|
|
8738
8738
|
});
|
|
8739
|
+
try {
|
|
8740
|
+
const stxMod = options.stxModule ? options.stxModule : await defaultStxModule;
|
|
8741
|
+
if (stxMod && typeof stxMod.loadStxConfig === "function") {
|
|
8742
|
+
const pluginLoaded = await stxMod.loadStxConfig();
|
|
8743
|
+
if (pluginLoaded?._pluginComponentDirs)
|
|
8744
|
+
stxConfig._pluginComponentDirs = pluginLoaded._pluginComponentDirs;
|
|
8745
|
+
if (pluginLoaded?._pluginPageDirs)
|
|
8746
|
+
stxConfig._pluginPageDirs = pluginLoaded._pluginPageDirs;
|
|
8747
|
+
}
|
|
8748
|
+
} catch {}
|
|
8739
8749
|
const componentsDir = options.componentsDir ?? stxConfig.componentsDir ?? defaultStxConfig.componentsDir;
|
|
8740
8750
|
const layoutsDir = options.layoutsDir ?? stxConfig.layoutsDir ?? defaultStxConfig.layoutsDir;
|
|
8741
8751
|
const partialsDir = options.partialsDir ?? stxConfig.partialsDir ?? defaultStxConfig.partialsDir;
|
|
@@ -8959,7 +8969,7 @@ After installing: bun add bun-plugin-stx`);
|
|
|
8959
8969
|
pageMiddlewarePatterns.length = 0;
|
|
8960
8970
|
await Promise.all(files.map((f) => detectPageMiddleware(f)));
|
|
8961
8971
|
try {
|
|
8962
|
-
const { Router } = await import("./chunk-
|
|
8972
|
+
const { Router } = await import("./chunk-ap5bhr00.js");
|
|
8963
8973
|
const pagesDirs = patterns.map((p) => p.replace(/\/$/, "")).filter(Boolean);
|
|
8964
8974
|
const router = new Router(process19.cwd(), { pagesDirs });
|
|
8965
8975
|
console.log(`[stx] Generated ${router.routes.length} routes \u2192 .stx/routes.ts`);
|
|
@@ -9162,7 +9172,9 @@ After installing: bun add bun-plugin-stx`);
|
|
|
9162
9172
|
..."defaultTitle" in stxConfig && { defaultTitle: stxConfig.defaultTitle },
|
|
9163
9173
|
..."defaultDescription" in stxConfig && { defaultDescription: stxConfig.defaultDescription },
|
|
9164
9174
|
..."defaultImage" in stxConfig && { defaultImage: stxConfig.defaultImage },
|
|
9165
|
-
..."seo" in stxConfig && { seo: stxConfig.seo }
|
|
9175
|
+
..."seo" in stxConfig && { seo: stxConfig.seo },
|
|
9176
|
+
..."_pluginComponentDirs" in stxConfig && { _pluginComponentDirs: stxConfig._pluginComponentDirs },
|
|
9177
|
+
..."_pluginPageDirs" in stxConfig && { _pluginPageDirs: stxConfig._pluginPageDirs }
|
|
9166
9178
|
};
|
|
9167
9179
|
if (config5.ssr === false || stxConfig.ssr === false) {
|
|
9168
9180
|
return generateSpaShell({
|
|
@@ -9332,7 +9344,9 @@ After installing: bun add bun-plugin-stx`);
|
|
|
9332
9344
|
..."defaultTitle" in stxConfig && { defaultTitle: stxConfig.defaultTitle },
|
|
9333
9345
|
..."defaultDescription" in stxConfig && { defaultDescription: stxConfig.defaultDescription },
|
|
9334
9346
|
..."defaultImage" in stxConfig && { defaultImage: stxConfig.defaultImage },
|
|
9335
|
-
..."seo" in stxConfig && { seo: stxConfig.seo }
|
|
9347
|
+
..."seo" in stxConfig && { seo: stxConfig.seo },
|
|
9348
|
+
..."_pluginComponentDirs" in stxConfig && { _pluginComponentDirs: stxConfig._pluginComponentDirs },
|
|
9349
|
+
..."_pluginPageDirs" in stxConfig && { _pluginPageDirs: stxConfig._pluginPageDirs }
|
|
9336
9350
|
};
|
|
9337
9351
|
let output = templateContent;
|
|
9338
9352
|
const dependencies = new Set;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bun-plugin-stx",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.57",
|
|
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",
|
|
@@ -61,19 +61,19 @@
|
|
|
61
61
|
],
|
|
62
62
|
"scripts": {
|
|
63
63
|
"build": "bun --bun build.ts",
|
|
64
|
-
"lint": "
|
|
65
|
-
"lint:fix": "
|
|
66
|
-
"fresh": "
|
|
67
|
-
"changelog": "
|
|
64
|
+
"lint": "bun x --bun pickier lint",
|
|
65
|
+
"lint:fix": "bun x --bun pickier lint --fix",
|
|
66
|
+
"fresh": "bun x rimraf node_modules/ bun.lock && bun i",
|
|
67
|
+
"changelog": "bun x changelogen --output CHANGELOG.md",
|
|
68
68
|
"prepublishOnly": "bun run build",
|
|
69
|
-
"release": "bun run changelog &&
|
|
69
|
+
"release": "bun run changelog && bun x bumpp package.json --all",
|
|
70
70
|
"test": "bun test --preload ../../test-utils/happy-dom.ts",
|
|
71
71
|
"test:watch": "bun test --watch --preload ../../test-utils/happy-dom.ts",
|
|
72
72
|
"test:coverage": "bun test --coverage --preload ../../test-utils/happy-dom.ts",
|
|
73
73
|
"typecheck": "bun tsc --noEmit"
|
|
74
74
|
},
|
|
75
75
|
"dependencies": {
|
|
76
|
-
"@stacksjs/stx": "0.2.
|
|
77
|
-
"stx-router": "0.2.
|
|
76
|
+
"@stacksjs/stx": "0.2.57",
|
|
77
|
+
"stx-router": "0.2.57"
|
|
78
78
|
}
|
|
79
79
|
}
|