@stacksjs/stx 0.2.364 → 0.2.365

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.
Files changed (57) hide show
  1. package/dist/{chunk-nfwtms2p.js → chunk-0t0b5yex.js} +1 -1
  2. package/dist/{chunk-t0e193kb.js → chunk-0thch80p.js} +1 -1
  3. package/dist/{chunk-wzebxbek.js → chunk-11v2ysbe.js} +1 -1
  4. package/dist/{chunk-yyxgghm5.js → chunk-1nv116m3.js} +1 -1
  5. package/dist/{chunk-23ftyfcz.js → chunk-1q2b0r3v.js} +1 -1
  6. package/dist/{chunk-c6b161h9.js → chunk-2aqq5j7c.js} +1 -1
  7. package/dist/{chunk-jq4h14y6.js → chunk-346jyc33.js} +1 -1
  8. package/dist/{chunk-whywmp6c.js → chunk-4dzsp35z.js} +1 -1
  9. package/dist/{chunk-8qp89yt9.js → chunk-5qs1t2cd.js} +1 -1
  10. package/dist/{chunk-4v04zysj.js → chunk-5t826ypq.js} +1 -1
  11. package/dist/{chunk-6xmkzx0a.js → chunk-6njr31wk.js} +1 -1
  12. package/dist/{chunk-p6avvxkg.js → chunk-6tk817fg.js} +1 -1
  13. package/dist/{chunk-s5qkcz77.js → chunk-77g77ygz.js} +1 -1
  14. package/dist/{chunk-asxfek33.js → chunk-7ptewn2w.js} +2 -2
  15. package/dist/{chunk-yectvv7c.js → chunk-7yyfbhna.js} +1 -1
  16. package/dist/{chunk-ddsfdbwt.js → chunk-8zdq8kk5.js} +1 -1
  17. package/dist/{chunk-7tp3zk2s.js → chunk-a47e67th.js} +1 -1
  18. package/dist/{chunk-08pf5tmf.js → chunk-atf4tj9y.js} +1 -1
  19. package/dist/{chunk-0d96p1my.js → chunk-bh1m0x85.js} +1 -1
  20. package/dist/{chunk-dj0c80w1.js → chunk-bszp4vx1.js} +1 -1
  21. package/dist/{chunk-2gkbht81.js → chunk-bxnx8sga.js} +1 -1
  22. package/dist/{chunk-wbwfsp44.js → chunk-czzy14fj.js} +48 -29
  23. package/dist/{chunk-wsqbnhcy.js → chunk-d5r4zwyd.js} +8 -8
  24. package/dist/{chunk-6xy59d9x.js → chunk-dk40tcv1.js} +1 -1
  25. package/dist/{chunk-6gns8q1a.js → chunk-eczq4cxz.js} +1 -1
  26. package/dist/{chunk-drk5v3wn.js → chunk-g63sh9bx.js} +1 -1
  27. package/dist/{chunk-7wvvzame.js → chunk-hyrm54da.js} +1 -1
  28. package/dist/{chunk-5qe5amz6.js → chunk-jerrq5k1.js} +1 -1
  29. package/dist/{chunk-y1vw94q2.js → chunk-k10f0c00.js} +1 -1
  30. package/dist/{chunk-3dkv2bqc.js → chunk-k3ktx8w2.js} +1 -1
  31. package/dist/{chunk-89c03r0q.js → chunk-kmd694ky.js} +2 -2
  32. package/dist/{chunk-bfecmzpa.js → chunk-mks2cgty.js} +1 -1
  33. package/dist/{chunk-szbgwctn.js → chunk-n5791wn3.js} +1 -1
  34. package/dist/{chunk-8zw9npx5.js → chunk-p33qyhtc.js} +1 -1
  35. package/dist/{chunk-gerew7rz.js → chunk-p8nasx5y.js} +1 -1
  36. package/dist/{chunk-zk0enyyh.js → chunk-pbt7f5h9.js} +1 -1
  37. package/dist/{chunk-7nf8tw22.js → chunk-q28ekhhb.js} +2 -2
  38. package/dist/{chunk-3xt912sq.js → chunk-r5dta1qf.js} +16 -16
  39. package/dist/{chunk-ck4n9zkv.js → chunk-r8hr3jhh.js} +1 -1
  40. package/dist/{chunk-rw0j25b8.js → chunk-ry56srm9.js} +1 -1
  41. package/dist/{chunk-e8nxcfp3.js → chunk-se8fh272.js} +1 -1
  42. package/dist/{chunk-h6jnte7x.js → chunk-syy0njsk.js} +1 -1
  43. package/dist/{chunk-tan44cyf.js → chunk-tfnq0cj6.js} +1 -1
  44. package/dist/{chunk-d8n3wqgy.js → chunk-ttw7qrz0.js} +1 -1
  45. package/dist/{chunk-8b5cwheg.js → chunk-v8ccphfs.js} +1 -1
  46. package/dist/{chunk-ec8pyr0w.js → chunk-wkeymrkg.js} +1 -1
  47. package/dist/{chunk-85tvgy7c.js → chunk-xr8ergcp.js} +1 -1
  48. package/dist/{chunk-md0h8d2h.js → chunk-y3ns6824.js} +1 -1
  49. package/dist/{chunk-xh55b3m0.js → chunk-z274qgsn.js} +1 -1
  50. package/dist/{chunk-bkeszcra.js → chunk-zjqw2fde.js} +1 -1
  51. package/dist/cli.js +8 -8
  52. package/dist/craft-entry.js +1 -1
  53. package/dist/craft.js +1 -1
  54. package/dist/pwa.js +1 -1
  55. package/dist/signals.js +48 -29
  56. package/dist/ssg.js +2 -2
  57. package/package.json +5 -5
