bun-plugin-stx 0.2.293 → 0.2.294
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-nb1x6zdk.js → chunk-awcgpf66.js} +22 -4
- package/dist/serve.d.ts +19 -0
- package/dist/serve.js +13 -5
- package/package.json +1 -1
|
@@ -986,8 +986,8 @@ function getRouterScript() {
|
|
|
986
986
|
// Unlike a fragment, a document holds the answer directly, so there is
|
|
987
987
|
// nothing to infer from markers or ask the server for: look for the script.
|
|
988
988
|
// Both emitted shapes carry data-stx-runtime \u2014 inline, and the serve-mode
|
|
989
|
-
// src="/_stx/runtime
|
|
990
|
-
// rendered by a server old enough not to stamp the attribute.
|
|
989
|
+
// src="/_stx/runtime.<hash>.js" \u2014 with the content sniff behind it for a
|
|
990
|
+
// document rendered by a server old enough not to stamp the attribute.
|
|
991
991
|
function documentShipsRuntime(doc,html){
|
|
992
992
|
if(doc&&doc.querySelector&&doc.querySelector('script[data-stx-runtime]'))return true;
|
|
993
993
|
return html.indexOf("'use strict';var cloakStyle")!==-1
|
|
@@ -998,6 +998,22 @@ function getRouterScript() {
|
|
|
998
998
|
||(code.indexOf('_cleanupContainer')!==-1&&code.indexOf('signals runtime loading')!==-1)
|
|
999
999
|
||code.indexOf("'use strict';var cloakStyle")!==-1;
|
|
1000
1000
|
}
|
|
1001
|
+
// The runtime and the router themselves, as external script tags.
|
|
1002
|
+
//
|
|
1003
|
+
// Serve mode links both by content hash, so after a deploy the incoming
|
|
1004
|
+
// page's copy has a different URL from the one this document loaded. Every
|
|
1005
|
+
// path below that loads a script[src] it has not seen yet would then run a
|
|
1006
|
+
// second router and a second runtime over the live ones \u2014 two click
|
|
1007
|
+
// handlers on every link, a fresh window.stx under scopes created by the
|
|
1008
|
+
// old one. A new version is picked up by the build-skew reload instead; it
|
|
1009
|
+
// is never loaded into a running page. The attrs form is for the fragment
|
|
1010
|
+
// path, which sees a tag as text.
|
|
1011
|
+
function isSharedClientScript(el){
|
|
1012
|
+
return !!(el&&el.hasAttribute&&(el.hasAttribute('data-stx-runtime')||el.hasAttribute('data-stx-router')));
|
|
1013
|
+
}
|
|
1014
|
+
function isSharedClientScriptAttrs(attrs){
|
|
1015
|
+
return /(?:^|\\s)data-stx-(?:runtime|router)(?:[\\s=]|$)/i.test(attrs||'');
|
|
1016
|
+
}
|
|
1001
1017
|
// A fragment never carries the signals runtime: the server strips the runtime
|
|
1002
1018
|
// IIFE out of it, and every re-execution path here filters it out again. So a
|
|
1003
1019
|
// page that never needed a runtime cannot hydrate a fragment that does \u2014 the
|
|
@@ -1554,7 +1570,7 @@ else {
|
|
|
1554
1570
|
// file is where the page's factory usually lives.
|
|
1555
1571
|
var srcMatch=attrs.match(/\\bsrc\\s*=\\s*(?:"([^"]*)"|'([^']*)'|([^\\s>]+))/i);
|
|
1556
1572
|
var fragSrc=srcMatch&&(srcMatch[1]||srcMatch[2]||srcMatch[3]);
|
|
1557
|
-
if(fragSrc){fragExternalScripts.push(fragSrc);return ''}
|
|
1573
|
+
if(fragSrc){if(!isSharedClientScriptAttrs(attrs))fragExternalScripts.push(fragSrc);return ''}
|
|
1558
1574
|
if(code&&code.trim()&&!isSignalsRuntimeScript({hasAttribute:function(name){return name==='data-stx-runtime'&&attrs.indexOf('data-stx-runtime')!==-1}},code)){
|
|
1559
1575
|
var slot='fragment-'+(++fragScriptId);
|
|
1560
1576
|
var scoped=/(?:^|\\s)data-stx-scoped(?:\\s|=|$)/i.test(attrs);
|
|
@@ -1902,7 +1918,8 @@ else {
|
|
|
1902
1918
|
var text=s.textContent||'';
|
|
1903
1919
|
// Not discarded: queued against docBase, so a relative src resolves
|
|
1904
1920
|
// against the page being navigated to rather than the current URL.
|
|
1905
|
-
|
|
1921
|
+
// The runtime and router are dropped, not queued: see isSharedClientScript.
|
|
1922
|
+
if(s.hasAttribute('src')){if(!isSharedClientScript(s))routedExternalScripts.push(s.getAttribute('src'));s.remove();return}
|
|
1906
1923
|
var type=(s.getAttribute('type')||'').trim().toLowerCase();
|
|
1907
1924
|
var executable=!type||type==='text/javascript'||type==='application/javascript'||type==='module';
|
|
1908
1925
|
if(!executable||!text.trim())return;
|
|
@@ -1959,6 +1976,7 @@ else {
|
|
|
1959
1976
|
document.querySelectorAll('head script[src]').forEach(function(s){loadedSrcs[s.src]=1});
|
|
1960
1977
|
var extPromises=[];
|
|
1961
1978
|
doc.querySelectorAll('head script[src]').forEach(function(s){
|
|
1979
|
+
if(isSharedClientScript(s))return;
|
|
1962
1980
|
// Fetched-document script: resolve against the page being navigated to
|
|
1963
1981
|
// (docBase), not the origin root \u2014 same rationale as the <link> reconcile (#1777).
|
|
1964
1982
|
var src=new URL(s.getAttribute('src'),docBase).href;
|
package/dist/serve.d.ts
CHANGED
|
@@ -99,6 +99,23 @@ export declare function isProductionServe(): boolean;
|
|
|
99
99
|
* given URL, so it gets the long immutable lifetime.
|
|
100
100
|
*/
|
|
101
101
|
export declare function staticCacheControl(pathname: string, production?: boolean): string;
|
|
102
|
+
/**
|
|
103
|
+
* `Cache-Control` for the shared runtime and router scripts.
|
|
104
|
+
*
|
|
105
|
+
* Pages link them by content hash (getServeClientAsset), so a request whose
|
|
106
|
+
* hash is the current content's can never see different bytes under that URL:
|
|
107
|
+
* cache it for a year.
|
|
108
|
+
*
|
|
109
|
+
* Anything else is answered with today's content but must not be kept. The
|
|
110
|
+
* unhashed URL is what HTML rendered before content addressing still points
|
|
111
|
+
* at, and a stale hash is a page from the previous deploy; either one caching
|
|
112
|
+
* the current bytes would pin them there. `no-cache`, not a short max-age:
|
|
113
|
+
* Cloudflare raises a max-age below its browser-TTL setting (four hours by
|
|
114
|
+
* default) to that setting, which is exactly how the old fixed URL served a
|
|
115
|
+
* previous release's router for hours after a deploy. It leaves `no-cache`
|
|
116
|
+
* alone, and the ETag keeps the revalidation to a 304.
|
|
117
|
+
*/
|
|
118
|
+
export declare function sharedScriptCacheControl(requestedHash: string | undefined, currentHash: string): string;
|
|
102
119
|
/**
|
|
103
120
|
* Render the built-in fallback 404 page.
|
|
104
121
|
*
|
|
@@ -170,6 +187,8 @@ export declare function serve(options: ServeOptions): Promise<void>;
|
|
|
170
187
|
* is the name every double-submit implementation in this ecosystem uses.
|
|
171
188
|
*/
|
|
172
189
|
export declare const CSRF_COOKIE: 'X-CSRF-Token';
|
|
190
|
+
/** `/_stx/runtime.js`, `/_stx/router.<16 hex>.js`, … — the shared client scripts. */
|
|
191
|
+
export declare const SHARED_SCRIPT_PATH: unknown;
|
|
173
192
|
/**
|
|
174
193
|
* Build the candidate regexes for a dynamic route file (stacksjs/stx#1927).
|
|
175
194
|
*
|
package/dist/serve.js
CHANGED
|
@@ -8940,6 +8940,10 @@ function staticCacheControl(pathname, production = isProductionServe()) {
|
|
|
8940
8940
|
const fingerprinted = /[.-][0-9a-f]{8,}\.[a-z0-9]+$/i.test(pathname);
|
|
8941
8941
|
return fingerprinted ? "public, max-age=31536000, immutable" : "public, max-age=3600";
|
|
8942
8942
|
}
|
|
8943
|
+
var SHARED_SCRIPT_PATH = /^\/_stx\/(runtime|router)(?:\.([0-9a-f]{16}))?\.js$/;
|
|
8944
|
+
function sharedScriptCacheControl(requestedHash, currentHash) {
|
|
8945
|
+
return requestedHash === currentHash ? "public, max-age=31536000, immutable" : "no-cache";
|
|
8946
|
+
}
|
|
8943
8947
|
function render404Page(opts) {
|
|
8944
8948
|
const { path, routes = [], isProduction } = opts;
|
|
8945
8949
|
const baseStyles = `
|
|
@@ -9700,7 +9704,7 @@ function __stxOverlay(errs){
|
|
|
9700
9704
|
pageMiddlewarePatterns.length = 0;
|
|
9701
9705
|
await Promise.all(files.map((f) => detectPageMiddleware(f)));
|
|
9702
9706
|
try {
|
|
9703
|
-
const { Router } = await import("./chunk-
|
|
9707
|
+
const { Router } = await import("./chunk-awcgpf66.js");
|
|
9704
9708
|
const pagesDirs = patterns.map((p) => p.replace(/\/$/, "")).filter(Boolean);
|
|
9705
9709
|
const router = new Router(process19.cwd(), { pagesDirs, stateDir: stateDirName() });
|
|
9706
9710
|
if (!options.quiet)
|
|
@@ -10427,13 +10431,15 @@ ${block}`;
|
|
|
10427
10431
|
}
|
|
10428
10432
|
});
|
|
10429
10433
|
}
|
|
10430
|
-
|
|
10434
|
+
const sharedScript = path.match(SHARED_SCRIPT_PATH);
|
|
10435
|
+
if (sharedScript) {
|
|
10431
10436
|
const stx = await stxModule;
|
|
10432
|
-
const
|
|
10433
|
-
const
|
|
10437
|
+
const asset = await stx.getServeClientAsset(sharedScript[1], sharedScript[1] === "runtime" && stxConfig.debug === true);
|
|
10438
|
+
const content2 = asset.content;
|
|
10439
|
+
const etag = `"${asset.hash}"`;
|
|
10434
10440
|
const headers = {
|
|
10435
10441
|
"Content-Type": "application/javascript; charset=utf-8",
|
|
10436
|
-
"Cache-Control":
|
|
10442
|
+
"Cache-Control": sharedScriptCacheControl(sharedScript[2], asset.hash),
|
|
10437
10443
|
ETag: etag,
|
|
10438
10444
|
...corsHeaders
|
|
10439
10445
|
};
|
|
@@ -11090,6 +11096,7 @@ if (import.meta.main) {
|
|
|
11090
11096
|
export {
|
|
11091
11097
|
usableErrorPage,
|
|
11092
11098
|
staticCacheControl,
|
|
11099
|
+
sharedScriptCacheControl,
|
|
11093
11100
|
serve,
|
|
11094
11101
|
routeSpecificity,
|
|
11095
11102
|
resolveServeOpenUrl,
|
|
@@ -11105,5 +11112,6 @@ export {
|
|
|
11105
11112
|
bundleBrowserAsset,
|
|
11106
11113
|
buildDynamicRouteRegexes,
|
|
11107
11114
|
boundedCache,
|
|
11115
|
+
SHARED_SCRIPT_PATH,
|
|
11108
11116
|
CSRF_COOKIE
|
|
11109
11117
|
};
|
package/package.json
CHANGED