package/dist/pwa.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // @bun
2
2
  import{Gk as wq,Hk as dq,Ik as Cq,Jk as mq,Kk as gq}from"./chunk-kaet6r9w.js";import{Lk as S,Mk as Tq,Nk as _q,Ok as z,Pk as D,Qk as P,Rk as kq,Sk as vq,Tk as w,Uk as Iq,Vk as d,Wk as Hq,Xk as Oq,Yk as Mq}from"./chunk-7wj5je2t.js";import{Jw as Aq,Kw as bq,Lw as Sq,Mw as zq,Nw as Dq,Ow as Pq}from"./chunk-vsqx756d.js";import{Sw as N}from"./chunk-m8kem5ca.js";import p from"fs";import E from"path";import C from"fs";import L from"path";var k=[72,96,128,144,152,192,384,512],v=[120,152,167,180],I=[16,32];async function H(G,B){let q={success:!0,generatedFiles:[],errors:[],warnings:[]},K=G.pwa?.icons;if(!K?.src)return q.errors.push("No source icon specified in pwa.icons.src"),q.success=!1,q;let Y=L.isAbsolute(K.src)?K.src:L.resolve(process.cwd(),K.src);if(!await Bun.file(Y).exists())return q.errors.push(`Source icon not found: ${Y}`),q.success=!1,q;let Q=L.resolve(B,K.outputDir||"pwa-icons");try{C.mkdirSync(Q,{recursive:!0})}catch{return q.errors.push(`Failed to create output directory: ${Q}`),q.success=!1,q}let X=K.sizes||k,j=K.generateWebP??!0,J=K.generateAppleIcons??!0;try{let y;try{y=await import("sharp")}catch{return q.errors.push(`sharp is not installed. Install it with: bun add sharp
3
- Icon generation requires the sharp package for image processing.`),q.success=!1,q}let R=await y.default(Y).metadata();if(R.width&&R.width<512)q.warnings.push(`Source icon is ${R.width}x${R.height}. Recommend using at least 512x512 for best quality.`);for(let $ of X){let x=L.join(Q,`icon-${$}x${$}.png`);if(await y.default(Y).resize($,$,{fit:"contain",background:{r:0,g:0,b:0,alpha:0}}).png().toFile(x),q.generatedFiles.push(x),j){let F=L.join(Q,`icon-${$}x${$}.webp`);await y.default(Y).resize($,$,{fit:"contain",background:{r:0,g:0,b:0,alpha:0}}).webp({quality:90}).toFile(F),q.generatedFiles.push(F)}}if(J){for(let x of v){let F=L.join(Q,`apple-touch-icon-${x}x${x}.png`);await y.default(Y).resize(x,x,{fit:"contain",background:{r:255,g:255,b:255,alpha:1}}).png().toFile(F),q.generatedFiles.push(F)}let $=L.join(Q,"apple-touch-icon.png");await y.default(Y).resize(180,180,{fit:"contain",background:{r:255,g:255,b:255,alpha:1}}).png().toFile($),q.generatedFiles.push($)}for(let $ of I){let x=L.join(Q,`favicon-${$}x${$}.png`);await y.default(Y).resize($,$,{fit:"contain",background:{r:0,g:0,b:0,alpha:0}}).png().toFile(x),q.generatedFiles.push(x)}let U=512,T=L.join(Q,`icon-maskable-${U}x${U}.png`),Z=Math.floor(U*0.1),_=U-Z*2;await y.default(Y).resize(_,_,{fit:"contain",background:{r:0,g:0,b:0,alpha:0}}).extend({top:Z,bottom:Z,left:Z,right:Z,background:{r:255,g:255,b:255,alpha:1}}).png().toFile(T),q.generatedFiles.push(T)}catch(y){let V=y instanceof Error?y.message:String(y);q.errors.push(`Icon generation failed: ${V}`),q.success=!1}return q}function n(G){let B=G.sizes||k,q=G.outputDir?`/${G.outputDir}`:"/pwa-icons",K=G.generateWebP??!0,Y=G.generateAppleIcons??!0,Q=[];for(let X of B)if(Q.push(`${q}/icon-${X}x${X}.png`),K)Q.push(`${q}/icon-${X}x${X}.webp`);if(Y){Q.push(`${q}/apple-touch-icon.png`);for(let X of v)Q.push(`${q}/apple-touch-icon-${X}x${X}.png`)}for(let X of I)Q.push(`${q}/favicon-${X}x${X}.png`);return Q.push(`${q}/icon-maskable-512x512.png`),Q}async function O(){try{return await import("sharp"),!0}catch{return!1}}function m(G,B,q,K){let Y=[],Q=K.join(" ");for(let X of G)if(Y.push({src:`${B}/icon-${X}x${X}.png`,sizes:`${X}x${X}`,type:"image/png",purpose:Q}),q)Y.push({src:`${B}/icon-${X}x${X}.webp`,sizes:`${X}x${X}`,type:"image/webp",purpose:Q});return Y}function g(G){return G.map((B)=>({name:B.name,short_name:B.shortName,description:B.description,url:B.url,icons:B.icons?.map((q)=>({src:q.src,sizes:q.sizes,type:q.type}))}))}function h(G){let B=G.pwa?.shareTarget;if(!B?.enabled)return;let q={action:B.action||"/share",method:B.method||"POST",enctype:B.enctype||"multipart/form-data",params:{title:B.params?.title||"title",text:B.params?.text||"text",url:B.params?.url||"url"}};if(B.acceptFiles&&B.acceptFiles.length>0)q.params.files=B.acceptFiles.map((K)=>({name:K.name,accept:K.accept}));return q}function c(G){let B=G.pwa?.fileHandlers;if(!B?.enabled||!B.accept)return;let q=[{action:B.action||"/",accept:B.accept,launch_type:B.launchType||"single-client"}];if(B.icons)q[0].icons=B.icons.map((K)=>({src:K.src,sizes:K.sizes,type:K.type}));return q}function l(G){let B=G.pwa?.protocolHandlers;if(!B||B.length===0)return;return B.map((q)=>({protocol:q.protocol,url:q.url}))}function u(G){let B=G.pwa;if(!B?.enabled||!B.manifest)return null;let{manifest:q,icons:K}=B,Y=K?.sizes||[72,96,128,144,152,192,384,512],Q=K?.outputDir?`/${K.outputDir}`:"/pwa-icons",X=K?.generateWebP??!0,j=K?.purpose||["any","maskable"],J={name:q.name,short_name:q.shortName||q.name,description:q.description,start_url:q.startUrl||"/",display:q.display||"standalone",display_override:q.displayOverride,orientation:q.orientation,theme_color:q.themeColor,background_color:q.backgroundColor,scope:q.scope||"/",lang:q.lang,dir:q.dir,id:q.id,categories:q.categories,icons:m(Y,Q,X,j)};if(q.shortcuts&&q.shortcuts.length>0)J.shortcuts=g(q.shortcuts);if(q.screenshots&&q.screenshots.length>0)J.screenshots=q.screenshots.map((U)=>({src:U.src,sizes:U.sizes,type:U.type,label:U.label,form_factor:U.platform}));let y=h(G);if(y)J.share_target=y;let V=c(G);if(V)J.file_handlers=V;let R=l(G);if(R)J.protocol_handlers=R;if(q.launchHandler)J.launch_handler={client_mode:q.launchHandler};if(q.handleLinks)J.handle_links=q.handleLinks;if(q.edgeSidePanel?.enabled)J.edge_side_panel={preferred_width:q.edgeSidePanel.preferredWidth};return J}function M(G){let B=u(G);if(!B)return"";let q=JSON.parse(JSON.stringify(B));return JSON.stringify(q,null,2)}function i(G,B){return{...B,...G,shortcuts:G.shortcuts||B.shortcuts,screenshots:G.screenshots||B.screenshots,categories:G.categories||B.categories}}function s(G){let B=[],q=G.pwa;if(!q?.enabled)return B;let K=q.manifest;if(!K)return B.push("PWA manifest configuration is missing"),B;if(!K.name)B.push("Manifest name is required");let Y=["fullscreen","standalone","minimal-ui","browser"];if(K.display&&!Y.includes(K.display))B.push(`Invalid display mode: ${K.display}. Must be one of: ${Y.join(", ")}`);let Q=["any","natural","landscape","landscape-primary","landscape-secondary","portrait","portrait-primary","portrait-secondary"];if(K.orientation&&!Q.includes(K.orientation))B.push(`Invalid orientation: ${K.orientation}`);let X=/^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$/;if(K.themeColor&&!X.test(K.themeColor))B.push(`Invalid theme color: ${K.themeColor}. Must be a valid hex color.`);if(K.backgroundColor&&!X.test(K.backgroundColor))B.push(`Invalid background color: ${K.backgroundColor}. Must be a valid hex color.`);if(q.shareTarget?.enabled){if(!q.shareTarget.action)B.push("Share target action URL is required")}if(q.fileHandlers?.enabled){if(!q.fileHandlers.accept||Object.keys(q.fileHandlers.accept).length===0)B.push("File handlers must specify accepted MIME types")}if(q.protocolHandlers)for(let j of q.protocolHandlers){if(!j.protocol)B.push("Protocol handler missing protocol");if(!j.url||!j.url.includes("%s"))B.push(`Protocol handler URL must contain %s placeholder: ${j.protocol}`)}return B}import A from"path";async function b(G){let B=G.pwa?.offline;if(!B?.enabled)return"";if(B.page){let q=A.isAbsolute(B.page)?B.page:A.resolve(process.cwd(),B.page);if(await Bun.file(q).exists())try{let{processDirectives:K}=await import("./chunk-3dkv2bqc.js"),Y=await Bun.file(q).text();return await K(Y,{},q,G,new Set)}catch(K){console.warn(`[PWA] Failed to process custom offline page: ${K}`)}else console.warn(`[PWA] Custom offline page not found: ${q}`)}return f(G)}function f(G){let B=G.pwa?.offline,q=G.pwa?.manifest,K=B?.fallbackTitle||"You are offline",Y=B?.fallbackMessage||"Please check your internet connection and try again.",Q=q?.themeColor||"#4f46e5",X=q?.shortName||q?.name||"App";return`<!DOCTYPE html>
3
+ Icon generation requires the sharp package for image processing.`),q.success=!1,q}let R=await y.default(Y).metadata();if(R.width&&R.width<512)q.warnings.push(`Source icon is ${R.width}x${R.height}. Recommend using at least 512x512 for best quality.`);for(let $ of X){let x=L.join(Q,`icon-${$}x${$}.png`);if(await y.default(Y).resize($,$,{fit:"contain",background:{r:0,g:0,b:0,alpha:0}}).png().toFile(x),q.generatedFiles.push(x),j){let F=L.join(Q,`icon-${$}x${$}.webp`);await y.default(Y).resize($,$,{fit:"contain",background:{r:0,g:0,b:0,alpha:0}}).webp({quality:90}).toFile(F),q.generatedFiles.push(F)}}if(J){for(let x of v){let F=L.join(Q,`apple-touch-icon-${x}x${x}.png`);await y.default(Y).resize(x,x,{fit:"contain",background:{r:255,g:255,b:255,alpha:1}}).png().toFile(F),q.generatedFiles.push(F)}let $=L.join(Q,"apple-touch-icon.png");await y.default(Y).resize(180,180,{fit:"contain",background:{r:255,g:255,b:255,alpha:1}}).png().toFile($),q.generatedFiles.push($)}for(let $ of I){let x=L.join(Q,`favicon-${$}x${$}.png`);await y.default(Y).resize($,$,{fit:"contain",background:{r:0,g:0,b:0,alpha:0}}).png().toFile(x),q.generatedFiles.push(x)}let U=512,T=L.join(Q,`icon-maskable-${U}x${U}.png`),Z=Math.floor(U*0.1),_=U-Z*2;await y.default(Y).resize(_,_,{fit:"contain",background:{r:0,g:0,b:0,alpha:0}}).extend({top:Z,bottom:Z,left:Z,right:Z,background:{r:255,g:255,b:255,alpha:1}}).png().toFile(T),q.generatedFiles.push(T)}catch(y){let V=y instanceof Error?y.message:String(y);q.errors.push(`Icon generation failed: ${V}`),q.success=!1}return q}function n(G){let B=G.sizes||k,q=G.outputDir?`/${G.outputDir}`:"/pwa-icons",K=G.generateWebP??!0,Y=G.generateAppleIcons??!0,Q=[];for(let X of B)if(Q.push(`${q}/icon-${X}x${X}.png`),K)Q.push(`${q}/icon-${X}x${X}.webp`);if(Y){Q.push(`${q}/apple-touch-icon.png`);for(let X of v)Q.push(`${q}/apple-touch-icon-${X}x${X}.png`)}for(let X of I)Q.push(`${q}/favicon-${X}x${X}.png`);return Q.push(`${q}/icon-maskable-512x512.png`),Q}async function O(){try{return await import("sharp"),!0}catch{return!1}}function m(G,B,q,K){let Y=[],Q=K.join(" ");for(let X of G)if(Y.push({src:`${B}/icon-${X}x${X}.png`,sizes:`${X}x${X}`,type:"image/png",purpose:Q}),q)Y.push({src:`${B}/icon-${X}x${X}.webp`,sizes:`${X}x${X}`,type:"image/webp",purpose:Q});return Y}function g(G){return G.map((B)=>({name:B.name,short_name:B.shortName,description:B.description,url:B.url,icons:B.icons?.map((q)=>({src:q.src,sizes:q.sizes,type:q.type}))}))}function h(G){let B=G.pwa?.shareTarget;if(!B?.enabled)return;let q={action:B.action||"/share",method:B.method||"POST",enctype:B.enctype||"multipart/form-data",params:{title:B.params?.title||"title",text:B.params?.text||"text",url:B.params?.url||"url"}};if(B.acceptFiles&&B.acceptFiles.length>0)q.params.files=B.acceptFiles.map((K)=>({name:K.name,accept:K.accept}));return q}function c(G){let B=G.pwa?.fileHandlers;if(!B?.enabled||!B.accept)return;let q=[{action:B.action||"/",accept:B.accept,launch_type:B.launchType||"single-client"}];if(B.icons)q[0].icons=B.icons.map((K)=>({src:K.src,sizes:K.sizes,type:K.type}));return q}function l(G){let B=G.pwa?.protocolHandlers;if(!B||B.length===0)return;return B.map((q)=>({protocol:q.protocol,url:q.url}))}function u(G){let B=G.pwa;if(!B?.enabled||!B.manifest)return null;let{manifest:q,icons:K}=B,Y=K?.sizes||[72,96,128,144,152,192,384,512],Q=K?.outputDir?`/${K.outputDir}`:"/pwa-icons",X=K?.generateWebP??!0,j=K?.purpose||["any","maskable"],J={name:q.name,short_name:q.shortName||q.name,description:q.description,start_url:q.startUrl||"/",display:q.display||"standalone",display_override:q.displayOverride,orientation:q.orientation,theme_color:q.themeColor,background_color:q.backgroundColor,scope:q.scope||"/",lang:q.lang,dir:q.dir,id:q.id,categories:q.categories,icons:m(Y,Q,X,j)};if(q.shortcuts&&q.shortcuts.length>0)J.shortcuts=g(q.shortcuts);if(q.screenshots&&q.screenshots.length>0)J.screenshots=q.screenshots.map((U)=>({src:U.src,sizes:U.sizes,type:U.type,label:U.label,form_factor:U.platform}));let y=h(G);if(y)J.share_target=y;let V=c(G);if(V)J.file_handlers=V;let R=l(G);if(R)J.protocol_handlers=R;if(q.launchHandler)J.launch_handler={client_mode:q.launchHandler};if(q.handleLinks)J.handle_links=q.handleLinks;if(q.edgeSidePanel?.enabled)J.edge_side_panel={preferred_width:q.edgeSidePanel.preferredWidth};return J}function M(G){let B=u(G);if(!B)return"";let q=JSON.parse(JSON.stringify(B));return JSON.stringify(q,null,2)}function i(G,B){return{...B,...G,shortcuts:G.shortcuts||B.shortcuts,screenshots:G.screenshots||B.screenshots,categories:G.categories||B.categories}}function s(G){let B=[],q=G.pwa;if(!q?.enabled)return B;let K=q.manifest;if(!K)return B.push("PWA manifest configuration is missing"),B;if(!K.name)B.push("Manifest name is required");let Y=["fullscreen","standalone","minimal-ui","browser"];if(K.display&&!Y.includes(K.display))B.push(`Invalid display mode: ${K.display}. Must be one of: ${Y.join(", ")}`);let Q=["any","natural","landscape","landscape-primary","landscape-secondary","portrait","portrait-primary","portrait-secondary"];if(K.orientation&&!Q.includes(K.orientation))B.push(`Invalid orientation: ${K.orientation}`);let X=/^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$/;if(K.themeColor&&!X.test(K.themeColor))B.push(`Invalid theme color: ${K.themeColor}. Must be a valid hex color.`);if(K.backgroundColor&&!X.test(K.backgroundColor))B.push(`Invalid background color: ${K.backgroundColor}. Must be a valid hex color.`);if(q.shareTarget?.enabled){if(!q.shareTarget.action)B.push("Share target action URL is required")}if(q.fileHandlers?.enabled){if(!q.fileHandlers.accept||Object.keys(q.fileHandlers.accept).length===0)B.push("File handlers must specify accepted MIME types")}if(q.protocolHandlers)for(let j of q.protocolHandlers){if(!j.protocol)B.push("Protocol handler missing protocol");if(!j.url||!j.url.includes("%s"))B.push(`Protocol handler URL must contain %s placeholder: ${j.protocol}`)}return B}import A from"path";async function b(G){let B=G.pwa?.offline;if(!B?.enabled)return"";if(B.page){let q=A.isAbsolute(B.page)?B.page:A.resolve(process.cwd(),B.page);if(await Bun.file(q).exists())try{let{processDirectives:K}=await import("./chunk-k3ktx8w2.js"),Y=await Bun.file(q).text();return await K(Y,{},q,G,new Set)}catch(K){console.warn(`[PWA] Failed to process custom offline page: ${K}`)}else console.warn(`[PWA] Custom offline page not found: ${q}`)}return f(G)}function f(G){let B=G.pwa?.offline,q=G.pwa?.manifest,K=B?.fallbackTitle||"You are offline",Y=B?.fallbackMessage||"Please check your internet connection and try again.",Q=q?.themeColor||"#4f46e5",X=q?.shortName||q?.name||"App";return`<!DOCTYPE html>
4
4
  <html lang="en">
5
5
  <head>
6
6
  <meta charset="UTF-8">
package/dist/signals.js CHANGED
@@ -154,6 +154,25 @@ console.log('[stx] entering IIFE');
154
154
  // Reactive Core
155
155
  // ==========================================================================
156
156
 
157
+ // Compiled expression functions, by parameter list and body. A binding was
158
+ // compiled with new Function on every evaluation: a page with a few hundred
159
+ // names in scope rebuilt a function of a few hundred parameters for every
160
+ // binding of every row, every time a row re-rendered. Opening a 386-message
161
+ // conversation took seven seconds in WebKit, the window frozen meanwhile.
162
+ // A Function built this way closes over nothing, so one can be reused.
163
+ const __stxCompiled = new Map();
164
+ function __stxCompile(params, body) {
165
+ const key = params.join(',') + '\\x01' + body;
166
+ let fn = __stxCompiled.get(key);
167
+ if (!fn) {
168
+ fn = new Function(...params, body);
169
+ // Bounded: expressions are finite per page, but SPA navigation adds more.
170
+ if (__stxCompiled.size >= 5000) __stxCompiled.clear();
171
+ __stxCompiled.set(key, fn);
172
+ }
173
+ return fn;
174
+ }
175
+
157
176
  let activeEffect = null;
158
177
  const effectStack = [];
159
178
  const pendingEffects = new Set();
@@ -743,7 +762,7 @@ else {
743
762
  // First evaluate the base expression
744
763
  let value;
745
764
  try {
746
- const fn = new Function(...Object.keys(scope), 'return ' + valueExpr);
765
+ const fn = __stxCompile(Object.keys(scope), 'return ' + valueExpr);
747
766
  value = fn(...Object.values(scope));
748
767
  }
749
768
  catch (e) {
@@ -764,7 +783,7 @@ catch (e) {
764
783
  if (/^['"].*['"]$/.test(arg)) return arg.slice(1, -1);
765
784
  // Try to evaluate as expression in scope
766
785
  try {
767
- const fn = new Function(...Object.keys(scope), 'return ' + arg);
786
+ const fn = __stxCompile(Object.keys(scope), 'return ' + arg);
768
787
  return fn(...Object.values(scope));
769
788
  }
770
789
  catch (e) {
@@ -2056,7 +2075,7 @@ finally {
2056
2075
  || expressionUsesSignalApi(expr, prop);
2057
2076
  })
2058
2077
  : baseScope;
2059
- const fn = new Function(...Object.keys(baseScope), 'return ' + expr);
2078
+ const fn = __stxCompile(Object.keys(baseScope), 'return ' + expr);
2060
2079
  const result = fn(...Object.values(scope));
2061
2080
  // Post-eval unwrap \u2014 see evalAttrExpr note for the reason.
2062
2081
  return (result && typeof result === 'function' && (result._isSignal || result._isDerived)) ? result() : result;
@@ -2224,7 +2243,7 @@ catch (e) {
2224
2243
  const v = scope[k];
2225
2244
  handlerScope[k] = (v && typeof v === 'function' && v._isStxLoopItem) ? v() : v;
2226
2245
  });
2227
- const fn = new Function(...Object.keys(handlerScope), '$event', expr);
2246
+ const fn = __stxCompile(Object.keys(handlerScope).concat(['$event']), expr);
2228
2247
  fn(...Object.values(handlerScope), event);
2229
2248
  }
2230
2249
  catch (e) {
@@ -2534,7 +2553,7 @@ catch (e) {
2534
2553
  return expressionCallsSignal(expression, prop)
2535
2554
  || expressionUsesSignalApi(expression, prop);
2536
2555
  });
2537
- var fn = new Function('__scope__', 'with(__scope__) { return (' + expression + ') }');
2556
+ var fn = __stxCompile(['__scope__'], 'with(__scope__) { return (' + expression + ') }');
2538
2557
  value = fn(unwrapScope);
2539
2558
  if (value && typeof value === 'function' && (value._isSignal || value._isDerived)) value = value();
2540
2559
  }
@@ -2742,7 +2761,7 @@ catch (e) {
2742
2761
  var memoExpr = el.getAttribute('data-stx-memo');
2743
2762
  try {
2744
2763
  var memoScope = { ...globalHelpers, ...scope, ...(findElementScope(el) || {}) };
2745
- var memoFn = new Function(...Object.keys(memoScope), 'return ' + memoExpr);
2764
+ var memoFn = __stxCompile(Object.keys(memoScope), 'return ' + memoExpr);
2746
2765
  var memoVals = JSON.stringify(memoFn(...Object.values(memoScope)));
2747
2766
  if (el.__stx_memo_prev === memoVals) {
2748
2767
  return; // Dependencies unchanged \u2014 skip re-processing
@@ -2795,7 +2814,7 @@ catch (e) {
2795
2814
  else {
2796
2815
  // Use auto-unwrap proxy (Feature #1)
2797
2816
  const unwrapScope = createExpressionAutoUnwrapProxy(capturedScope, expr);
2798
- const fn = new Function(...Object.keys(capturedScope), 'return ' + expr);
2817
+ const fn = __stxCompile(Object.keys(capturedScope), 'return ' + expr);
2799
2818
  bindingNode.textContent = fn(...Object.values(unwrapScope));
2800
2819
  }
2801
2820
  }
@@ -2804,7 +2823,7 @@ catch (e) {
2804
2823
  // because it converts the signal to its value before the expression runs.
2805
2824
  // Retry without auto-unwrap so signal functions remain callable.
2806
2825
  try {
2807
- const fn = new Function(...Object.keys(capturedScope), 'return ' + expr);
2826
+ const fn = __stxCompile(Object.keys(capturedScope), 'return ' + expr);
2808
2827
  bindingNode.textContent = fn(...Object.values(capturedScope));
2809
2828
  }
2810
2829
  catch (e2) {
@@ -2921,7 +2940,7 @@ else if (part) {
2921
2940
 
2922
2941
  // Use auto-unwrap proxy (Feature #1)
2923
2942
  const unwrapScope = createExpressionAutoUnwrapProxy(activeScope, expr);
2924
- const fn = new Function('__scope__', 'with(__scope__) { return (' + expr + ') }');
2943
+ const fn = __stxCompile(['__scope__'], 'with(__scope__) { return (' + expr + ') }');
2925
2944
  var value = maybeUnwrapSignal(fn(unwrapScope));
2926
2945
  noteExprSuccess(expr);
2927
2946
  return value;
@@ -2930,7 +2949,7 @@ catch (e) {
2930
2949
  // Auto-unwrap can break explicit signal calls like errorData().message
2931
2950
  // Retry without auto-unwrap so signal functions remain callable
2932
2951
  try {
2933
- const fn = new Function('__scope__', 'with(__scope__) { return (' + expr + ') }');
2952
+ const fn = __stxCompile(['__scope__'], 'with(__scope__) { return (' + expr + ') }');
2934
2953
  var retried = maybeUnwrapSignal(fn(activeScope));
2935
2954
  noteExprSuccess(expr);
2936
2955
  return retried;
@@ -3244,7 +3263,7 @@ else if (name === 'ref' || name === ':ref' || name === 'x-ref' || name === 'data
3244
3263
  return 'if(' + k + ' !== __s["' + k + '"]()) __s["' + k + '"].set(' + k + ')';
3245
3264
  }).join(';');
3246
3265
  var body = getVars + ';' + value + ';' + setVars;
3247
- var fn2 = new Function('__s', '$event', body);
3266
+ var fn2 = __stxCompile(['__s', '$event'], body);
3248
3267
  fn2(eventCapturedScope, handlerEvent);
3249
3268
  } else if (hasSignals) {
3250
3269
  // Function calls with signals in scope keep any signal used through
@@ -3267,10 +3286,10 @@ else if (name === 'ref' || name === ':ref' || name === 'x-ref' || name === 'data
3267
3286
  }
3268
3287
  return 'var ' + k + ' = __s["' + k + '"] && typeof __s["' + k + '"] === "function" && __s["' + k + '"]._isSignal ? __s["' + k + '"]() : __s["' + k + '"]';
3269
3288
  }).join(';');
3270
- var fn3 = new Function('__s', '$event', unwrapVars + ';' + value);
3289
+ var fn3 = __stxCompile(['__s', '$event'], unwrapVars + ';' + value);
3271
3290
  fn3(eventCapturedScope, handlerEvent);
3272
3291
  } else {
3273
- var fn = new Function(...Object.keys(eventCapturedScope), '$event', value);
3292
+ var fn = __stxCompile(Object.keys(eventCapturedScope).concat(['$event']), value);
3274
3293
  fn(...Object.values(eventCapturedScope), handlerEvent);
3275
3294
  }
3276
3295
  }
@@ -3396,13 +3415,13 @@ catch (e) {
3396
3415
  var value;
3397
3416
  try {
3398
3417
  var unwrapScope = createExpressionAutoUnwrapProxy(capturedScope, expr);
3399
- var fn = new Function(...Object.keys(capturedScope), 'return ' + expr);
3418
+ var fn = __stxCompile(Object.keys(capturedScope), 'return ' + expr);
3400
3419
  value = fn(...Object.values(unwrapScope));
3401
3420
  } catch (e1) {
3402
3421
  // Retry without unwrapping \u2014 handles edge cases where the proxy
3403
3422
  // interferes with certain expression patterns
3404
3423
  try {
3405
- var fn2 = new Function(...Object.keys(capturedScope), 'return ' + expr);
3424
+ var fn2 = __stxCompile(Object.keys(capturedScope), 'return ' + expr);
3406
3425
  value = fn2(...Object.values(capturedScope));
3407
3426
  } catch (e2) {
3408
3427
  // Suppress ReferenceError/TypeError during async init \u2014 a signal
@@ -3448,7 +3467,7 @@ catch (e) {
3448
3467
  return direct();
3449
3468
  try {
3450
3469
  var unwrapScope = createExpressionAutoUnwrapProxy(capturedScope, expr);
3451
- var fn = new Function('__scope__', 'with(__scope__) { return (' + expr + ') }');
3470
+ var fn = __stxCompile(['__scope__'], 'with(__scope__) { return (' + expr + ') }');
3452
3471
  return fn(unwrapScope);
3453
3472
  }
3454
3473
  catch (e) {
@@ -3476,7 +3495,7 @@ else {
3476
3495
  // Routing through it also drops the old requirement that every scope
3477
3496
  // key be a valid identifier, since nothing is destructured now.
3478
3497
  var writeScope = createModelWriteProxy(capturedScope);
3479
- var writeFn = new Function('__scope__', '__v__', 'with(__scope__) { ' + expr + ' = __v__ }');
3498
+ var writeFn = __stxCompile(['__scope__', '__v__'], 'with(__scope__) { ' + expr + ' = __v__ }');
3480
3499
  writeFn(writeScope, val);
3481
3500
  }
3482
3501
  }
@@ -3590,7 +3609,7 @@ else {
3590
3609
  const safeKeys = keys.filter(k => /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(k));
3591
3610
  let fn;
3592
3611
  try {
3593
- fn = new Function(...safeKeys, 'return ' + expr);
3612
+ fn = __stxCompile(safeKeys, 'return ' + expr);
3594
3613
  } catch (e) {
3595
3614
  console.warn('[STX] bindClass compile error:', expr, e);
3596
3615
  return;
@@ -3659,12 +3678,12 @@ else {
3659
3678
  // throw TypeError.
3660
3679
  try {
3661
3680
  const unwrapScope = createExpressionAutoUnwrapProxy(capturedScope, expr);
3662
- const fn = new Function(...Object.keys(capturedScope), 'return ' + expr);
3681
+ const fn = __stxCompile(Object.keys(capturedScope), 'return ' + expr);
3663
3682
  return fn(...Object.values(unwrapScope));
3664
3683
  }
3665
3684
  catch (e1) {
3666
3685
  try {
3667
- const fn2 = new Function(...Object.keys(capturedScope), 'return ' + expr);
3686
+ const fn2 = __stxCompile(Object.keys(capturedScope), 'return ' + expr);
3668
3687
  return fn2(...Object.values(capturedScope));
3669
3688
  }
3670
3689
  catch (e2) {
@@ -4150,7 +4169,7 @@ else {
4150
4169
  return expressionCallsSignal(expression, prop)
4151
4170
  || expressionUsesSignalApi(expression, prop);
4152
4171
  });
4153
- const fn = new Function(...Object.keys(scope), 'return ' + expression);
4172
+ const fn = __stxCompile(Object.keys(scope), 'return ' + expression);
4154
4173
  return fn(...Object.values(unwrapScope));
4155
4174
  }
4156
4175
  catch (e) {
@@ -4173,7 +4192,7 @@ catch (e) {
4173
4192
  });
4174
4193
  // new Function body is non-strict, so with() works \u2014 only accessed
4175
4194
  // properties trigger the proxy's get trap and register as dependencies
4176
- const fn = new Function('__scope__', 'with(__scope__) { return ' + expression + ' }');
4195
+ const fn = __stxCompile(['__scope__'], 'with(__scope__) { return ' + expression + ' }');
4177
4196
  return fn(unwrapScope);
4178
4197
  } catch (e) {
4179
4198
  if (!(e instanceof ReferenceError) && !(e instanceof TypeError)) console.warn('[STX] Expression error:', expression, e);
@@ -4268,7 +4287,7 @@ catch (e) {
4268
4287
  try {
4269
4288
  const scope = { [itemName]: item };
4270
4289
  if (indexName) scope[indexName] = index;
4271
- const fn = new Function(itemName, indexName || '_idx', 'return ' + keyExpr);
4290
+ const fn = __stxCompile([itemName, indexName || '_idx'], 'return ' + keyExpr);
4272
4291
  return String(fn(item, index));
4273
4292
  } catch (e) {
4274
4293
  return String(index);
@@ -4691,12 +4710,12 @@ catch (e) {
4691
4710
  try {
4692
4711
  var unwrapScope = createExpressionAutoUnwrapProxy(scope, expression);
4693
4712
  // new Function body is non-strict, so with() works.
4694
- var fn = new Function('__scope__', 'with(__scope__) { return ' + expression + ' }');
4713
+ var fn = __stxCompile(['__scope__'], 'with(__scope__) { return ' + expression + ' }');
4695
4714
  return fn(unwrapScope);
4696
4715
  }
4697
4716
  catch (e1) {
4698
4717
  try {
4699
- var fn2 = new Function('__scope__', 'with(__scope__) { return ' + expression + ' }');
4718
+ var fn2 = __stxCompile(['__scope__'], 'with(__scope__) { return ' + expression + ' }');
4700
4719
  return fn2(scope);
4701
4720
  }
4702
4721
  catch (e2) {
@@ -4940,14 +4959,14 @@ catch (e) { /* a disposer of its own is not this branch's problem */ }
4940
4959
  try {
4941
4960
  const scope = { ...globalHelpers, ...capturedComponentScope, ...(capturedElementScope || {}) };
4942
4961
  const unwrapScope = createExpressionAutoUnwrapProxy(scope, expression);
4943
- const fn = new Function('__scope__', 'with(__scope__) { return ' + expression + ' }');
4962
+ const fn = __stxCompile(['__scope__'], 'with(__scope__) { return ' + expression + ' }');
4944
4963
  return fn(unwrapScope);
4945
4964
  }
4946
4965
  catch (e1) {
4947
4966
  try {
4948
4967
  // Retry without the unwrap proxy so call-syntax (signal()) works.
4949
4968
  const scope2 = { ...globalHelpers, ...capturedComponentScope, ...(capturedElementScope || {}) };
4950
- const fn2 = new Function('__scope__', 'with(__scope__) { return ' + expression + ' }');
4969
+ const fn2 = __stxCompile(['__scope__'], 'with(__scope__) { return ' + expression + ' }');
4951
4970
  return fn2(scope2);
4952
4971
  }
4953
4972
  catch (e2) {
@@ -8240,7 +8259,7 @@ else {
8240
8259
  if (matches) {
8241
8260
  matches.forEach(match => {
8242
8261
  const expr = match.replace(/^\\{\\{\\s*|\\s*\\}\\}$/g, '');
8243
- const fn = new Function(...Object.keys(componentScope), 'return ' + expr);
8262
+ const fn = __stxCompile(Object.keys(componentScope), 'return ' + expr);
8244
8263
  const value = fn(...Object.values(componentScope));
8245
8264
  result = result.replace(match, value != null ? value : '');
8246
8265
  });
@@ -8267,7 +8286,7 @@ else if (el.tagName === 'META') {
8267
8286
  matches.forEach(match => {
8268
8287
  const expr = match.replace(/^\\{\\{\\s*|\\s*\\}\\}$/g, '');
8269
8288
  if (/^__[A-Z_]+__$/.test(expr.trim())) return;
8270
- const fn = new Function(...Object.keys(componentScope), 'return ' + expr);
8289
+ const fn = __stxCompile(Object.keys(componentScope), 'return ' + expr);
8271
8290
  const value = fn(...Object.values(componentScope));
8272
8291
  result = result.replace(match, value != null ? value : '');
8273
8292
  });
package/dist/ssg.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- import{Ck as Fq,xk as Uq,yk as Iq}from"./chunk-necx4e30.js";import{Dk as Eq,Ek as Tq,Fk as Dq}from"./chunk-frp9fc7j.js";import{_k as _q,bl as zq,cl as Aq}from"./chunk-e8nxcfp3.js";import"./chunk-rw0j25b8.js";import"./chunk-qjvny3wf.js";import{Lp as P,Tm as Oq,jo as l,mo as Hq,xr as n}from"./chunk-3xt912sq.js";import"./chunk-jc6wrxrh.js";import"./chunk-2xpdcr8c.js";import"./chunk-v90kxg77.js";import"./chunk-4arms0am.js";import"./chunk-135mme4g.js";import{nt as Xq}from"./chunk-8b5cwheg.js";import{st as d}from"./chunk-w1asc0zd.js";import"./chunk-kd95t585.js";import"./chunk-6xmkzx0a.js";import"./chunk-xk402w4a.js";import{Zt as Bq}from"./chunk-dnard9gp.js";import"./chunk-vgx5077x.js";import"./chunk-met6wtbk.js";import"./chunk-ta6z7k4p.js";import"./chunk-zxptxz2b.js";import"./chunk-7racewc5.js";import{Aw as Lq,Bw as Nq,ww as Yq,xw as Vq,yw as jq,zw as Gq}from"./chunk-e03m4har.js";import"./chunk-vsqx756d.js";import{Sw as y}from"./chunk-m8kem5ca.js";import O from"fs";import j from"path";import{createHash as xq}from"crypto";function yq(q){try{return new Bun.Transpiler({loader:"js",minifyWhitespace:!0}).transformSync(q).replace(/\}(var |let |const |function )/g,"};$1").trim()}catch{return q}}var Pq=/<script\s+type="stx\/island"\s+data-stx-island="([^"]+)"([^>]*)>([\s\S]*?)<\/script>/g;function Cq(q){return Bun.hash(q).toString(16)}function Qq(q,Z={}){if(!q.includes('type="stx/island"'))return{html:q,chunks:[]};let $=new Map,Q=q.replace(Pq,(J,W,z,A)=>{let G=A.trim();if(!G)return J;if(/\bdata-stx-src=/.test(z))return J;if(Z.minify)G=yq(G);let X=Cq(G);if(!$.has(X))$.set(X,G);let B=Z.integrity?` data-stx-integrity="sha384-${xq("sha384").update(G).digest("base64")}"`:"";return`<script type="stx/island" data-stx-island="${W}" data-stx-src="/_stx/islands/${X}.js"${B}${z}></script>`}),K=Array.from($,([J,W])=>({hash:J,code:W}));return{html:Q,chunks:K}}var gq=new Set(["visible","idle"]);function Zq(q){if(!q.includes("data-stx-src="))return q;let Z=new Map,$=/data-stx-scope="([^"]+)"[^>]*?stx-hydrate="([^"]+)"/g,Q;while((Q=$.exec(q))!==null)Z.set(Q[1],Q[2]);let K=new Set,J=/data-stx-island="([^"]+)"[^>]*?data-stx-src="([^"]+)"/g,W;while((W=J.exec(q))!==null)if(gq.has(Z.get(W[1])||""))K.add(W[2]);let z=q.lastIndexOf("</head>");if(K.size===0||z===-1)return q;let A=Array.from(K).filter((G)=>!q.includes(`rel="prefetch" href="${G}"`)).map((G)=>`<link rel="prefetch" href="${G}" as="script">`).join("");if(!A)return q;return q.slice(0,z)+A+q.slice(z)}var fq=["STX_SITE_URL","SITE_URL","URL","VERCEL_URL","CF_PAGES_URL"];function h(q){let Z=q.trim();if(!Z)return null;let $=/^https?:\/\//i.test(Z)?Z:`https://${Z}`;try{return new URL($).origin+new URL($).pathname.replace(/\/$/,"")}catch{return null}}function mq(q){for(let Z of fq){let $=q[Z];if(!$)continue;let Q=h($);if(Q)return{url:Q,source:"env",via:Z}}return null}function $q(q){if(!q||typeof q!=="object")return null;let Z=q,$=Z.site?.url??Z.url??Z.app?.url;return typeof $==="string"?h($):null}async function dq(q){let{existsSync:Z}=await import("fs"),$=await import("path");for(let Q of["site.config.ts","site.config.js",".config/site.config.ts"]){let K=$.resolve(q,Q);if(!Z(K))continue;try{let J=await import(K),W=$q(J.default??J);if(W)return W}catch{}}return null}async function Kq(q={}){let Z=q.cwd??process.cwd(),$=q.env??process.env;if(q.explicit){let W=h(q.explicit);if(W)return{url:W,source:"option"}}let Q=$q(q.stxConfig);if(Q)return{url:Q,source:"stx.config",via:"site.url"};let K=await dq(Z);if(K)return{url:K,source:"site.config",via:"url"};let J=mq($);if(J)return J;return{url:"http://localhost",source:"fallback"}}function Wq(){return["No site URL configured \u2014 sitemap.xml and robots.txt will point at http://localhost."," Set one in stx.config.ts (site: { url: 'https://example.com' }), in site.config.ts,"," via --domain, or with SITE_URL in the build environment."].join(`
2
+ import{Ck as Fq,xk as Uq,yk as Iq}from"./chunk-necx4e30.js";import{Dk as Eq,Ek as Tq,Fk as Dq}from"./chunk-frp9fc7j.js";import{_k as _q,bl as zq,cl as Aq}from"./chunk-se8fh272.js";import"./chunk-ry56srm9.js";import"./chunk-qjvny3wf.js";import{Lp as P,Tm as Oq,jo as l,mo as Hq,xr as n}from"./chunk-r5dta1qf.js";import"./chunk-jc6wrxrh.js";import"./chunk-2xpdcr8c.js";import"./chunk-v90kxg77.js";import"./chunk-4arms0am.js";import"./chunk-135mme4g.js";import{nt as Xq}from"./chunk-v8ccphfs.js";import{st as d}from"./chunk-w1asc0zd.js";import"./chunk-kd95t585.js";import"./chunk-6njr31wk.js";import"./chunk-xk402w4a.js";import{Zt as Bq}from"./chunk-dnard9gp.js";import"./chunk-vgx5077x.js";import"./chunk-met6wtbk.js";import"./chunk-ta6z7k4p.js";import"./chunk-zxptxz2b.js";import"./chunk-7racewc5.js";import{Aw as Lq,Bw as Nq,ww as Yq,xw as Vq,yw as jq,zw as Gq}from"./chunk-e03m4har.js";import"./chunk-vsqx756d.js";import{Sw as y}from"./chunk-m8kem5ca.js";import O from"fs";import j from"path";import{createHash as xq}from"crypto";function yq(q){try{return new Bun.Transpiler({loader:"js",minifyWhitespace:!0}).transformSync(q).replace(/\}(var |let |const |function )/g,"};$1").trim()}catch{return q}}var Pq=/<script\s+type="stx\/island"\s+data-stx-island="([^"]+)"([^>]*)>([\s\S]*?)<\/script>/g;function Cq(q){return Bun.hash(q).toString(16)}function Qq(q,Z={}){if(!q.includes('type="stx/island"'))return{html:q,chunks:[]};let $=new Map,Q=q.replace(Pq,(J,W,z,A)=>{let G=A.trim();if(!G)return J;if(/\bdata-stx-src=/.test(z))return J;if(Z.minify)G=yq(G);let X=Cq(G);if(!$.has(X))$.set(X,G);let B=Z.integrity?` data-stx-integrity="sha384-${xq("sha384").update(G).digest("base64")}"`:"";return`<script type="stx/island" data-stx-island="${W}" data-stx-src="/_stx/islands/${X}.js"${B}${z}></script>`}),K=Array.from($,([J,W])=>({hash:J,code:W}));return{html:Q,chunks:K}}var gq=new Set(["visible","idle"]);function Zq(q){if(!q.includes("data-stx-src="))return q;let Z=new Map,$=/data-stx-scope="([^"]+)"[^>]*?stx-hydrate="([^"]+)"/g,Q;while((Q=$.exec(q))!==null)Z.set(Q[1],Q[2]);let K=new Set,J=/data-stx-island="([^"]+)"[^>]*?data-stx-src="([^"]+)"/g,W;while((W=J.exec(q))!==null)if(gq.has(Z.get(W[1])||""))K.add(W[2]);let z=q.lastIndexOf("</head>");if(K.size===0||z===-1)return q;let A=Array.from(K).filter((G)=>!q.includes(`rel="prefetch" href="${G}"`)).map((G)=>`<link rel="prefetch" href="${G}" as="script">`).join("");if(!A)return q;return q.slice(0,z)+A+q.slice(z)}var fq=["STX_SITE_URL","SITE_URL","URL","VERCEL_URL","CF_PAGES_URL"];function h(q){let Z=q.trim();if(!Z)return null;let $=/^https?:\/\//i.test(Z)?Z:`https://${Z}`;try{return new URL($).origin+new URL($).pathname.replace(/\/$/,"")}catch{return null}}function mq(q){for(let Z of fq){let $=q[Z];if(!$)continue;let Q=h($);if(Q)return{url:Q,source:"env",via:Z}}return null}function $q(q){if(!q||typeof q!=="object")return null;let Z=q,$=Z.site?.url??Z.url??Z.app?.url;return typeof $==="string"?h($):null}async function dq(q){let{existsSync:Z}=await import("fs"),$=await import("path");for(let Q of["site.config.ts","site.config.js",".config/site.config.ts"]){let K=$.resolve(q,Q);if(!Z(K))continue;try{let J=await import(K),W=$q(J.default??J);if(W)return W}catch{}}return null}async function Kq(q={}){let Z=q.cwd??process.cwd(),$=q.env??process.env;if(q.explicit){let W=h(q.explicit);if(W)return{url:W,source:"option"}}let Q=$q(q.stxConfig);if(Q)return{url:Q,source:"stx.config",via:"site.url"};let K=await dq(Z);if(K)return{url:K,source:"site.config",via:"url"};let J=mq($);if(J)return J;return{url:"http://localhost",source:"fallback"}}function Wq(){return["No site URL configured \u2014 sitemap.xml and robots.txt will point at http://localhost."," Set one in stx.config.ts (site: { url: 'https://example.com' }), in site.config.ts,"," via --domain, or with SITE_URL in the build environment."].join(`
3
3
  `)}class wq{cacheDir;cache=new Map;loaded=!1;salt;constructor(q,Z=""){this.cacheDir=q,this.salt=Z}async load(){if(this.loaded)return;let q=j.join(this.cacheDir,"build-cache.json");if(await Bun.file(q).exists())try{let Z=JSON.parse(await Bun.file(q).text());for(let[$,Q]of Object.entries(Z))this.cache.set($,Q)}catch{}this.loaded=!0}async save(){await O.promises.mkdir(this.cacheDir,{recursive:!0});let q=j.join(this.cacheDir,"build-cache.json"),Z={};for(let[$,Q]of this.cache)Z[$]=Q;await Bun.write(q,JSON.stringify(Z))}getHash(q,Z){let $=O.statSync(q),Q=`${this.salt}|${q}:${$.mtimeMs}`;for(let J of Z)if(O.existsSync(J)){let W=O.statSync(J);Q+=`:${J}:${W.mtimeMs}`}let K=0;for(let J=0;J<Q.length;J++){let W=Q.charCodeAt(J);K=(K<<5)-K+W,K=K&K}return Math.abs(K).toString(36)}get(q,Z){let $=this.cache.get(q);if(!$)return null;let Q=this.getHash(Z,$.dependencies??[]);if($.hash!==Q)return this.cache.delete(q),null;return $.html}set(q,Z,$,Q){let K=this.getHash(Z,$);this.cache.set(q,{hash:K,html:Q,generatedAt:Date.now(),dependencies:$})}}class Rq{cacheDir;constructor(q){this.cacheDir=q}getFilePath(q){let Z=q.replace(/[^a-zA-Z0-9]/g,"_")+".json";return j.join(this.cacheDir,"isr",Z)}async get(q){let Z=this.getFilePath(q);if(!await Bun.file(Z).exists())return null;try{return JSON.parse(await Bun.file(Z).text())}catch{return null}}async set(q,Z){let $=this.getFilePath(q);await O.promises.mkdir(j.dirname($),{recursive:!0}),await Bun.write($,JSON.stringify(Z))}async invalidate(q){let Z=this.getFilePath(q);if(await Bun.file(Z).exists())await O.promises.unlink(Z)}async invalidatePattern(q){let Z=j.join(this.cacheDir,"isr");if(!O.existsSync(Z))return;let $=await O.promises.readdir(Z);for(let Q of $){let K=Q.replace(/_/g,"/").replace(".json","");if(q.test(K))await O.promises.unlink(j.join(Z,Q))}}async needsRevalidation(q){let Z=await this.get(q);if(!Z)return!0;return Date.now()>Z.revalidateAfter}}async function pq(q){try{let $=(await Bun.file(q).text()).match(/<script\s+server\b[^>]*>([\s\S]*?)<\/script>/i);if(!$)return null;let Q=$[1];if(!Q.includes("getStaticPaths"))return null;let K=Q.match(/(?:export\s+)?(?:async\s+)?function\s+getStaticPaths\s*\([^)]*\)\s*\{([\s\S]*?)\n[\t ]*\}/);if(!K)return null;return await Function(`
4
4
  return (async function getStaticPaths() {
5
5
  ${K[1]}
@@ -41,7 +41,7 @@ ${q.map((Q)=>{let K=new URL(Q.loc,Z).href,J=` <url>
41
41
  ${$.join(`
42
42
  `)}
43
43
  </channel>
44
- </rss>`}async function aq(q={}){let Z=Date.now();Aq();let $=await n(process.cwd()),Q=$.build||{},K=await Kq({explicit:q.domain||Q.domain,stxConfig:$});if(K.source==="fallback"&&(q.sitemap??Q.sitemap??!0))console.warn(Wq());let J={router:q.router??$?.router??{},pagesDir:q.pagesDir||Q.pagesDir||"pages",outputDir:q.outputDir||Q.outputDir||"dist",baseUrl:q.baseUrl||Q.baseUrl||"/",domain:K.url,revalidate:q.revalidate??Q.revalidate??!1,sitemap:q.sitemap??Q.sitemap??!0,sitemapExclude:q.sitemapExclude||Q.sitemapExclude||[],robots:q.robots??Q.robots??!0,rss:q.rss??Q.rss??!1,concurrency:q.concurrency||Q.concurrency||10,cache:q.cache??Q.cache??!0,cacheDir:q.cacheDir||Q.cacheDir||d(process.cwd(),"ssg-cache"),contentLoaders:q.contentLoaders||[],hooks:q.hooks||{},minify:q.minify??Q.minify??!0,generate404:q.generate404??Q.generate404??!0,publicDir:q.publicDir||Q.publicDir||"public",trailingSlash:q.trailingSlash??Q.trailingSlash??!1,cleanOutput:q.cleanOutput??Q.cleanOutput??!0,cacheSalt:q.cacheSalt??"",partialsDir:q.partialsDir||$?.partialsDir||"",componentsDir:q.componentsDir||$?.componentsDir||"",failOnIncludeError:q.failOnIncludeError??!0,chunkIslands:q.chunkIslands===!0,prefetchIslands:q.prefetchIslands===!0,integrityIslands:q.integrityIslands===!0},W={totalPages:0,successCount:0,failedCount:0,cachedCount:0,buildTime:0,pages:[],errors:[]},z=new Set,A=0,G={},X={};await J.hooks.onBuildStart?.();try{if(J.cleanOutput&&O.existsSync(J.outputDir))await O.promises.rm(J.outputDir,{recursive:!0});await O.promises.mkdir(J.outputDir,{recursive:!0});let L=J.cacheSalt;if(!L){let{resolveUserCssConfig:Y,fingerprintConfig:N}=await import("./chunk-6gns8q1a.js");try{L=N(await Y(process.cwd()))}catch{}}let{prepareImageDelivery:_}=await import("./chunk-pf8575bx.js"),F=await _(J.publicDir,J.outputDir);if(F.count>0)console.log(`Optimized ${F.count} image(s) for responsive delivery`),L=[L,F.fingerprint].filter(Boolean).join(":");let C=new wq(J.cacheDir,L);if(J.cache)await C.load();try{let{generateCss:Y}=await import("./chunk-6gns8q1a.js");await Y('<div class="bg-black"></div>')}catch{}Yq();let kq=$?.routeMiddleware?.dir||"middleware";await jq(process.cwd(),kq);let p=Vq();if(p.length>0)console.log(`Loaded ${p.length} middleware: ${p.join(", ")}`);let bq=$?.routeMiddleware?.global||[];Fq($?.layoutsDir,d(process.cwd()));let i=l(".",{pagesDir:J.pagesDir,pagesDirs:$?._layerPageDirs});console.log(`Found ${i.length} routes`);let g=[];for(let Y of i){let N=await uq(Y);for(let H of N)g.push({route:Y,url:H.url,params:H.params,props:H.props,revalidate:H.revalidate??J.revalidate})}W.totalPages=g.length,console.log(`Generating ${W.totalPages} pages...`);let b=[],s=[];for(let Y=0;Y<g.length;Y+=J.concurrency)s.push(g.slice(Y,Y+J.concurrency));for(let Y of s)await Promise.all(Y.map(async(N)=>{let{route:H,url:V,params:S,props:Sq,revalidate:a}=N;try{await J.hooks.onPageStart?.(V);let w=await Bun.file(H.filePath).text(),R=JJ(w),vq=R?.middleware?Array.isArray(R.middleware)?R.middleware:[R.middleware]:[],t=[...bq,...vq];if(t.length>0){let D=Gq(V,S,R||{}),M=Lq(D,null,void 0,{isServer:!0}),E=await Nq(t,M);if(E.redirect){let U=typeof E.redirect==="string"?E.redirect:E.redirect.path||E.redirect,x=QJ(String(U),V),k=ZJ(V,J);await O.promises.mkdir(j.dirname(k),{recursive:!0}),await Bun.write(k,x),W.successCount++,W.pages.push({route:V,outputPath:k,size:Buffer.byteLength(x),cached:!1}),b.push({loc:V,lastmod:new Date().toISOString()}),console.log(` \u21B3 ${V} \u2192 redirect to ${U}`);return}if(E.abort){let U=typeof E.abort==="string"?E.abort:E.abort?.error?.message||"aborted";console.warn(` \u21B3 ${V} \u2014 middleware aborted: ${U}`);return}}let e=w.match(/definePageMeta\s*\(\s*\{[\s\S]*?validate\s*:\s*((?:\([^)]*\)|[^,}])*(?:\{[\s\S]*?\})?)/m);if(e)try{if(!await Function("route",`
44
+ </rss>`}async function aq(q={}){let Z=Date.now();Aq();let $=await n(process.cwd()),Q=$.build||{},K=await Kq({explicit:q.domain||Q.domain,stxConfig:$});if(K.source==="fallback"&&(q.sitemap??Q.sitemap??!0))console.warn(Wq());let J={router:q.router??$?.router??{},pagesDir:q.pagesDir||Q.pagesDir||"pages",outputDir:q.outputDir||Q.outputDir||"dist",baseUrl:q.baseUrl||Q.baseUrl||"/",domain:K.url,revalidate:q.revalidate??Q.revalidate??!1,sitemap:q.sitemap??Q.sitemap??!0,sitemapExclude:q.sitemapExclude||Q.sitemapExclude||[],robots:q.robots??Q.robots??!0,rss:q.rss??Q.rss??!1,concurrency:q.concurrency||Q.concurrency||10,cache:q.cache??Q.cache??!0,cacheDir:q.cacheDir||Q.cacheDir||d(process.cwd(),"ssg-cache"),contentLoaders:q.contentLoaders||[],hooks:q.hooks||{},minify:q.minify??Q.minify??!0,generate404:q.generate404??Q.generate404??!0,publicDir:q.publicDir||Q.publicDir||"public",trailingSlash:q.trailingSlash??Q.trailingSlash??!1,cleanOutput:q.cleanOutput??Q.cleanOutput??!0,cacheSalt:q.cacheSalt??"",partialsDir:q.partialsDir||$?.partialsDir||"",componentsDir:q.componentsDir||$?.componentsDir||"",failOnIncludeError:q.failOnIncludeError??!0,chunkIslands:q.chunkIslands===!0,prefetchIslands:q.prefetchIslands===!0,integrityIslands:q.integrityIslands===!0},W={totalPages:0,successCount:0,failedCount:0,cachedCount:0,buildTime:0,pages:[],errors:[]},z=new Set,A=0,G={},X={};await J.hooks.onBuildStart?.();try{if(J.cleanOutput&&O.existsSync(J.outputDir))await O.promises.rm(J.outputDir,{recursive:!0});await O.promises.mkdir(J.outputDir,{recursive:!0});let L=J.cacheSalt;if(!L){let{resolveUserCssConfig:Y,fingerprintConfig:N}=await import("./chunk-eczq4cxz.js");try{L=N(await Y(process.cwd()))}catch{}}let{prepareImageDelivery:_}=await import("./chunk-pf8575bx.js"),F=await _(J.publicDir,J.outputDir);if(F.count>0)console.log(`Optimized ${F.count} image(s) for responsive delivery`),L=[L,F.fingerprint].filter(Boolean).join(":");let C=new wq(J.cacheDir,L);if(J.cache)await C.load();try{let{generateCss:Y}=await import("./chunk-eczq4cxz.js");await Y('<div class="bg-black"></div>')}catch{}Yq();let kq=$?.routeMiddleware?.dir||"middleware";await jq(process.cwd(),kq);let p=Vq();if(p.length>0)console.log(`Loaded ${p.length} middleware: ${p.join(", ")}`);let bq=$?.routeMiddleware?.global||[];Fq($?.layoutsDir,d(process.cwd()));let i=l(".",{pagesDir:J.pagesDir,pagesDirs:$?._layerPageDirs});console.log(`Found ${i.length} routes`);let g=[];for(let Y of i){let N=await uq(Y);for(let H of N)g.push({route:Y,url:H.url,params:H.params,props:H.props,revalidate:H.revalidate??J.revalidate})}W.totalPages=g.length,console.log(`Generating ${W.totalPages} pages...`);let b=[],s=[];for(let Y=0;Y<g.length;Y+=J.concurrency)s.push(g.slice(Y,Y+J.concurrency));for(let Y of s)await Promise.all(Y.map(async(N)=>{let{route:H,url:V,params:S,props:Sq,revalidate:a}=N;try{await J.hooks.onPageStart?.(V);let w=await Bun.file(H.filePath).text(),R=JJ(w),vq=R?.middleware?Array.isArray(R.middleware)?R.middleware:[R.middleware]:[],t=[...bq,...vq];if(t.length>0){let D=Gq(V,S,R||{}),M=Lq(D,null,void 0,{isServer:!0}),E=await Nq(t,M);if(E.redirect){let U=typeof E.redirect==="string"?E.redirect:E.redirect.path||E.redirect,x=QJ(String(U),V),k=ZJ(V,J);await O.promises.mkdir(j.dirname(k),{recursive:!0}),await Bun.write(k,x),W.successCount++,W.pages.push({route:V,outputPath:k,size:Buffer.byteLength(x),cached:!1}),b.push({loc:V,lastmod:new Date().toISOString()}),console.log(` \u21B3 ${V} \u2192 redirect to ${U}`);return}if(E.abort){let U=typeof E.abort==="string"?E.abort:E.abort?.error?.message||"aborted";console.warn(` \u21B3 ${V} \u2014 middleware aborted: ${U}`);return}}let e=w.match(/definePageMeta\s*\(\s*\{[\s\S]*?validate\s*:\s*((?:\([^)]*\)|[^,}])*(?:\{[\s\S]*?\})?)/m);if(e)try{if(!await Function("route",`
45
45
  const validate = ${e[1]};
46
46
  return validate(route);
47
47
  `)({params:S})){console.warn(`Validation failed for ${V}, skipping...`);return}}catch{}let I=null,qq=!1;if(J.cache){if(I=C.get(V,H.filePath),I)qq=!0,W.cachedCount++}if(!I){let D=await Mq(H,S,Sq,J,$);if(I=D.html,J.failOnIncludeError&&D.includeFailures.length>0)throw Error(`${D.includeFailures.length} include(s) failed to resolve, so this page would have shipped with an error banner where the markup should be:
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@stacksjs/stx",
3
3
  "type": "module",
4
- "version": "0.2.364",
4
+ "version": "0.2.365",
5
5
  "description": "A performant UI Framework. Powered by Bun.",
6
6
  "author": "Chris Breuer <chris@stacksjs.org>",
7
7
  "license": "MIT",
@@ -118,12 +118,12 @@
118
118
  "dependencies": {
119
119
  "@stacksjs/ts-css": "^0.3.2",
120
120
  "@stacksjs/clapp": "^0.2.16",
121
- "@stacksjs/desktop": "0.2.364",
122
- "@stacksjs/sanitizer": "0.2.364",
121
+ "@stacksjs/desktop": "0.2.365",
122
+ "@stacksjs/sanitizer": "0.2.365",
123
123
  "@stacksjs/ts-i18n": "^0.1.11",
124
- "bun-plugin-stx": "0.2.364",
124
+ "bun-plugin-stx": "0.2.365",
125
125
  "bunfig": "^0.15.19",
126
- "stx-router": "0.2.364",
126
+ "stx-router": "0.2.365",
127
127
  "ts-broadcasting": "^0.0.10",
128
128
  "ts-images": "^0.2.22",
129
129
  "ts-syntax-highlighter": "^0.2.1"