@devlusoft/devix 0.4.1-beta.14 → 0.4.1-beta.15
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/cli/dev-server.js
CHANGED
|
@@ -256,7 +256,7 @@ export type PageParams = NonNullable<Parameters<typeof loader>[0]>["params"]
|
|
|
256
256
|
`:`// auto-generado por devix - no editar
|
|
257
257
|
export type PageData = undefined
|
|
258
258
|
export type PageParams = Record<string, string>
|
|
259
|
-
`}function b(e,t){let r=x(t,e),o=ee(r,"utf-8"),n=Fe(o,r),a=x(t,".devix","pages",e.replace(/\.(tsx?|jsx?)$/,"")),d=x(a,"$types.d.ts"),y=r.replace(/\.(tsx?|jsx?)$/,""),f=re(a,y).replace(/\\/g,"/"),u=Ue(f,n);te(d)&&ee(d,"utf-8")===u||(Ce(a,{recursive:!0}),Le(d,u,"utf-8"))}function ne(e,t){let r=x(t,".devix","pages",e.replace(/\.(tsx?|jsx?)$/,"")),o=x(r,"$types.d.ts");te(o)&&Me(o)}function j(e,t){let r=x(t,e,"pages"),o;try{o=oe(r,t)}catch{return}for(let n of o)try{b(n,t)}catch{}}var S=qe(Ne(import.meta.url)),F="virtual:devix/entry-client",U="virtual:devix/client-routes",T="virtual:devix/render",$="virtual:devix/api",k="virtual:devix/context",H="virtual:devix/server-entry",ie=new Set(["loader","guard","generateStaticParams","headers"]);function se(e){let t=e.appDir??"app",r=`${t}/pages`,o=(e.css??[]).map(i=>i.startsWith("/")?i:`/${i.replace(/^\.\//,"")}`),n=p(S,"../server/render.js").replace(/\\/g,"/"),a=p(S,"../server/api.js").replace(/\\/g,"/"),d=p(S,"../runtime/client-router.js").replace(/\\/g,"/"),y=p(S,"../server/routes.js").replace(/\\/g,"/"),f=p(S,"../utils/env.js").replace(/\\/g,"/"),u=We(import.meta.url),_=u.resolve("@hono/node-server").replace(/\\/g,"/"),A=u.resolve("@hono/node-server/serve-static").replace(/\\/g,"/"),ye=u.resolve("hono").replace(/\\/g,"/"),xe={name:"devix",enforce:"pre",resolveId(i){if(i===F)return`\0${F}`;if(i===U)return`\0${U}`;if(i===T)return`\0${T}`;if(i===$)return`\0${$}`;if(i===k)return`\0${k}`;if(i===H)return`\0${H}`},load(i){if(i===`\0${F}`)return q({cssUrls:o});if(i===`\0${U}`)return V({pagesDir:r,matcherPath:d});if(i===`\0${T}`)return W({pagesDir:r,renderPath:n});if(i===`\0${$}`)return B({apiPath:a,appDir:t});if(i===`\0${k}`)return J();if(i===`\0${H}`)return Q({routesPath:y,envPath:f,honoServerPath:_,honoServerStaticPath:A,honoPath:ye})},transform(i,c,E){if(E?.ssr)return;let w=p(process.cwd(),r);if(!c.startsWith(w))return;let P=Be(c,i,{sourceType:"module"}),g=[];for(let l of P.program.body){if(l.type!=="ExportNamedDeclaration"||!l.declaration)continue;let h=l.declaration;if(h.type==="FunctionDeclaration"&&h.id&&ie.has(h.id.name)&&g.push({start:l.start,end:l.end,name:h.id.name}),h.type==="VariableDeclaration"){let D=new Set;for(let C of h.declarations)C.id.type==="Identifier"&&ie.has(C.id.name)&&(D.has(l.start)||(D.add(l.start),g.push({start:l.start,end:l.end,name:C.id.name})))}}if(g.length===0)return;g.sort((l,h)=>h.start-l.start);let s=i;for(let{start:l,end:h,name:D}of g)s=s.slice(0,l)+`export const ${D} = undefined`+s.slice(h);return{code:s,map:null}},buildStart(){let i=process.cwd(),c=O(t,i);L(I(c,`${t}/api`),i),j(t,i)},configureServer(i){let c=process.cwd();j(t,c);let E=()=>{let s=O(t,c);L(I(s,`${t}/api`),c)},w=s=>s.startsWith(p(c,r))&&!s.endsWith("layout.tsx")&&!s.endsWith("error.tsx"),P=s=>Ve(c,s).replace(/\\/g,"/"),g=s=>{let l=i.moduleGraph.getModuleById(`\0${s}`);l&&i.moduleGraph.invalidateModule(l)};i.watcher.add(p(c,"devix.config.ts")),i.watcher.on("change",s=>{s===p(c,"devix.config.ts")&&(console.log("[devix] Config changed, restarting..."),process.exit(75))}),i.watcher.on("add",s=>{s.startsWith(p(c,r))&&g(T),w(s)&&b(P(s),c),s.includes(`${t}/api`)&&(g($),E())}),i.watcher.on("unlink",s=>{s.startsWith(p(c,r))&&g(T),w(s)&&ne(P(s),c),s.includes(`${t}/api`)&&(g($),E())}),i.watcher.on("change",s=>{w(s)&&b(P(s),c),s.includes(`${t}/api`)&&!s.endsWith("middleware.ts")&&E()})}},ve={plugins:[He(),xe],publicDir:p(process.cwd(),e.publicDir??"public"),ssr:{noExternal:["@devlusoft/devix"]},...e.envPrefix?{envPrefix:e.envPrefix}:{}};return ke(ve,e.vite??{})}function ae(e,{apiModule:t,renderModule:r,loaderTimeout:o}){e.all("/api/*",async n=>{try{return await t.handleApiRequest(n.req.url,n.req.raw)}catch(a){return console.error(a),n.json({error:"internal error"},500)}}),e.get("/_data/*",async n=>{try{let{pathname:a,search:d}=new URL(n.req.url,"http://localhost"),y=a.replace(/^\/_data/,"")+d,f=await r.runLoader(y,n.req.raw,{loaderTimeout:o});if(f.error)return n.json({error:"internal error"},500);if("loaderError"in f){let{statusCode:u,message:_,data:A}=f.loaderError;return n.json({statusCode:u,message:_,data:A},u)}return n.json(f)}catch(a){return console.error(a),n.json({error:"internal error"},500)}})}import m from"picocolors";import{networkInterfaces as Je}from"node:os";function Ge(e){let t=Je();for(let r of Object.values(t))for(let o of r??[])if(o.family==="IPv4"&&!o.internal)return`http://${o.address}:${e}/`;return null}function ce(e){let t="0.4.1-beta.
|
|
259
|
+
`}function b(e,t){let r=x(t,e),o=ee(r,"utf-8"),n=Fe(o,r),a=x(t,".devix","pages",e.replace(/\.(tsx?|jsx?)$/,"")),d=x(a,"$types.d.ts"),y=r.replace(/\.(tsx?|jsx?)$/,""),f=re(a,y).replace(/\\/g,"/"),u=Ue(f,n);te(d)&&ee(d,"utf-8")===u||(Ce(a,{recursive:!0}),Le(d,u,"utf-8"))}function ne(e,t){let r=x(t,".devix","pages",e.replace(/\.(tsx?|jsx?)$/,"")),o=x(r,"$types.d.ts");te(o)&&Me(o)}function j(e,t){let r=x(t,e,"pages"),o;try{o=oe(r,t)}catch{return}for(let n of o)try{b(n,t)}catch{}}var S=qe(Ne(import.meta.url)),F="virtual:devix/entry-client",U="virtual:devix/client-routes",T="virtual:devix/render",$="virtual:devix/api",k="virtual:devix/context",H="virtual:devix/server-entry",ie=new Set(["loader","guard","generateStaticParams","headers"]);function se(e){let t=e.appDir??"app",r=`${t}/pages`,o=(e.css??[]).map(i=>i.startsWith("/")?i:`/${i.replace(/^\.\//,"")}`),n=p(S,"../server/render.js").replace(/\\/g,"/"),a=p(S,"../server/api.js").replace(/\\/g,"/"),d=p(S,"../runtime/client-router.js").replace(/\\/g,"/"),y=p(S,"../server/routes.js").replace(/\\/g,"/"),f=p(S,"../utils/env.js").replace(/\\/g,"/"),u=We(import.meta.url),_=u.resolve("@hono/node-server").replace(/\\/g,"/"),A=u.resolve("@hono/node-server/serve-static").replace(/\\/g,"/"),ye=u.resolve("hono").replace(/\\/g,"/"),xe={name:"devix",enforce:"pre",resolveId(i){if(i===F)return`\0${F}`;if(i===U)return`\0${U}`;if(i===T)return`\0${T}`;if(i===$)return`\0${$}`;if(i===k)return`\0${k}`;if(i===H)return`\0${H}`},load(i){if(i===`\0${F}`)return q({cssUrls:o});if(i===`\0${U}`)return V({pagesDir:r,matcherPath:d});if(i===`\0${T}`)return W({pagesDir:r,renderPath:n});if(i===`\0${$}`)return B({apiPath:a,appDir:t});if(i===`\0${k}`)return J();if(i===`\0${H}`)return Q({routesPath:y,envPath:f,honoServerPath:_,honoServerStaticPath:A,honoPath:ye})},transform(i,c,E){if(E?.ssr)return;let w=p(process.cwd(),r);if(!c.startsWith(w))return;let P=Be(c,i,{sourceType:"module"}),g=[];for(let l of P.program.body){if(l.type!=="ExportNamedDeclaration"||!l.declaration)continue;let h=l.declaration;if(h.type==="FunctionDeclaration"&&h.id&&ie.has(h.id.name)&&g.push({start:l.start,end:l.end,name:h.id.name}),h.type==="VariableDeclaration"){let D=new Set;for(let C of h.declarations)C.id.type==="Identifier"&&ie.has(C.id.name)&&(D.has(l.start)||(D.add(l.start),g.push({start:l.start,end:l.end,name:C.id.name})))}}if(g.length===0)return;g.sort((l,h)=>h.start-l.start);let s=i;for(let{start:l,end:h,name:D}of g)s=s.slice(0,l)+`export const ${D} = undefined`+s.slice(h);return{code:s,map:null}},buildStart(){let i=process.cwd(),c=O(t,i);L(I(c,`${t}/api`),i),j(t,i)},configureServer(i){let c=process.cwd();j(t,c);let E=()=>{let s=O(t,c);L(I(s,`${t}/api`),c)},w=s=>s.startsWith(p(c,r))&&!s.endsWith("layout.tsx")&&!s.endsWith("error.tsx"),P=s=>Ve(c,s).replace(/\\/g,"/"),g=s=>{let l=i.moduleGraph.getModuleById(`\0${s}`);l&&i.moduleGraph.invalidateModule(l)};i.watcher.add(p(c,"devix.config.ts")),i.watcher.on("change",s=>{s===p(c,"devix.config.ts")&&(console.log("[devix] Config changed, restarting..."),process.exit(75))}),i.watcher.on("add",s=>{s.startsWith(p(c,r))&&g(T),w(s)&&b(P(s),c),s.includes(`${t}/api`)&&(g($),E())}),i.watcher.on("unlink",s=>{s.startsWith(p(c,r))&&g(T),w(s)&&ne(P(s),c),s.includes(`${t}/api`)&&(g($),E())}),i.watcher.on("change",s=>{w(s)&&b(P(s),c),s.includes(`${t}/api`)&&!s.endsWith("middleware.ts")&&E()})}},ve={plugins:[He(),xe],publicDir:p(process.cwd(),e.publicDir??"public"),ssr:{noExternal:["@devlusoft/devix"]},...e.envPrefix?{envPrefix:e.envPrefix}:{}};return ke(ve,e.vite??{})}function ae(e,{apiModule:t,renderModule:r,loaderTimeout:o}){e.all("/api/*",async n=>{try{return await t.handleApiRequest(n.req.url,n.req.raw)}catch(a){return console.error(a),n.json({error:"internal error"},500)}}),e.get("/_data/*",async n=>{try{let{pathname:a,search:d}=new URL(n.req.url,"http://localhost"),y=a.replace(/^\/_data/,"")+d,f=await r.runLoader(y,n.req.raw,{loaderTimeout:o});if(f.error)return n.json({error:"internal error"},500);if("loaderError"in f){let{statusCode:u,message:_,data:A}=f.loaderError;return n.json({statusCode:u,message:_,data:A},u)}return n.json(f)}catch(a){return console.error(a),n.json({error:"internal error"},500)}})}import m from"picocolors";import{networkInterfaces as Je}from"node:os";function Ge(e){let t=Je();for(let r of Object.values(t))for(let o of r??[])if(o.family==="IPv4"&&!o.internal)return`http://${o.address}:${e}/`;return null}function ce(e){let t="0.4.1-beta.15",r=Ge(e);console.log(),console.log(` ${m.bold(m.yellow("devix"))} ${m.dim(`v${t}`)}`),console.log(),console.log(` ${m.green("\u279C")} ${m.bold("Local:")} ${m.cyan(`http://localhost:${e}/`)}`),console.log(r?` ${m.green("\u279C")} ${m.bold("Network:")} ${m.cyan(r)}`:` ${m.green("\u279C")} ${m.bold("Network:")} ${m.dim("use --host to expose")}`),console.log()}async function le(e){let t=new Set;for(let[,r]of e.moduleGraph.idToModuleMap)r.id&&(r.id.endsWith(".css")||r.id.includes(".css?"))&&r.url.startsWith("/")&&t.add(r.url);return[...t]}function ue(e){if(typeof e=="number")return e;let t=e.trim().match(/^(\d+(?:\.\d+)?)\s*(ms|s|m|h)?$/);if(!t)throw new Error(`[devix] Invalid duration: "${e}". Use a number (ms) or a string like "5s", "2m", "500ms".`);let r=parseFloat(t[1]);switch(t[2]){case"h":return r*36e5;case"m":return r*6e4;case"s":return r*1e3;default:return r}}import{loadEnv as Xe}from"vite";function de(e){let t=Xe(e,process.cwd(),"");for(let[r,o]of Object.entries(t))process.env[r]===void 0&&(process.env[r]=o)}import{build as Ye}from"esbuild";import{join as pe}from"node:path";import{unlinkSync as ze,writeFileSync as Ze}from"node:fs";import{pathToFileURL as Ke}from"node:url";async function me(e){let t=await Ye({entryPoints:[pe(e,"devix.config.ts")],bundle:!0,write:!1,format:"esm",platform:"node",packages:"external"}),r=pe(e,`.devix-config-${Date.now()}.mjs`);Ze(r,t.outputFiles[0].text);try{return(await import(Ke(r).href)).default}finally{ze(r)}}de("development");var fe="virtual:devix/render",ot="virtual:devix/api",R=await me(process.cwd()),ge=Number(process.env.PORT)||R.port||3e3,nt=typeof R.host=="string"?R.host:R.host?"0.0.0.0":"localhost",v=await et({...se(R),configFile:!1,appType:"custom",server:{middlewareMode:!0}}),he={render:async(...e)=>(await v.ssrLoadModule(fe)).render(...e),runLoader:async(...e)=>(await v.ssrLoadModule(fe)).runLoader(...e)},it={handleApiRequest:async(...e)=>(await v.ssrLoadModule(ot)).handleApiRequest(...e)},N=new rt;ae(N,{renderModule:he,apiModule:it});N.get("*",async e=>{try{let{html:t,statusCode:r,headers:o}=await he.render(e.req.url,e.req.raw,{loaderTimeout:ue(R.loaderTimeout??1e4)}),a=(await le(v)).map(u=>`<link rel="stylesheet" href="${u}">`).join(`
|
|
260
260
|
`),d=a?t.replace("</head>",`${a}
|
|
261
261
|
</head>`):t,y=await v.transformIndexHtml(e.req.url,`<!DOCTYPE html>${d}`),f=e.html(y,r);for(let[u,_]of Object.entries(o))f.headers.set(u,_);return f}catch(t){return v.ssrFixStacktrace(t),console.error(t),e.text("Internal Server Error",500)}});var st=tt(N.fetch);Qe(async(e,t)=>{await new Promise(r=>v.middlewares(e,t,r)),t.writableEnded||await st(e,t)}).listen(ge,nt,()=>{ce(ge)});
|
|
262
262
|
//# sourceMappingURL=dev-server.js.map
|
package/dist/cli/index.js
CHANGED
|
@@ -257,7 +257,7 @@ export type PageParams = NonNullable<Parameters<typeof loader>[0]>["params"]
|
|
|
257
257
|
`:`// auto-generado por devix - no editar
|
|
258
258
|
export type PageData = undefined
|
|
259
259
|
export type PageParams = Record<string, string>
|
|
260
|
-
`}function O(e,t){let r=y(t,e),n=be(r,"utf-8"),o=$t(n,r),a=y(t,".devix","pages",e.replace(/\.(tsx?|jsx?)$/,"")),d=y(a,"$types.d.ts"),x=r.replace(/\.(tsx?|jsx?)$/,""),m=Ce(a,x).replace(/\\/g,"/"),f=bt(m,o);De(d)&&be(d,"utf-8")===f||(wt(a,{recursive:!0}),Pt(d,f,"utf-8"))}function Oe(e,t){let r=y(t,".devix","pages",e.replace(/\.(tsx?|jsx?)$/,"")),n=y(r,"$types.d.ts");De(n)&&St(n)}function H(e,t){let r=y(t,e,"pages"),n;try{n=Ae(r,t)}catch{return}for(let o of n)try{O(o,t)}catch{}}var je=c(()=>{"use strict"});import{mergeConfig as Dt}from"vite";import Ct from"@vitejs/plugin-react";import{fileURLToPath as At}from"node:url";import{dirname as Ot,relative as jt,resolve as p}from"node:path";import{createRequire as Mt}from"node:module";import{parseSync as Ft}from"oxc-parser";function Fe(e){let t=e.appDir??"app",r=`${t}/pages`,n=(e.css??[]).map(i=>i.startsWith("/")?i:`/${i.replace(/^\.\//,"")}`),o=p(P,"../server/render.js").replace(/\\/g,"/"),a=p(P,"../server/api.js").replace(/\\/g,"/"),d=p(P,"../runtime/client-router.js").replace(/\\/g,"/"),x=p(P,"../server/routes.js").replace(/\\/g,"/"),m=p(P,"../utils/env.js").replace(/\\/g,"/"),f=Mt(import.meta.url),w=f.resolve("@hono/node-server").replace(/\\/g,"/"),M=f.resolve("@hono/node-server/serve-static").replace(/\\/g,"/"),tt=f.resolve("hono").replace(/\\/g,"/"),rt={name:"devix",enforce:"pre",resolveId(i){if(i===q)return`\0${q}`;if(i===V)return`\0${V}`;if(i===T)return`\0${T}`;if(i===$)return`\0${$}`;if(i===J)return`\0${J}`;if(i===W)return`\0${W}`},load(i){if(i===`\0${q}`)return ie({cssUrls:n});if(i===`\0${V}`)return ae({pagesDir:r,matcherPath:d});if(i===`\0${T}`)return le({pagesDir:r,renderPath:o});if(i===`\0${$}`)return de({apiPath:a,appDir:t});if(i===`\0${J}`)return me();if(i===`\0${W}`)return Te({routesPath:x,envPath:m,honoServerPath:w,honoServerStaticPath:M,honoPath:tt})},transform(i,l,_){if(_?.ssr)return;let S=p(process.cwd(),r);if(!l.startsWith(S))return;let E=Ft(l,i,{sourceType:"module"}),g=[];for(let u of E.program.body){if(u.type!=="ExportNamedDeclaration"||!u.declaration)continue;let h=u.declaration;if(h.type==="FunctionDeclaration"&&h.id&&Me.has(h.id.name)&&g.push({start:u.start,end:u.end,name:h.id.name}),h.type==="VariableDeclaration"){let A=new Set;for(let F of h.declarations)F.id.type==="Identifier"&&Me.has(F.id.name)&&(A.has(u.start)||(A.add(u.start),g.push({start:u.start,end:u.end,name:F.id.name})))}}if(g.length===0)return;g.sort((u,h)=>h.start-u.start);let s=i;for(let{start:u,end:h,name:A}of g)s=s.slice(0,u)+`export const ${A} = undefined`+s.slice(h);return{code:s,map:null}},buildStart(){let i=process.cwd(),l=k(t,i);N(I(l,`${t}/api`),i),H(t,i)},configureServer(i){let l=process.cwd();H(t,l);let _=()=>{let s=k(t,l);N(I(s,`${t}/api`),l)},S=s=>s.startsWith(p(l,r))&&!s.endsWith("layout.tsx")&&!s.endsWith("error.tsx"),E=s=>jt(l,s).replace(/\\/g,"/"),g=s=>{let u=i.moduleGraph.getModuleById(`\0${s}`);u&&i.moduleGraph.invalidateModule(u)};i.watcher.add(p(l,"devix.config.ts")),i.watcher.on("change",s=>{s===p(l,"devix.config.ts")&&(console.log("[devix] Config changed, restarting..."),process.exit(75))}),i.watcher.on("add",s=>{s.startsWith(p(l,r))&&g(T),S(s)&&O(E(s),l),s.includes(`${t}/api`)&&(g($),_())}),i.watcher.on("unlink",s=>{s.startsWith(p(l,r))&&g(T),S(s)&&Oe(E(s),l),s.includes(`${t}/api`)&&(g($),_())}),i.watcher.on("change",s=>{S(s)&&O(E(s),l),s.includes(`${t}/api`)&&!s.endsWith("middleware.ts")&&_()})}},ot={plugins:[Ct(),rt],publicDir:p(process.cwd(),e.publicDir??"public"),ssr:{noExternal:["@devlusoft/devix"]},...e.envPrefix?{envPrefix:e.envPrefix}:{}};return Dt(ot,e.vite??{})}var P,q,V,T,$,J,W,Me,Ie=c(()=>{"use strict";se();ce();ue();pe();fe();Se();L();Pe();$e();je();P=Ot(At(import.meta.url)),q="virtual:devix/entry-client",V="virtual:devix/client-routes",T="virtual:devix/render",$="virtual:devix/api",J="virtual:devix/context",W="virtual:devix/server-entry",Me=new Set(["loader","guard","generateStaticParams","headers"])});function Le(e){if(typeof e=="number")return e;let t=e.trim().match(/^(\d+(?:\.\d+)?)\s*(ms|s|m|h)?$/);if(!t)throw new Error(`[devix] Invalid duration: "${e}". Use a number (ms) or a string like "5s", "2m", "500ms".`);let r=parseFloat(t[1]);switch(t[2]){case"h":return r*36e5;case"m":return r*6e4;case"s":return r*1e3;default:return r}}var Ue=c(()=>{"use strict"});import{build as It}from"esbuild";import{join as ke}from"node:path";import{unlinkSync as Lt,writeFileSync as Ut}from"node:fs";import{pathToFileURL as kt}from"node:url";async function j(e){let t=await It({entryPoints:[ke(e,"devix.config.ts")],bundle:!0,write:!1,format:"esm",platform:"node",packages:"external"}),r=ke(e,`.devix-config-${Date.now()}.mjs`);Ut(r,t.outputFiles[0].text);try{return(await import(kt(r).href)).default}finally{Lt(r)}}var B=c(()=>{"use strict"});var Ne={};import{writeFileSync as Nt}from"node:fs";import{resolve as Ht}from"node:path";import{build as G}from"vite";var b,X,qt,Y=c(async()=>{"use strict";Ie();Ue();B();b=await j(process.cwd()),X=Fe(b);await G({...X,configFile:!1,build:{outDir:"dist/client",manifest:!0,rolldownOptions:{input:"virtual:devix/entry-client"}}});await G({...X,configFile:!1,build:{ssr:!0,outDir:"dist/server",copyPublicDir:!1,rolldownOptions:{input:{render:"virtual:devix/render",api:"virtual:devix/api"}}}});await G({...X,configFile:!1,build:{ssr:!0,outDir:"dist/server",emptyOutDir:!1,copyPublicDir:!1,rolldownOptions:{input:{index:"virtual:devix/server-entry"}}}});qt={port:b.port??3e3,host:b.host??!1,loaderTimeout:Le(b.loaderTimeout??1e4),output:b.output??"server"};Nt(Ht(process.cwd(),"dist/devix.config.json"),JSON.stringify(qt,null,2),"utf-8")});var Gt={};import{readFileSync as Vt,mkdirSync as He,writeFileSync as qe,rmSync as Jt}from"node:fs";import{resolve as K,join as R}from"node:path";import{pathToFileURL as Wt}from"node:url";var Je,Bt,z,Ve,Z,We=c(async()=>{"use strict";B();Je=await j(process.cwd());Je.output!=="static"&&console.warn('[devix] Tip: set output: "static" in devix.config.ts to skip the SSR server at runtime.');await Y().then(()=>Ne);Bt=Date.now(),z=await import(Wt(K(process.cwd(),"dist/server/render.js")).href+`?t=${Bt}`),Ve=JSON.parse(Vt(K(process.cwd(),"dist/client/.vite/manifest.json"),"utf-8")),Z=await z.getStaticRoutes();console.log(`[devix] Generating ${Z.length} static page${Z.length===1?"":"s"}...`);for(let e of Z){let t=`http://localhost${e}`,{html:r,statusCode:n}=await z.render(t,new Request(t),{manifest:Ve});if(n!==200){console.warn(`[devix] Skipping ${e} \u2014 status ${n}`);continue}let o=e==="/"?R(process.cwd(),"dist/client/index.html"):R(process.cwd(),"dist/client",e,"index.html");He(R(o,".."),{recursive:!0}),qe(o,`<!DOCTYPE html>${r}`,"utf-8");let a=await z.runLoader(t,new Request(t),{manifest:Ve}),d=e==="/"?R(process.cwd(),"dist/client/_data/index.json"):R(process.cwd(),"dist/client/_data",`${e}.json`);He(R(d,".."),{recursive:!0}),qe(d,JSON.stringify(a),"utf-8"),console.log(` \u2713 ${e}`)}console.log("[devix] Generation complete.");Je.output==="static"&&(Jt(K(process.cwd(),"dist/server"),{recursive:!0,force:!0}),console.log("[devix] Removed dist/server (not needed in static mode)"))});function Be(e,{apiModule:t,renderModule:r,loaderTimeout:n}){e.all("/api/*",async o=>{try{return await t.handleApiRequest(o.req.url,o.req.raw)}catch(a){return console.error(a),o.json({error:"internal error"},500)}}),e.get("/_data/*",async o=>{try{let{pathname:a,search:d}=new URL(o.req.url,"http://localhost"),x=a.replace(/^\/_data/,"")+d,m=await r.runLoader(x,o.req.raw,{loaderTimeout:n});if(m.error)return o.json({error:"internal error"},500);if("loaderError"in m){let{statusCode:f,message:w,data:M}=m.loaderError;return o.json({statusCode:f,message:w,data:M},f)}return o.json(m)}catch(a){return console.error(a),o.json({error:"internal error"},500)}})}function Ge(e,{renderModule:t,manifest:r,loaderTimeout:n}){e.get("*",async o=>{try{let{html:a,statusCode:d,headers:x}=await t.render(o.req.url,o.req.raw,{manifest:r,loaderTimeout:n}),m=o.html(`<!DOCTYPE html>${a}`,d);for(let[f,w]of Object.entries(x))m.headers.set(f,w);return m}catch(a){return console.error(a),o.text("Internal Server Error",500)}})}var Xe=c(()=>{"use strict"});import{loadEnv as Xt}from"vite";function Ye(e){let t=Xt(e,process.cwd(),"");for(let[r,n]of Object.entries(t))process.env[r]===void 0&&(process.env[r]=n)}var ze=c(()=>{"use strict"});var er={};import{readFileSync as Q}from"node:fs";import{serve as Yt}from"@hono/node-server";import{serveStatic as zt}from"@hono/node-server/serve-static";import{Hono as Zt}from"hono";import{resolve as Ze,join as D}from"node:path";import{pathToFileURL as Ke}from"node:url";var ee,te,re,v,Kt,Qt,C,oe,Qe=c(async()=>{"use strict";Xe();ze();Ye("production");try{v=JSON.parse(Q(D(process.cwd(),"dist/devix.config.json"),"utf-8")),v.output!=="static"&&(ee=await import(Ke(Ze(process.cwd(),"dist/server/render.js")).href),te=await import(Ke(Ze(process.cwd(),"dist/server/api.js")).href)),re=JSON.parse(Q(D(process.cwd(),"dist/client/.vite/manifest.json"),"utf-8"))}catch{console.error('[devix] Build not found. Run "devix build" first.'),process.exit(1)}Kt=Number(process.env.PORT)||v.port||3e3,Qt=typeof v.host=="string"?v.host:v.host?"0.0.0.0":process.env.HOST||"0.0.0.0",C=new Zt,oe=D(process.cwd(),"dist/client");v.output==="static"&&C.get("/_data/*",e=>{let t=e.req.path.replace(/^\/_data/,"")||"/",r=t==="/"?D(oe,"_data/index.json"):D(oe,"_data",`${t}.json`);try{let n=Q(r,"utf-8");return e.json(JSON.parse(n))}catch{return e.json({error:"not found"},404)}});C.use("/*",zt({root:oe,onFound:(e,t)=>{t.header("Cache-Control",e.includes("/assets/")?"public, immutable, max-age=31536000":"no-cache")}}));v.output==="static"?console.log("[devix] Static mode \u2014 serving pre-generated files from dist/client"):(Be(C,{renderModule:ee,apiModule:te,manifest:re}),Ge(C,{renderModule:ee,apiModule:te,manifest:re,loaderTimeout:v.loaderTimeout}));Yt({fetch:C.fetch,port:Kt,hostname:Qt},e=>console.log(`http://${e.address}:${e.port}`))});var et=process.argv[2];switch(et){case"dev":await Promise.resolve().then(()=>(ne(),lt));break;case"build":await Y().then(()=>Ne);break;case"generate":await We().then(()=>Gt);break;case"start":await Qe().then(()=>er);break;case"--version":case"-v":{console.log("0.4.1-beta.14");break}case"--help":case"-h":console.log(`
|
|
260
|
+
`}function O(e,t){let r=y(t,e),n=be(r,"utf-8"),o=$t(n,r),a=y(t,".devix","pages",e.replace(/\.(tsx?|jsx?)$/,"")),d=y(a,"$types.d.ts"),x=r.replace(/\.(tsx?|jsx?)$/,""),m=Ce(a,x).replace(/\\/g,"/"),f=bt(m,o);De(d)&&be(d,"utf-8")===f||(wt(a,{recursive:!0}),Pt(d,f,"utf-8"))}function Oe(e,t){let r=y(t,".devix","pages",e.replace(/\.(tsx?|jsx?)$/,"")),n=y(r,"$types.d.ts");De(n)&&St(n)}function H(e,t){let r=y(t,e,"pages"),n;try{n=Ae(r,t)}catch{return}for(let o of n)try{O(o,t)}catch{}}var je=c(()=>{"use strict"});import{mergeConfig as Dt}from"vite";import Ct from"@vitejs/plugin-react";import{fileURLToPath as At}from"node:url";import{dirname as Ot,relative as jt,resolve as p}from"node:path";import{createRequire as Mt}from"node:module";import{parseSync as Ft}from"oxc-parser";function Fe(e){let t=e.appDir??"app",r=`${t}/pages`,n=(e.css??[]).map(i=>i.startsWith("/")?i:`/${i.replace(/^\.\//,"")}`),o=p(P,"../server/render.js").replace(/\\/g,"/"),a=p(P,"../server/api.js").replace(/\\/g,"/"),d=p(P,"../runtime/client-router.js").replace(/\\/g,"/"),x=p(P,"../server/routes.js").replace(/\\/g,"/"),m=p(P,"../utils/env.js").replace(/\\/g,"/"),f=Mt(import.meta.url),w=f.resolve("@hono/node-server").replace(/\\/g,"/"),M=f.resolve("@hono/node-server/serve-static").replace(/\\/g,"/"),tt=f.resolve("hono").replace(/\\/g,"/"),rt={name:"devix",enforce:"pre",resolveId(i){if(i===q)return`\0${q}`;if(i===V)return`\0${V}`;if(i===T)return`\0${T}`;if(i===$)return`\0${$}`;if(i===J)return`\0${J}`;if(i===W)return`\0${W}`},load(i){if(i===`\0${q}`)return ie({cssUrls:n});if(i===`\0${V}`)return ae({pagesDir:r,matcherPath:d});if(i===`\0${T}`)return le({pagesDir:r,renderPath:o});if(i===`\0${$}`)return de({apiPath:a,appDir:t});if(i===`\0${J}`)return me();if(i===`\0${W}`)return Te({routesPath:x,envPath:m,honoServerPath:w,honoServerStaticPath:M,honoPath:tt})},transform(i,l,_){if(_?.ssr)return;let S=p(process.cwd(),r);if(!l.startsWith(S))return;let E=Ft(l,i,{sourceType:"module"}),g=[];for(let u of E.program.body){if(u.type!=="ExportNamedDeclaration"||!u.declaration)continue;let h=u.declaration;if(h.type==="FunctionDeclaration"&&h.id&&Me.has(h.id.name)&&g.push({start:u.start,end:u.end,name:h.id.name}),h.type==="VariableDeclaration"){let A=new Set;for(let F of h.declarations)F.id.type==="Identifier"&&Me.has(F.id.name)&&(A.has(u.start)||(A.add(u.start),g.push({start:u.start,end:u.end,name:F.id.name})))}}if(g.length===0)return;g.sort((u,h)=>h.start-u.start);let s=i;for(let{start:u,end:h,name:A}of g)s=s.slice(0,u)+`export const ${A} = undefined`+s.slice(h);return{code:s,map:null}},buildStart(){let i=process.cwd(),l=k(t,i);N(I(l,`${t}/api`),i),H(t,i)},configureServer(i){let l=process.cwd();H(t,l);let _=()=>{let s=k(t,l);N(I(s,`${t}/api`),l)},S=s=>s.startsWith(p(l,r))&&!s.endsWith("layout.tsx")&&!s.endsWith("error.tsx"),E=s=>jt(l,s).replace(/\\/g,"/"),g=s=>{let u=i.moduleGraph.getModuleById(`\0${s}`);u&&i.moduleGraph.invalidateModule(u)};i.watcher.add(p(l,"devix.config.ts")),i.watcher.on("change",s=>{s===p(l,"devix.config.ts")&&(console.log("[devix] Config changed, restarting..."),process.exit(75))}),i.watcher.on("add",s=>{s.startsWith(p(l,r))&&g(T),S(s)&&O(E(s),l),s.includes(`${t}/api`)&&(g($),_())}),i.watcher.on("unlink",s=>{s.startsWith(p(l,r))&&g(T),S(s)&&Oe(E(s),l),s.includes(`${t}/api`)&&(g($),_())}),i.watcher.on("change",s=>{S(s)&&O(E(s),l),s.includes(`${t}/api`)&&!s.endsWith("middleware.ts")&&_()})}},ot={plugins:[Ct(),rt],publicDir:p(process.cwd(),e.publicDir??"public"),ssr:{noExternal:["@devlusoft/devix"]},...e.envPrefix?{envPrefix:e.envPrefix}:{}};return Dt(ot,e.vite??{})}var P,q,V,T,$,J,W,Me,Ie=c(()=>{"use strict";se();ce();ue();pe();fe();Se();L();Pe();$e();je();P=Ot(At(import.meta.url)),q="virtual:devix/entry-client",V="virtual:devix/client-routes",T="virtual:devix/render",$="virtual:devix/api",J="virtual:devix/context",W="virtual:devix/server-entry",Me=new Set(["loader","guard","generateStaticParams","headers"])});function Le(e){if(typeof e=="number")return e;let t=e.trim().match(/^(\d+(?:\.\d+)?)\s*(ms|s|m|h)?$/);if(!t)throw new Error(`[devix] Invalid duration: "${e}". Use a number (ms) or a string like "5s", "2m", "500ms".`);let r=parseFloat(t[1]);switch(t[2]){case"h":return r*36e5;case"m":return r*6e4;case"s":return r*1e3;default:return r}}var Ue=c(()=>{"use strict"});import{build as It}from"esbuild";import{join as ke}from"node:path";import{unlinkSync as Lt,writeFileSync as Ut}from"node:fs";import{pathToFileURL as kt}from"node:url";async function j(e){let t=await It({entryPoints:[ke(e,"devix.config.ts")],bundle:!0,write:!1,format:"esm",platform:"node",packages:"external"}),r=ke(e,`.devix-config-${Date.now()}.mjs`);Ut(r,t.outputFiles[0].text);try{return(await import(kt(r).href)).default}finally{Lt(r)}}var B=c(()=>{"use strict"});var Ne={};import{writeFileSync as Nt}from"node:fs";import{resolve as Ht}from"node:path";import{build as G}from"vite";var b,X,qt,Y=c(async()=>{"use strict";Ie();Ue();B();b=await j(process.cwd()),X=Fe(b);await G({...X,configFile:!1,build:{outDir:"dist/client",manifest:!0,rolldownOptions:{input:"virtual:devix/entry-client"}}});await G({...X,configFile:!1,build:{ssr:!0,outDir:"dist/server",copyPublicDir:!1,rolldownOptions:{input:{render:"virtual:devix/render",api:"virtual:devix/api"}}}});await G({...X,configFile:!1,build:{ssr:!0,outDir:"dist/server",emptyOutDir:!1,copyPublicDir:!1,rolldownOptions:{input:{index:"virtual:devix/server-entry"}}}});qt={port:b.port??3e3,host:b.host??!1,loaderTimeout:Le(b.loaderTimeout??1e4),output:b.output??"server"};Nt(Ht(process.cwd(),"dist/devix.config.json"),JSON.stringify(qt,null,2),"utf-8")});var Gt={};import{readFileSync as Vt,mkdirSync as He,writeFileSync as qe,rmSync as Jt}from"node:fs";import{resolve as K,join as R}from"node:path";import{pathToFileURL as Wt}from"node:url";var Je,Bt,z,Ve,Z,We=c(async()=>{"use strict";B();Je=await j(process.cwd());Je.output!=="static"&&console.warn('[devix] Tip: set output: "static" in devix.config.ts to skip the SSR server at runtime.');await Y().then(()=>Ne);Bt=Date.now(),z=await import(Wt(K(process.cwd(),"dist/server/render.js")).href+`?t=${Bt}`),Ve=JSON.parse(Vt(K(process.cwd(),"dist/client/.vite/manifest.json"),"utf-8")),Z=await z.getStaticRoutes();console.log(`[devix] Generating ${Z.length} static page${Z.length===1?"":"s"}...`);for(let e of Z){let t=`http://localhost${e}`,{html:r,statusCode:n}=await z.render(t,new Request(t),{manifest:Ve});if(n!==200){console.warn(`[devix] Skipping ${e} \u2014 status ${n}`);continue}let o=e==="/"?R(process.cwd(),"dist/client/index.html"):R(process.cwd(),"dist/client",e,"index.html");He(R(o,".."),{recursive:!0}),qe(o,`<!DOCTYPE html>${r}`,"utf-8");let a=await z.runLoader(t,new Request(t),{manifest:Ve}),d=e==="/"?R(process.cwd(),"dist/client/_data/index.json"):R(process.cwd(),"dist/client/_data",`${e}.json`);He(R(d,".."),{recursive:!0}),qe(d,JSON.stringify(a),"utf-8"),console.log(` \u2713 ${e}`)}console.log("[devix] Generation complete.");Je.output==="static"&&(Jt(K(process.cwd(),"dist/server"),{recursive:!0,force:!0}),console.log("[devix] Removed dist/server (not needed in static mode)"))});function Be(e,{apiModule:t,renderModule:r,loaderTimeout:n}){e.all("/api/*",async o=>{try{return await t.handleApiRequest(o.req.url,o.req.raw)}catch(a){return console.error(a),o.json({error:"internal error"},500)}}),e.get("/_data/*",async o=>{try{let{pathname:a,search:d}=new URL(o.req.url,"http://localhost"),x=a.replace(/^\/_data/,"")+d,m=await r.runLoader(x,o.req.raw,{loaderTimeout:n});if(m.error)return o.json({error:"internal error"},500);if("loaderError"in m){let{statusCode:f,message:w,data:M}=m.loaderError;return o.json({statusCode:f,message:w,data:M},f)}return o.json(m)}catch(a){return console.error(a),o.json({error:"internal error"},500)}})}function Ge(e,{renderModule:t,manifest:r,loaderTimeout:n}){e.get("*",async o=>{try{let{html:a,statusCode:d,headers:x}=await t.render(o.req.url,o.req.raw,{manifest:r,loaderTimeout:n}),m=o.html(`<!DOCTYPE html>${a}`,d);for(let[f,w]of Object.entries(x))m.headers.set(f,w);return m}catch(a){return console.error(a),o.text("Internal Server Error",500)}})}var Xe=c(()=>{"use strict"});import{loadEnv as Xt}from"vite";function Ye(e){let t=Xt(e,process.cwd(),"");for(let[r,n]of Object.entries(t))process.env[r]===void 0&&(process.env[r]=n)}var ze=c(()=>{"use strict"});var er={};import{readFileSync as Q}from"node:fs";import{serve as Yt}from"@hono/node-server";import{serveStatic as zt}from"@hono/node-server/serve-static";import{Hono as Zt}from"hono";import{resolve as Ze,join as D}from"node:path";import{pathToFileURL as Ke}from"node:url";var ee,te,re,v,Kt,Qt,C,oe,Qe=c(async()=>{"use strict";Xe();ze();Ye("production");try{v=JSON.parse(Q(D(process.cwd(),"dist/devix.config.json"),"utf-8")),v.output!=="static"&&(ee=await import(Ke(Ze(process.cwd(),"dist/server/render.js")).href),te=await import(Ke(Ze(process.cwd(),"dist/server/api.js")).href)),re=JSON.parse(Q(D(process.cwd(),"dist/client/.vite/manifest.json"),"utf-8"))}catch{console.error('[devix] Build not found. Run "devix build" first.'),process.exit(1)}Kt=Number(process.env.PORT)||v.port||3e3,Qt=typeof v.host=="string"?v.host:v.host?"0.0.0.0":process.env.HOST||"0.0.0.0",C=new Zt,oe=D(process.cwd(),"dist/client");v.output==="static"&&C.get("/_data/*",e=>{let t=e.req.path.replace(/^\/_data/,"")||"/",r=t==="/"?D(oe,"_data/index.json"):D(oe,"_data",`${t}.json`);try{let n=Q(r,"utf-8");return e.json(JSON.parse(n))}catch{return e.json({error:"not found"},404)}});C.use("/*",zt({root:oe,onFound:(e,t)=>{t.header("Cache-Control",e.includes("/assets/")?"public, immutable, max-age=31536000":"no-cache")}}));v.output==="static"?console.log("[devix] Static mode \u2014 serving pre-generated files from dist/client"):(Be(C,{renderModule:ee,apiModule:te,manifest:re}),Ge(C,{renderModule:ee,apiModule:te,manifest:re,loaderTimeout:v.loaderTimeout}));Yt({fetch:C.fetch,port:Kt,hostname:Qt},e=>console.log(`http://${e.address}:${e.port}`))});var et=process.argv[2];switch(et){case"dev":await Promise.resolve().then(()=>(ne(),lt));break;case"build":await Y().then(()=>Ne);break;case"generate":await We().then(()=>Gt);break;case"start":await Qe().then(()=>er);break;case"--version":case"-v":{console.log("0.4.1-beta.15");break}case"--help":case"-h":console.log(`
|
|
261
261
|
devix \u2014 a lightweight SSR framework
|
|
262
262
|
|
|
263
263
|
Usage:
|
package/dist/runtime/index.d.ts
CHANGED
|
@@ -39,4 +39,4 @@ export interface FetchOptions<M extends HttpMethod = 'GET', P extends string = s
|
|
|
39
39
|
headers?: HeadersInit;
|
|
40
40
|
signal?: AbortSignal;
|
|
41
41
|
}
|
|
42
|
-
export declare function $fetch<P extends ApiPath = ApiPath, M extends HttpMethod = 'GET'>(path: P
|
|
42
|
+
export declare function $fetch<P extends ApiPath = ApiPath, M extends HttpMethod = 'GET'>(path: P, options?: FetchOptions<M, P>): Promise<InferResult<M, P>>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/runtime/router-provider.tsx", "../../src/runtime/head.tsx", "../../src/runtime/context.tsx", "../../src/runtime/error-boundary.tsx", "../../src/runtime/link.tsx", "../../src/utils/cookies.ts", "../../src/utils/response.ts", "../../src/runtime/create-handler.ts", "../../src/runtime/fetch.ts", "../../src/runtime/index.ts"],
|
|
4
|
-
"sourcesContent": ["import { ComponentType, ReactNode, useCallback, useContext, useEffect, useRef, useState } from \"react\";\nimport { RouterContext } from 'virtual:devix/context'\nimport { ErrorProps, LayoutProps, PageProps } from \"../server/types\";\nimport { Metadata, Viewport } from \"../types\";\nimport { getDefaultErrorPage, loadErrorPage, matchClientRoute } from \"virtual:devix/client-routes\";\nimport { HeadSlot } from \"./head\";\nimport { NavigateOptions, PageMetaContext, RouteDataContext } from \"./context\";\nimport { DevixErrorBoundary } from \"./error-boundary\";\nimport type { Redirect } from \"../utils/response\";\n\ninterface RouteState {\n pathname: string\n params: Record<string, string>\n loaderData: unknown\n layoutsData: unknown[]\n Page: ComponentType<PageProps>\n layouts: ComponentType<LayoutProps>[]\n metadata: Metadata | null\n viewport?: Viewport\n pendingError?: ErrorProps\n ErrorPage?: ComponentType<ErrorProps>\n}\n\nexport function useRouter() {\n return useContext(RouterContext)\n}\n\nconst noopNavigate = () => Promise.resolve()\nconst noopRevalidate = () => Promise.resolve()\n\nexport function useNavigate() {\n const ctx = useContext(RouterContext)\n return ctx?.navigate ?? noopNavigate\n}\n\nexport function useRevalidate() {\n const ctx = useContext(RouterContext)\n return ctx?.revalidate ?? noopRevalidate\n}\n\nexport function useParams<T extends Record<string, string>>() {\n const ctx = useContext(RouteDataContext)\n if (!ctx) throw new Error(\"useParams must be used within a route or layout\")\n return ctx.params as T\n}\n\ntype LoaderReturnType<T> = T extends (...args: any[]) => Promise<infer R>\n ? [Exclude<R, Redirect | void | undefined>] extends [never] ? undefined : Exclude<R, Redirect | void | undefined>\n : T extends (...args: any[]) => infer R\n ? [Exclude<R, Redirect | void | undefined>] extends [never] ? undefined : Exclude<R, Redirect | void | undefined>\n : T\n\nexport function useLoaderData<T>() {\n const ctx = useContext(RouteDataContext)\n if (!ctx) throw new Error(\"useLoaderData must be used within a route or layout\")\n return ctx.loaderData as LoaderReturnType<T>\n}\n\ninterface PrefetchEntry {\n promise: Promise<{ pageMod: any; layoutMods: any[]; data: any } | null>\n controller: AbortController\n}\n\ninterface RouterProviderProps {\n initialData: unknown\n initialParams: Record<string, string>\n initialPage: ComponentType<PageProps>\n initialLayouts?: ComponentType<LayoutProps>[]\n initialLayoutsData?: unknown[]\n initialMeta?: Metadata | null\n initialViewport?: Viewport\n initialError?: ErrorProps\n initialErrorPage?: ComponentType<ErrorProps>\n clientEntry: string\n}\n\nexport function RouterProvider({\n initialData,\n initialParams,\n initialPage,\n initialLayouts = [],\n initialLayoutsData = [],\n initialMeta,\n initialViewport,\n initialError,\n initialErrorPage,\n clientEntry,\n}: RouterProviderProps) {\n\n const [state, setState] = useState<RouteState>({\n pathname: window.location.pathname,\n params: initialParams,\n loaderData: initialData,\n layoutsData: initialLayoutsData,\n Page: initialPage,\n layouts: initialLayouts,\n metadata: initialMeta ?? null,\n viewport: initialViewport,\n pendingError: initialError,\n ErrorPage: initialErrorPage,\n })\n\n const navigatingRef = useRef<AbortController | null>(null)\n const [isNavigating, setIsNavigating] = useState(false)\n\n const prefetchCacheRef = useRef<Map<string, PrefetchEntry>>(new Map())\n\n const prefetchRoute = useCallback((href: string) => {\n if (prefetchCacheRef.current.has(href)) return\n const pathname = href.split('?')[0].split('#')[0]\n const matched = matchClientRoute(pathname)\n if (!matched) return\n\n const controller = new AbortController()\n const promise = Promise.all([\n Promise.all([matched.load(), ...matched.loadLayouts.map(l => l())]),\n fetch(`/_data${href}`, { headers: { Accept: 'application/json' }, signal: controller.signal })\n ]).then(async ([[pageMod, ...layoutMods], dataRes]) => {\n if (!dataRes.ok || !pageMod.default) return null\n const data = await dataRes.json()\n return { pageMod, layoutMods, data }\n }).catch(() => null)\n\n const expireTimer = setTimeout(() => {\n controller.abort()\n prefetchCacheRef.current.delete(href)\n }, 3000)\n promise.finally(() => clearTimeout(expireTimer))\n\n prefetchCacheRef.current.set(href, { promise, controller })\n }, [])\n\n const loadRoute = useCallback(async (to: string, controller: AbortController) => {\n const pathname = to.split('?')[0].split('#')[0]\n const matched = matchClientRoute(pathname)\n if (!matched) {\n const ErrorPage = await loadErrorPage() ?? getDefaultErrorPage()\n setState(prev => ({\n ...prev,\n pathname: pathname,\n pendingError: { statusCode: 404, message: 'Not found' },\n ErrorPage: ErrorPage ?? undefined,\n }))\n return\n }\n\n const cached = prefetchCacheRef.current.get(to)\n if (cached) prefetchCacheRef.current.delete(to)\n const prefetched = cached ? await cached.promise : null\n\n if (controller.signal.aborted) return\n\n let pageMod: any, layoutMods: any[], data: any\n\n if (prefetched) {\n ;({ pageMod, layoutMods, data } = prefetched)\n } else {\n const [[pm, ...lm], dataRes] = await Promise.all([\n Promise.all([\n matched.load(),\n ...matched.loadLayouts.map(l => l()),\n ]),\n fetch(`/_data${to}`, {\n headers: { Accept: 'application/json' },\n signal: controller.signal,\n })\n ])\n\n if (controller.signal.aborted) return\n if (!pm.default) return\n\n if (!dataRes.ok) {\n const ct = dataRes.headers.get('Content-Type') ?? ''\n let errorBody: { statusCode?: number; message?: string; data?: unknown } | null = null\n try {\n if (ct.includes('application/json')) errorBody = await dataRes.json()\n else if (ct.includes('text/plain')) errorBody = { message: await dataRes.text() }\n } catch { /* ignorar errores de parsing */ }\n\n const headers: Record<string, string> = {}\n dataRes.headers.forEach((value, key) => { headers[key] = value })\n\n const ErrorPage = await loadErrorPage() ?? getDefaultErrorPage()\n setState(prev => ({\n ...prev,\n pathname,\n pendingError: {\n statusCode: errorBody?.statusCode ?? dataRes.status,\n message: errorBody?.message ?? 'Server error',\n data: errorBody?.data,\n headers,\n },\n ErrorPage: ErrorPage ?? undefined,\n }))\n return\n }\n\n pageMod = pm\n layoutMods = lm\n data = await dataRes.json()\n }\n\n if (data.redirect) {\n if (data.redirectReplace) {\n window.history.replaceState(null, '', data.redirect)\n } else {\n window.history.pushState(null, '', data.redirect)\n }\n await loadRoute(data.redirect, controller)\n return\n }\n\n setState({\n pathname,\n params: data.params ?? {},\n loaderData: data.loaderData,\n layoutsData: (data.layouts ?? []).map((l: any) => l.loaderData),\n Page: pageMod.default,\n layouts: layoutMods.map(m => m.default),\n metadata: data.metadata ?? null,\n viewport: data.viewport,\n })\n\n const hash = to.includes('#') ? to.split('#')[1] : null\n const scrollBehavior = getComputedStyle(document.documentElement).scrollBehavior as ScrollBehavior\n if (hash) {\n requestAnimationFrame(() => {\n document.getElementById(hash)?.scrollIntoView({ behavior: scrollBehavior })\n })\n } else {\n window.scrollTo({ top: 0, behavior: scrollBehavior })\n }\n }, [])\n\n const navigate = useCallback(async (to: string, options?: NavigateOptions) => {\n navigatingRef.current?.abort()\n const controller = new AbortController()\n navigatingRef.current = controller\n\n setIsNavigating(true)\n const run = async () => {\n window.history[options?.replace ? 'replaceState' : 'pushState'](null, '', to)\n await loadRoute(to, controller)\n }\n try {\n if (options?.viewTransition && 'startViewTransition' in document) {\n await (document as any).startViewTransition(run).finished\n } else {\n await run()\n }\n } finally {\n if (!controller.signal.aborted) setIsNavigating(false)\n }\n }, [loadRoute])\n\n const revalidate = useCallback(async () => {\n const to = window.location.pathname + window.location.search\n const controller = new AbortController()\n const dataRes = await fetch(`/_data${to}`, {\n headers: { Accept: 'application/json' },\n signal: controller.signal,\n })\n if (!dataRes.ok) return\n const data = await dataRes.json()\n if (data.redirect) {\n await navigate(data.redirect, { replace: data.redirectReplace })\n return\n }\n setState(prev => ({\n ...prev,\n loaderData: data.loaderData,\n layoutsData: (data.layouts ?? []).map((l: any) => l.loaderData),\n params: data.params ?? prev.params,\n metadata: data.metadata ?? prev.metadata,\n viewport: data.viewport ?? prev.viewport,\n }))\n }, [navigate])\n\n useEffect(() => {\n const handlePop = () => {\n navigatingRef.current?.abort()\n const controller = new AbortController()\n navigatingRef.current = controller\n\n const to = window.location.pathname + window.location.search\n loadRoute(to, controller).catch(err => {\n if (err.name !== 'AbortError') console.error('[router] popstate error:', err)\n })\n }\n window.addEventListener(\"popstate\", handlePop)\n return () => window.removeEventListener(\"popstate\", handlePop)\n }, [loadRoute])\n\n let content: ReactNode\n\n if (state.pendingError) {\n content = state.ErrorPage\n ? <state.ErrorPage {...state.pendingError} />\n : <h1>{state.pendingError.statusCode}</h1>\n } else {\n let tree: ReactNode = (\n <RouteDataContext value={{ loaderData: state.loaderData, params: state.params }}>\n <state.Page data={state.loaderData} params={state.params} url={state.pathname} />\n </RouteDataContext>\n )\n\n for (let i = state.layouts.length - 1; i >= 0; i--) {\n const Layout = state.layouts[i]\n const layoutData = state.layoutsData[i]\n tree = (\n <RouteDataContext value={{ loaderData: layoutData, params: state.params }}>\n <Layout data={layoutData} params={state.params}>{tree}</Layout>\n </RouteDataContext>\n )\n }\n\n content = (\n <DevixErrorBoundary key={state.pathname} ErrorPage={state.ErrorPage}>\n {tree}\n </DevixErrorBoundary>\n )\n }\n\n return (\n <PageMetaContext value={{\n metadata: state.metadata,\n viewport: state.viewport,\n clientEntry,\n }}>\n <HeadSlot metadata={state.metadata} viewport={state.viewport} />\n <RouterContext value={{ ...state, isNavigating, navigate, revalidate, prefetchRoute }}>\n {content}\n </RouterContext>\n </PageMetaContext>\n )\n}", "import { Metadata, MetadataIcon, Viewport } from \"../types\";\nimport { ReactNode } from \"react\";\n\ntype MetaTag =\n | { tag: 'title'; children: string }\n | { tag: 'meta'; name?: string; property?: string; content: string }\n | { tag: 'link'; rel: string; href: string; hrefLang?: string; type?: string; sizes?: string }\n\nfunction collectTags(metadata: Metadata, viewport?: Viewport): MetaTag[] {\n const tags: MetaTag[] = []\n\n if (metadata.title)\n tags.push({ tag: 'title', children: metadata.title })\n if (metadata.description)\n tags.push({ tag: 'meta', name: 'description', content: metadata.description })\n if (metadata.keywords?.length)\n tags.push({ tag: 'meta', name: 'keywords', content: metadata.keywords.join(', ') })\n\n const ogTitle = metadata.og?.title ?? metadata.title\n if (ogTitle) tags.push({ tag: 'meta', property: 'og:title', content: ogTitle })\n const ogDesc = metadata.og?.description ?? metadata.description\n if (ogDesc) tags.push({ tag: 'meta', property: 'og:description', content: ogDesc })\n if (metadata.og?.image) tags.push({ tag: 'meta', property: 'og:image', content: metadata.og.image })\n if (metadata.og?.type) tags.push({ tag: 'meta', property: 'og:type', content: metadata.og.type })\n if (metadata.og?.url) tags.push({ tag: 'meta', property: 'og:url', content: metadata.og.url })\n\n const twTitle = metadata.twitter?.title ?? metadata.title\n if (twTitle) tags.push({ tag: 'meta', name: 'twitter:title', content: twTitle })\n const twDesc = metadata.twitter?.description ?? metadata.description\n if (twDesc) tags.push({ tag: 'meta', name: 'twitter:description', content: twDesc })\n if (metadata.twitter?.card) tags.push({\n tag: 'meta', name: 'twitter:card', content:\n metadata.twitter.card\n })\n if (metadata.twitter?.image) tags.push({\n tag: 'meta', name: 'twitter:image', content:\n metadata.twitter.image\n })\n if (metadata.twitter?.creator) tags.push({\n tag: 'meta', name: 'twitter:creator', content:\n metadata.twitter.creator\n })\n\n if (metadata.canonical) tags.push({ tag: 'link', rel: 'canonical', href: metadata.canonical })\n if (metadata.robots) tags.push({ tag: 'meta', name: 'robots', content: metadata.robots })\n if (metadata.alternates) {\n for (const [lang, href] of Object.entries(metadata.alternates))\n tags.push({ tag: 'link', rel: 'alternate', href, hrefLang: lang })\n }\n\n if (metadata.icons) {\n const raw = Array.isArray(metadata.icons) ? metadata.icons : [metadata.icons]\n for (const icon of raw) {\n const resolved: MetadataIcon = typeof icon === 'string' ? { href: icon } : icon\n tags.push({\n tag: 'link',\n rel: resolved.rel ?? 'icon',\n href: resolved.href,\n ...(resolved.type && { type: resolved.type }),\n ...(resolved.sizes && { sizes: resolved.sizes }),\n })\n }\n }\n\n if (viewport) {\n const parts: string[] = []\n if (viewport.width !== undefined) parts.push(`width=${viewport.width}`)\n if (viewport.initialScale !== undefined) parts.push(`initial-scale=${viewport.initialScale}`)\n if (viewport.maximumScale !== undefined) parts.push(`maximum-scale=${viewport.maximumScale}`)\n if (viewport.userScalable !== undefined) parts.push(`user-scalable=${viewport.userScalable ? 'yes' :\n 'no'}`)\n if (parts.length) tags.push({ tag: 'meta', name: 'viewport', content: parts.join(', ') })\n if (viewport.themeColor) tags.push({\n tag: 'meta', name: 'theme-color', content: viewport.themeColor\n })\n }\n\n return tags\n}\n\nexport function HeadSlot({ metadata, viewport }: { metadata: Metadata | null, viewport?: Viewport }) {\n if (typeof window === 'undefined' || !metadata) return null\n return <>{buildHeadNodes(metadata, viewport)}</>\n}\n\nexport function buildHeadNodes(metadata: Metadata, viewport?: Viewport): ReactNode {\n const tags = collectTags(metadata, viewport)\n\n return <>\n {tags.map((t, i) => {\n if (t.tag === 'title') return <title key={i}>{t.children}</title>\n if (t.tag === 'link') return <link key={i} rel={t.rel} href={t.href} hrefLang={t.hrefLang} type={t.type} sizes={t.sizes} />\n return <meta key={i} name={t.name} property={t.property} content={t.content} />\n })}\n </>\n}", "import {createContext, Context, ComponentType} from \"react\";\nimport {Metadata, Viewport} from \"../types\";\nimport {LayoutProps, PageProps} from \"../server/types\";\n\nexport interface NavigateOptions {\n replace?: boolean\n viewTransition?: boolean\n}\n\nexport interface RouterContextValue {\n pathname: string\n params: Record<string, string>\n loaderData: unknown\n layoutsData: unknown[]\n Page: ComponentType<PageProps>\n layouts: ComponentType<LayoutProps>[]\n metadata: Metadata | null\n viewport?: Viewport\n navigate: (to: string, options?: NavigateOptions) => Promise<void>\n revalidate: () => Promise<void>\n prefetchRoute: (href: string) => void\n isNavigating: boolean\n}\n\nexport interface PageMetaContextValue {\n metadata: Metadata | null\n viewport?: Viewport\n clientEntry?: string\n}\n\nexport interface RouteDataContextValue {\n loaderData: unknown\n params: Record<string, string>\n}\n\nconst g = globalThis as any\n\ng.__devix_RouterContext__ ??= createContext<RouterContextValue | null>(null)\nexport const RouterContext: Context<RouterContextValue | null> = g.__devix_RouterContext__\n\ng.__devix_PageMetaContext__ ??= createContext<PageMetaContextValue | null>(null)\ng.__devix_RouteDataContext__ ??= createContext<RouteDataContextValue | null>(null)\n\nexport const PageMetaContext: Context<PageMetaContextValue | null> = g.__devix_PageMetaContext__\nexport const RouteDataContext: Context<RouteDataContextValue | null> = g.__devix_RouteDataContext__\n\n", "import {Component, ComponentType, ReactNode} from \"react\";\nimport {ErrorProps} from \"../server/types\";\n\ninterface Props {\n ErrorPage?: ComponentType<ErrorProps>\n children: ReactNode\n}\n\ninterface State {\n error: ErrorProps | null\n}\n\nexport class DevixErrorBoundary extends Component<Props, State> {\n state: State = { error: null }\n\n static getDerivedStateFromError(err: unknown): State {\n if (err instanceof DevixError) {\n return {\n error: {statusCode: err.statusCode, message: err.message}\n }\n }\n return {\n error: {statusCode: 500, message: err instanceof Error ? err.message : 'Unknown error'}\n }\n }\n\n render() {\n if (this.state.error && this.props.ErrorPage) {\n return <this.props.ErrorPage {...this.state.error} />\n }\n if (this.state.error) {\n return <h1>{this.state.error.statusCode}</h1>\n }\n return this.props.children\n }\n}\n\nexport class DevixError extends Error {\n statusCode: number\n constructor(statusCode: number, message: string) {\n super(message)\n this.statusCode = statusCode\n }\n}\n", "import { AnchorHTMLAttributes, MouseEventHandler, useCallback, useContext, useRef } from \"react\"\nimport { NavigateOptions, RouterContext } from './context'\n\ninterface LinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {\n href: string\n prefetch?: 'hover' | 'none'\n replace?: boolean\n viewTransition?: boolean\n}\n\nfunction resolveHref(href: string): string {\n if (href.startsWith('/') || href.startsWith('http')) return href\n const base = window.location.pathname.endsWith('/')\n ? window.location.href\n : window.location.href + '/'\n const resolved = new URL(href, base).pathname\n return resolved.length > 1 ? resolved.replace(/\\/$/, '') : resolved\n}\n\nexport function Link({ href, prefetch = 'hover', replace = false, viewTransition = false, children, ...props }: LinkProps) {\n const router = useContext(RouterContext)\n const hoverTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)\n\n const cancelHoverTimer = useCallback(() => {\n if (hoverTimerRef.current !== null) {\n clearTimeout(hoverTimerRef.current)\n hoverTimerRef.current = null\n }\n }, [])\n\n const triggerPrefetch = useCallback(() => {\n if (!router || prefetch === 'none') return\n router.prefetchRoute(resolveHref(href))\n }, [href, prefetch, router])\n\n const handleMouseEnter = useCallback(() => {\n if (prefetch === 'none') return\n hoverTimerRef.current = setTimeout(triggerPrefetch, 50)\n }, [prefetch, triggerPrefetch])\n\n const handleMouseLeave = useCallback(() => {\n cancelHoverTimer()\n }, [cancelHoverTimer])\n\n const handleTouchStart = useCallback(() => {\n cancelHoverTimer()\n triggerPrefetch()\n }, [cancelHoverTimer, triggerPrefetch])\n\n const handleClick: MouseEventHandler<HTMLAnchorElement> = (e) => {\n cancelHoverTimer()\n if (!router) return\n if (!e.ctrlKey && !e.metaKey && !e.shiftKey && e.button === 0) {\n e.preventDefault()\n const options: NavigateOptions = { replace, viewTransition }\n router.navigate(resolveHref(href), options)\n }\n }\n\n return (\n <a\n href={href}\n onClick={handleClick}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n onTouchStart={handleTouchStart}\n {...props}\n >\n {children}\n </a>\n )\n}", "export interface CookieOptions {\n httpOnly?: boolean\n secure?: boolean\n sameSite?: 'Strict' | 'Lax' | 'None'\n maxAge?: number\n expires?: Date\n path?: string\n domain?: string\n}\n\nexport function getCookie(req: Request, name: string): string | undefined {\n const header = req.headers.get('cookie')\n if (!header) return undefined\n for (const part of header.split(';')) {\n const [key, ...rest] = part.trim().split('=')\n if (key.trim() === name) return decodeURIComponent(rest.join('='))\n }\n return undefined\n}\n\nexport function setCookie(headers: Headers, name: string, value: string, options: CookieOptions = {}): void {\n let cookie = `${name}=${encodeURIComponent(value)}; Path=${options.path ?? '/'}`\n if (options.domain) cookie += `; Domain=${options.domain}`\n if (options.maxAge !== undefined) cookie += `; Max-Age=${options.maxAge}`\n if (options.expires) cookie += `; Expires=${options.expires.toUTCString()}`\n if (options.httpOnly) cookie += `; HttpOnly`\n if (options.secure) cookie += `; Secure`\n if (options.sameSite) cookie += `; SameSite=${options.sameSite}`\n headers.append('Set-Cookie', cookie)\n}\n\nexport function deleteCookie(headers: Headers, name: string, options: Pick<CookieOptions, 'path' | 'domain'> = {}): void {\n setCookie(headers, name, '', {...options, maxAge: 0, expires: new Date(0)})\n}\n", "export type JsonResponse<T = unknown, S extends number = number> = Response & {\n readonly __body: T\n readonly __status: S\n}\n\nexport function json<const T>(data: T): JsonResponse<T, 200>\nexport function json<const T, const S extends number>(data: T, status: S): JsonResponse<T, S>\nexport function json<const T>(data: T, status: number = 200): JsonResponse<T, any> {\n return new Response(JSON.stringify(data), {\n status,\n headers: {'Content-Type': 'application/json'},\n }) as JsonResponse<T, any>\n}\n\nexport const text = (body: string, status = 200): Response =>\n new Response(body, {status, headers: {'Content-Type': 'text/plain; charset=utf-8'}})\n\nconst REDIRECT_BRAND = Symbol('devix.redirect')\n\nexport interface RedirectOptions {\n status?: number\n replace?: boolean\n}\n\nexport interface Redirect {\n readonly [REDIRECT_BRAND]: true\n readonly url: string\n readonly status: number\n readonly replace: boolean\n}\n\nexport function redirect(url: string, statusOrOptions?: number | RedirectOptions): Redirect {\n const status = typeof statusOrOptions === 'number' ? statusOrOptions : (statusOrOptions?.status ?? 302)\n const replace = typeof statusOrOptions === 'object' ? (statusOrOptions?.replace ?? false) : false\n return {[REDIRECT_BRAND]: true, url, status, replace} as Redirect\n}\n\nexport function isRedirect(value: unknown): value is Redirect {\n return typeof value === 'object' && value !== null && REDIRECT_BRAND in value\n}\n\nconst ERROR_BRAND = Symbol('devix.loaderError')\n\nexport interface RouteError {\n readonly [ERROR_BRAND]: true\n readonly statusCode: number\n readonly message: string\n readonly data?: unknown\n}\n\nexport function error(statusCode: number, message: string, data?: unknown): RouteError {\n return { [ERROR_BRAND]: true, statusCode, message, data } as RouteError\n}\n\nexport function isLoaderError(value: unknown): value is RouteError {\n return typeof value === 'object' && value !== null && ERROR_BRAND in value\n}\n", "export const HANDLER_BRAND = '__devix_handler__' as const\n\nexport interface DevixHandler<TBody = undefined, TReturn = unknown> {\n readonly [HANDLER_BRAND]: true\n readonly fn: (...args: any[]) => any\n readonly __body: TBody\n readonly __return: TReturn\n}\n\ntype ExtractBody<TFn> = TFn extends (body: infer B) => any ? B : undefined\n\nexport function createHandler<TFn extends (...args: any[]) => any>(\n fn: TFn,\n): DevixHandler<ExtractBody<TFn>, Awaited<ReturnType<TFn>>> {\n return {[HANDLER_BRAND]: true, fn} as unknown as DevixHandler<ExtractBody<TFn>, Awaited<ReturnType<TFn>>>\n}\n", "export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS'\n\nexport class FetchError<E = unknown> extends Error {\n constructor(\n public readonly status: number,\n public readonly statusText: string,\n public readonly response: Response,\n public readonly body?: E,\n ) {\n super(`HTTP ${status}: ${statusText}`)\n this.name = 'FetchError'\n }\n}\n", "export {useRouter, useNavigate, useRevalidate, useParams, useLoaderData, RouterProvider} from \"./router-provider\"\n\nexport {Link} from \"./link\"\n\nexport type { Metadata, MetadataIcon, Viewport, LoaderContext, LoaderContextWithGuard, LoaderFunction, GuardFunction } from '../types'\nexport type { NavigateOptions } from './context'\nexport type { PageProps, LayoutProps, PageModule, LayoutModule, ErrorProps } from '../server/types'\nexport type { RouteHandler, RouteResult } from './api-context'\nexport {getCookie, setCookie, deleteCookie} from '../utils/cookies'\nexport type {CookieOptions} from '../utils/cookies'\nexport {json, text, redirect, error} from '../utils/response'\nexport type {JsonResponse, Redirect, RedirectOptions, RouteError} from '../utils/response'\nexport {createHandler} from './create-handler'\nexport type {DevixHandler} from './create-handler'\nexport {FetchError} from './fetch'\nexport type {HttpMethod} from './fetch'\n\nimport {FetchError, type HttpMethod} from './fetch'\n\nexport interface ApiRoutes {}\n\ntype ApiKey<M extends HttpMethod, P extends string> = `${M} ${P}`\ntype MatchingKey<M extends HttpMethod, P extends string> = {\n [K in keyof ApiRoutes]: K extends ApiKey<M, P> ? K : never\n}[keyof ApiRoutes]\ntype RouteData<M extends HttpMethod, P extends string> = ApiRoutes[MatchingKey<M, P>]\ntype AllApiPaths = {\n [K in keyof ApiRoutes]: K extends `${HttpMethod} ${infer P}` ? P : never\n}[keyof ApiRoutes]\ntype ApiPath = AllApiPaths | (string & {})\ntype ExtractBody<D> = D extends { __body: infer B } ? B : never\ntype ExtractResponse<D> = D extends { __response: infer R } ? R : D\ntype InferBody<M extends HttpMethod, P extends string> = ExtractBody<RouteData<M, P>>\ntype InferResult<M extends HttpMethod, P extends string> = ExtractResponse<RouteData<M, P>>\ntype BodyOption<M extends HttpMethod, P extends string> = [InferBody<M, P>] extends [never] ? unknown : InferBody<M, P>\n\nexport interface FetchOptions<M extends HttpMethod = 'GET', P extends string = string> {\n method?: M\n body?: BodyOption<M, P>\n headers?: HeadersInit\n signal?: AbortSignal\n}\n\nexport async function $fetch<P extends ApiPath = ApiPath, M extends HttpMethod = 'GET'>(\n path: P & string,\n options?: FetchOptions<M, P>\n): Promise<InferResult<M, P>> {\n const method = options?.method ?? 'GET'\n const headers = new Headers(options?.headers)\n\n let body: BodyInit | undefined\n if (options?.body !== undefined) {\n if (options.body instanceof FormData || options.body instanceof Blob || options.body instanceof ArrayBuffer) {\n body = options.body\n } else {\n body = JSON.stringify(options.body)\n if (!headers.has('Content-Type')) {\n headers.set('Content-Type', 'application/json')\n }\n }\n }\n\n const response = await fetch(path, {method, headers, body, signal: options?.signal})\n\n if (!response.ok) {\n const contentType = response.headers.get('Content-Type') ?? ''\n const errorBody = contentType.includes('application/json')\n ? await response.json()\n : undefined\n throw new FetchError(response.status, response.statusText, response, errorBody)\n }\n\n const contentType = response.headers.get('Content-Type') ?? ''\n if (contentType.includes('application/json')) {\n return response.json() as Promise<InferResult<M, P>>\n }\n\n return response.text() as unknown as Promise<InferResult<M, P>>\n}\n"],
|
|
4
|
+
"sourcesContent": ["import { ComponentType, ReactNode, useCallback, useContext, useEffect, useRef, useState } from \"react\";\nimport { RouterContext } from 'virtual:devix/context'\nimport { ErrorProps, LayoutProps, PageProps } from \"../server/types\";\nimport { Metadata, Viewport } from \"../types\";\nimport { getDefaultErrorPage, loadErrorPage, matchClientRoute } from \"virtual:devix/client-routes\";\nimport { HeadSlot } from \"./head\";\nimport { NavigateOptions, PageMetaContext, RouteDataContext } from \"./context\";\nimport { DevixErrorBoundary } from \"./error-boundary\";\nimport type { Redirect } from \"../utils/response\";\n\ninterface RouteState {\n pathname: string\n params: Record<string, string>\n loaderData: unknown\n layoutsData: unknown[]\n Page: ComponentType<PageProps>\n layouts: ComponentType<LayoutProps>[]\n metadata: Metadata | null\n viewport?: Viewport\n pendingError?: ErrorProps\n ErrorPage?: ComponentType<ErrorProps>\n}\n\nexport function useRouter() {\n return useContext(RouterContext)\n}\n\nconst noopNavigate = () => Promise.resolve()\nconst noopRevalidate = () => Promise.resolve()\n\nexport function useNavigate() {\n const ctx = useContext(RouterContext)\n return ctx?.navigate ?? noopNavigate\n}\n\nexport function useRevalidate() {\n const ctx = useContext(RouterContext)\n return ctx?.revalidate ?? noopRevalidate\n}\n\nexport function useParams<T extends Record<string, string>>() {\n const ctx = useContext(RouteDataContext)\n if (!ctx) throw new Error(\"useParams must be used within a route or layout\")\n return ctx.params as T\n}\n\ntype LoaderReturnType<T> = T extends (...args: any[]) => Promise<infer R>\n ? [Exclude<R, Redirect | void | undefined>] extends [never] ? undefined : Exclude<R, Redirect | void | undefined>\n : T extends (...args: any[]) => infer R\n ? [Exclude<R, Redirect | void | undefined>] extends [never] ? undefined : Exclude<R, Redirect | void | undefined>\n : T\n\nexport function useLoaderData<T>() {\n const ctx = useContext(RouteDataContext)\n if (!ctx) throw new Error(\"useLoaderData must be used within a route or layout\")\n return ctx.loaderData as LoaderReturnType<T>\n}\n\ninterface PrefetchEntry {\n promise: Promise<{ pageMod: any; layoutMods: any[]; data: any } | null>\n controller: AbortController\n}\n\ninterface RouterProviderProps {\n initialData: unknown\n initialParams: Record<string, string>\n initialPage: ComponentType<PageProps>\n initialLayouts?: ComponentType<LayoutProps>[]\n initialLayoutsData?: unknown[]\n initialMeta?: Metadata | null\n initialViewport?: Viewport\n initialError?: ErrorProps\n initialErrorPage?: ComponentType<ErrorProps>\n clientEntry: string\n}\n\nexport function RouterProvider({\n initialData,\n initialParams,\n initialPage,\n initialLayouts = [],\n initialLayoutsData = [],\n initialMeta,\n initialViewport,\n initialError,\n initialErrorPage,\n clientEntry,\n}: RouterProviderProps) {\n\n const [state, setState] = useState<RouteState>({\n pathname: window.location.pathname,\n params: initialParams,\n loaderData: initialData,\n layoutsData: initialLayoutsData,\n Page: initialPage,\n layouts: initialLayouts,\n metadata: initialMeta ?? null,\n viewport: initialViewport,\n pendingError: initialError,\n ErrorPage: initialErrorPage,\n })\n\n const navigatingRef = useRef<AbortController | null>(null)\n const [isNavigating, setIsNavigating] = useState(false)\n\n const prefetchCacheRef = useRef<Map<string, PrefetchEntry>>(new Map())\n\n const prefetchRoute = useCallback((href: string) => {\n if (prefetchCacheRef.current.has(href)) return\n const pathname = href.split('?')[0].split('#')[0]\n const matched = matchClientRoute(pathname)\n if (!matched) return\n\n const controller = new AbortController()\n const promise = Promise.all([\n Promise.all([matched.load(), ...matched.loadLayouts.map(l => l())]),\n fetch(`/_data${href}`, { headers: { Accept: 'application/json' }, signal: controller.signal })\n ]).then(async ([[pageMod, ...layoutMods], dataRes]) => {\n if (!dataRes.ok || !pageMod.default) return null\n const data = await dataRes.json()\n return { pageMod, layoutMods, data }\n }).catch(() => null)\n\n const expireTimer = setTimeout(() => {\n controller.abort()\n prefetchCacheRef.current.delete(href)\n }, 3000)\n promise.finally(() => clearTimeout(expireTimer))\n\n prefetchCacheRef.current.set(href, { promise, controller })\n }, [])\n\n const loadRoute = useCallback(async (to: string, controller: AbortController) => {\n const pathname = to.split('?')[0].split('#')[0]\n const matched = matchClientRoute(pathname)\n if (!matched) {\n const ErrorPage = await loadErrorPage() ?? getDefaultErrorPage()\n setState(prev => ({\n ...prev,\n pathname: pathname,\n pendingError: { statusCode: 404, message: 'Not found' },\n ErrorPage: ErrorPage ?? undefined,\n }))\n return\n }\n\n const cached = prefetchCacheRef.current.get(to)\n if (cached) prefetchCacheRef.current.delete(to)\n const prefetched = cached ? await cached.promise : null\n\n if (controller.signal.aborted) return\n\n let pageMod: any, layoutMods: any[], data: any\n\n if (prefetched) {\n ;({ pageMod, layoutMods, data } = prefetched)\n } else {\n const [[pm, ...lm], dataRes] = await Promise.all([\n Promise.all([\n matched.load(),\n ...matched.loadLayouts.map(l => l()),\n ]),\n fetch(`/_data${to}`, {\n headers: { Accept: 'application/json' },\n signal: controller.signal,\n })\n ])\n\n if (controller.signal.aborted) return\n if (!pm.default) return\n\n if (!dataRes.ok) {\n const ct = dataRes.headers.get('Content-Type') ?? ''\n let errorBody: { statusCode?: number; message?: string; data?: unknown } | null = null\n try {\n if (ct.includes('application/json')) errorBody = await dataRes.json()\n else if (ct.includes('text/plain')) errorBody = { message: await dataRes.text() }\n } catch { /* ignorar errores de parsing */ }\n\n const headers: Record<string, string> = {}\n dataRes.headers.forEach((value, key) => { headers[key] = value })\n\n const ErrorPage = await loadErrorPage() ?? getDefaultErrorPage()\n setState(prev => ({\n ...prev,\n pathname,\n pendingError: {\n statusCode: errorBody?.statusCode ?? dataRes.status,\n message: errorBody?.message ?? 'Server error',\n data: errorBody?.data,\n headers,\n },\n ErrorPage: ErrorPage ?? undefined,\n }))\n return\n }\n\n pageMod = pm\n layoutMods = lm\n data = await dataRes.json()\n }\n\n if (data.redirect) {\n if (data.redirectReplace) {\n window.history.replaceState(null, '', data.redirect)\n } else {\n window.history.pushState(null, '', data.redirect)\n }\n await loadRoute(data.redirect, controller)\n return\n }\n\n setState({\n pathname,\n params: data.params ?? {},\n loaderData: data.loaderData,\n layoutsData: (data.layouts ?? []).map((l: any) => l.loaderData),\n Page: pageMod.default,\n layouts: layoutMods.map(m => m.default),\n metadata: data.metadata ?? null,\n viewport: data.viewport,\n })\n\n const hash = to.includes('#') ? to.split('#')[1] : null\n const scrollBehavior = getComputedStyle(document.documentElement).scrollBehavior as ScrollBehavior\n if (hash) {\n requestAnimationFrame(() => {\n document.getElementById(hash)?.scrollIntoView({ behavior: scrollBehavior })\n })\n } else {\n window.scrollTo({ top: 0, behavior: scrollBehavior })\n }\n }, [])\n\n const navigate = useCallback(async (to: string, options?: NavigateOptions) => {\n navigatingRef.current?.abort()\n const controller = new AbortController()\n navigatingRef.current = controller\n\n setIsNavigating(true)\n const run = async () => {\n window.history[options?.replace ? 'replaceState' : 'pushState'](null, '', to)\n await loadRoute(to, controller)\n }\n try {\n if (options?.viewTransition && 'startViewTransition' in document) {\n await (document as any).startViewTransition(run).finished\n } else {\n await run()\n }\n } finally {\n if (!controller.signal.aborted) setIsNavigating(false)\n }\n }, [loadRoute])\n\n const revalidate = useCallback(async () => {\n const to = window.location.pathname + window.location.search\n const controller = new AbortController()\n const dataRes = await fetch(`/_data${to}`, {\n headers: { Accept: 'application/json' },\n signal: controller.signal,\n })\n if (!dataRes.ok) return\n const data = await dataRes.json()\n if (data.redirect) {\n await navigate(data.redirect, { replace: data.redirectReplace })\n return\n }\n setState(prev => ({\n ...prev,\n loaderData: data.loaderData,\n layoutsData: (data.layouts ?? []).map((l: any) => l.loaderData),\n params: data.params ?? prev.params,\n metadata: data.metadata ?? prev.metadata,\n viewport: data.viewport ?? prev.viewport,\n }))\n }, [navigate])\n\n useEffect(() => {\n const handlePop = () => {\n navigatingRef.current?.abort()\n const controller = new AbortController()\n navigatingRef.current = controller\n\n const to = window.location.pathname + window.location.search\n loadRoute(to, controller).catch(err => {\n if (err.name !== 'AbortError') console.error('[router] popstate error:', err)\n })\n }\n window.addEventListener(\"popstate\", handlePop)\n return () => window.removeEventListener(\"popstate\", handlePop)\n }, [loadRoute])\n\n let content: ReactNode\n\n if (state.pendingError) {\n content = state.ErrorPage\n ? <state.ErrorPage {...state.pendingError} />\n : <h1>{state.pendingError.statusCode}</h1>\n } else {\n let tree: ReactNode = (\n <RouteDataContext value={{ loaderData: state.loaderData, params: state.params }}>\n <state.Page data={state.loaderData} params={state.params} url={state.pathname} />\n </RouteDataContext>\n )\n\n for (let i = state.layouts.length - 1; i >= 0; i--) {\n const Layout = state.layouts[i]\n const layoutData = state.layoutsData[i]\n tree = (\n <RouteDataContext value={{ loaderData: layoutData, params: state.params }}>\n <Layout data={layoutData} params={state.params}>{tree}</Layout>\n </RouteDataContext>\n )\n }\n\n content = (\n <DevixErrorBoundary key={state.pathname} ErrorPage={state.ErrorPage}>\n {tree}\n </DevixErrorBoundary>\n )\n }\n\n return (\n <PageMetaContext value={{\n metadata: state.metadata,\n viewport: state.viewport,\n clientEntry,\n }}>\n <HeadSlot metadata={state.metadata} viewport={state.viewport} />\n <RouterContext value={{ ...state, isNavigating, navigate, revalidate, prefetchRoute }}>\n {content}\n </RouterContext>\n </PageMetaContext>\n )\n}", "import { Metadata, MetadataIcon, Viewport } from \"../types\";\nimport { ReactNode } from \"react\";\n\ntype MetaTag =\n | { tag: 'title'; children: string }\n | { tag: 'meta'; name?: string; property?: string; content: string }\n | { tag: 'link'; rel: string; href: string; hrefLang?: string; type?: string; sizes?: string }\n\nfunction collectTags(metadata: Metadata, viewport?: Viewport): MetaTag[] {\n const tags: MetaTag[] = []\n\n if (metadata.title)\n tags.push({ tag: 'title', children: metadata.title })\n if (metadata.description)\n tags.push({ tag: 'meta', name: 'description', content: metadata.description })\n if (metadata.keywords?.length)\n tags.push({ tag: 'meta', name: 'keywords', content: metadata.keywords.join(', ') })\n\n const ogTitle = metadata.og?.title ?? metadata.title\n if (ogTitle) tags.push({ tag: 'meta', property: 'og:title', content: ogTitle })\n const ogDesc = metadata.og?.description ?? metadata.description\n if (ogDesc) tags.push({ tag: 'meta', property: 'og:description', content: ogDesc })\n if (metadata.og?.image) tags.push({ tag: 'meta', property: 'og:image', content: metadata.og.image })\n if (metadata.og?.type) tags.push({ tag: 'meta', property: 'og:type', content: metadata.og.type })\n if (metadata.og?.url) tags.push({ tag: 'meta', property: 'og:url', content: metadata.og.url })\n\n const twTitle = metadata.twitter?.title ?? metadata.title\n if (twTitle) tags.push({ tag: 'meta', name: 'twitter:title', content: twTitle })\n const twDesc = metadata.twitter?.description ?? metadata.description\n if (twDesc) tags.push({ tag: 'meta', name: 'twitter:description', content: twDesc })\n if (metadata.twitter?.card) tags.push({\n tag: 'meta', name: 'twitter:card', content:\n metadata.twitter.card\n })\n if (metadata.twitter?.image) tags.push({\n tag: 'meta', name: 'twitter:image', content:\n metadata.twitter.image\n })\n if (metadata.twitter?.creator) tags.push({\n tag: 'meta', name: 'twitter:creator', content:\n metadata.twitter.creator\n })\n\n if (metadata.canonical) tags.push({ tag: 'link', rel: 'canonical', href: metadata.canonical })\n if (metadata.robots) tags.push({ tag: 'meta', name: 'robots', content: metadata.robots })\n if (metadata.alternates) {\n for (const [lang, href] of Object.entries(metadata.alternates))\n tags.push({ tag: 'link', rel: 'alternate', href, hrefLang: lang })\n }\n\n if (metadata.icons) {\n const raw = Array.isArray(metadata.icons) ? metadata.icons : [metadata.icons]\n for (const icon of raw) {\n const resolved: MetadataIcon = typeof icon === 'string' ? { href: icon } : icon\n tags.push({\n tag: 'link',\n rel: resolved.rel ?? 'icon',\n href: resolved.href,\n ...(resolved.type && { type: resolved.type }),\n ...(resolved.sizes && { sizes: resolved.sizes }),\n })\n }\n }\n\n if (viewport) {\n const parts: string[] = []\n if (viewport.width !== undefined) parts.push(`width=${viewport.width}`)\n if (viewport.initialScale !== undefined) parts.push(`initial-scale=${viewport.initialScale}`)\n if (viewport.maximumScale !== undefined) parts.push(`maximum-scale=${viewport.maximumScale}`)\n if (viewport.userScalable !== undefined) parts.push(`user-scalable=${viewport.userScalable ? 'yes' :\n 'no'}`)\n if (parts.length) tags.push({ tag: 'meta', name: 'viewport', content: parts.join(', ') })\n if (viewport.themeColor) tags.push({\n tag: 'meta', name: 'theme-color', content: viewport.themeColor\n })\n }\n\n return tags\n}\n\nexport function HeadSlot({ metadata, viewport }: { metadata: Metadata | null, viewport?: Viewport }) {\n if (typeof window === 'undefined' || !metadata) return null\n return <>{buildHeadNodes(metadata, viewport)}</>\n}\n\nexport function buildHeadNodes(metadata: Metadata, viewport?: Viewport): ReactNode {\n const tags = collectTags(metadata, viewport)\n\n return <>\n {tags.map((t, i) => {\n if (t.tag === 'title') return <title key={i}>{t.children}</title>\n if (t.tag === 'link') return <link key={i} rel={t.rel} href={t.href} hrefLang={t.hrefLang} type={t.type} sizes={t.sizes} />\n return <meta key={i} name={t.name} property={t.property} content={t.content} />\n })}\n </>\n}", "import {createContext, Context, ComponentType} from \"react\";\nimport {Metadata, Viewport} from \"../types\";\nimport {LayoutProps, PageProps} from \"../server/types\";\n\nexport interface NavigateOptions {\n replace?: boolean\n viewTransition?: boolean\n}\n\nexport interface RouterContextValue {\n pathname: string\n params: Record<string, string>\n loaderData: unknown\n layoutsData: unknown[]\n Page: ComponentType<PageProps>\n layouts: ComponentType<LayoutProps>[]\n metadata: Metadata | null\n viewport?: Viewport\n navigate: (to: string, options?: NavigateOptions) => Promise<void>\n revalidate: () => Promise<void>\n prefetchRoute: (href: string) => void\n isNavigating: boolean\n}\n\nexport interface PageMetaContextValue {\n metadata: Metadata | null\n viewport?: Viewport\n clientEntry?: string\n}\n\nexport interface RouteDataContextValue {\n loaderData: unknown\n params: Record<string, string>\n}\n\nconst g = globalThis as any\n\ng.__devix_RouterContext__ ??= createContext<RouterContextValue | null>(null)\nexport const RouterContext: Context<RouterContextValue | null> = g.__devix_RouterContext__\n\ng.__devix_PageMetaContext__ ??= createContext<PageMetaContextValue | null>(null)\ng.__devix_RouteDataContext__ ??= createContext<RouteDataContextValue | null>(null)\n\nexport const PageMetaContext: Context<PageMetaContextValue | null> = g.__devix_PageMetaContext__\nexport const RouteDataContext: Context<RouteDataContextValue | null> = g.__devix_RouteDataContext__\n\n", "import {Component, ComponentType, ReactNode} from \"react\";\nimport {ErrorProps} from \"../server/types\";\n\ninterface Props {\n ErrorPage?: ComponentType<ErrorProps>\n children: ReactNode\n}\n\ninterface State {\n error: ErrorProps | null\n}\n\nexport class DevixErrorBoundary extends Component<Props, State> {\n state: State = { error: null }\n\n static getDerivedStateFromError(err: unknown): State {\n if (err instanceof DevixError) {\n return {\n error: {statusCode: err.statusCode, message: err.message}\n }\n }\n return {\n error: {statusCode: 500, message: err instanceof Error ? err.message : 'Unknown error'}\n }\n }\n\n render() {\n if (this.state.error && this.props.ErrorPage) {\n return <this.props.ErrorPage {...this.state.error} />\n }\n if (this.state.error) {\n return <h1>{this.state.error.statusCode}</h1>\n }\n return this.props.children\n }\n}\n\nexport class DevixError extends Error {\n statusCode: number\n constructor(statusCode: number, message: string) {\n super(message)\n this.statusCode = statusCode\n }\n}\n", "import { AnchorHTMLAttributes, MouseEventHandler, useCallback, useContext, useRef } from \"react\"\nimport { NavigateOptions, RouterContext } from './context'\n\ninterface LinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {\n href: string\n prefetch?: 'hover' | 'none'\n replace?: boolean\n viewTransition?: boolean\n}\n\nfunction resolveHref(href: string): string {\n if (href.startsWith('/') || href.startsWith('http')) return href\n const base = window.location.pathname.endsWith('/')\n ? window.location.href\n : window.location.href + '/'\n const resolved = new URL(href, base).pathname\n return resolved.length > 1 ? resolved.replace(/\\/$/, '') : resolved\n}\n\nexport function Link({ href, prefetch = 'hover', replace = false, viewTransition = false, children, ...props }: LinkProps) {\n const router = useContext(RouterContext)\n const hoverTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)\n\n const cancelHoverTimer = useCallback(() => {\n if (hoverTimerRef.current !== null) {\n clearTimeout(hoverTimerRef.current)\n hoverTimerRef.current = null\n }\n }, [])\n\n const triggerPrefetch = useCallback(() => {\n if (!router || prefetch === 'none') return\n router.prefetchRoute(resolveHref(href))\n }, [href, prefetch, router])\n\n const handleMouseEnter = useCallback(() => {\n if (prefetch === 'none') return\n hoverTimerRef.current = setTimeout(triggerPrefetch, 50)\n }, [prefetch, triggerPrefetch])\n\n const handleMouseLeave = useCallback(() => {\n cancelHoverTimer()\n }, [cancelHoverTimer])\n\n const handleTouchStart = useCallback(() => {\n cancelHoverTimer()\n triggerPrefetch()\n }, [cancelHoverTimer, triggerPrefetch])\n\n const handleClick: MouseEventHandler<HTMLAnchorElement> = (e) => {\n cancelHoverTimer()\n if (!router) return\n if (!e.ctrlKey && !e.metaKey && !e.shiftKey && e.button === 0) {\n e.preventDefault()\n const options: NavigateOptions = { replace, viewTransition }\n router.navigate(resolveHref(href), options)\n }\n }\n\n return (\n <a\n href={href}\n onClick={handleClick}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n onTouchStart={handleTouchStart}\n {...props}\n >\n {children}\n </a>\n )\n}", "export interface CookieOptions {\n httpOnly?: boolean\n secure?: boolean\n sameSite?: 'Strict' | 'Lax' | 'None'\n maxAge?: number\n expires?: Date\n path?: string\n domain?: string\n}\n\nexport function getCookie(req: Request, name: string): string | undefined {\n const header = req.headers.get('cookie')\n if (!header) return undefined\n for (const part of header.split(';')) {\n const [key, ...rest] = part.trim().split('=')\n if (key.trim() === name) return decodeURIComponent(rest.join('='))\n }\n return undefined\n}\n\nexport function setCookie(headers: Headers, name: string, value: string, options: CookieOptions = {}): void {\n let cookie = `${name}=${encodeURIComponent(value)}; Path=${options.path ?? '/'}`\n if (options.domain) cookie += `; Domain=${options.domain}`\n if (options.maxAge !== undefined) cookie += `; Max-Age=${options.maxAge}`\n if (options.expires) cookie += `; Expires=${options.expires.toUTCString()}`\n if (options.httpOnly) cookie += `; HttpOnly`\n if (options.secure) cookie += `; Secure`\n if (options.sameSite) cookie += `; SameSite=${options.sameSite}`\n headers.append('Set-Cookie', cookie)\n}\n\nexport function deleteCookie(headers: Headers, name: string, options: Pick<CookieOptions, 'path' | 'domain'> = {}): void {\n setCookie(headers, name, '', {...options, maxAge: 0, expires: new Date(0)})\n}\n", "export type JsonResponse<T = unknown, S extends number = number> = Response & {\n readonly __body: T\n readonly __status: S\n}\n\nexport function json<const T>(data: T): JsonResponse<T, 200>\nexport function json<const T, const S extends number>(data: T, status: S): JsonResponse<T, S>\nexport function json<const T>(data: T, status: number = 200): JsonResponse<T, any> {\n return new Response(JSON.stringify(data), {\n status,\n headers: {'Content-Type': 'application/json'},\n }) as JsonResponse<T, any>\n}\n\nexport const text = (body: string, status = 200): Response =>\n new Response(body, {status, headers: {'Content-Type': 'text/plain; charset=utf-8'}})\n\nconst REDIRECT_BRAND = Symbol('devix.redirect')\n\nexport interface RedirectOptions {\n status?: number\n replace?: boolean\n}\n\nexport interface Redirect {\n readonly [REDIRECT_BRAND]: true\n readonly url: string\n readonly status: number\n readonly replace: boolean\n}\n\nexport function redirect(url: string, statusOrOptions?: number | RedirectOptions): Redirect {\n const status = typeof statusOrOptions === 'number' ? statusOrOptions : (statusOrOptions?.status ?? 302)\n const replace = typeof statusOrOptions === 'object' ? (statusOrOptions?.replace ?? false) : false\n return {[REDIRECT_BRAND]: true, url, status, replace} as Redirect\n}\n\nexport function isRedirect(value: unknown): value is Redirect {\n return typeof value === 'object' && value !== null && REDIRECT_BRAND in value\n}\n\nconst ERROR_BRAND = Symbol('devix.loaderError')\n\nexport interface RouteError {\n readonly [ERROR_BRAND]: true\n readonly statusCode: number\n readonly message: string\n readonly data?: unknown\n}\n\nexport function error(statusCode: number, message: string, data?: unknown): RouteError {\n return { [ERROR_BRAND]: true, statusCode, message, data } as RouteError\n}\n\nexport function isLoaderError(value: unknown): value is RouteError {\n return typeof value === 'object' && value !== null && ERROR_BRAND in value\n}\n", "export const HANDLER_BRAND = '__devix_handler__' as const\n\nexport interface DevixHandler<TBody = undefined, TReturn = unknown> {\n readonly [HANDLER_BRAND]: true\n readonly fn: (...args: any[]) => any\n readonly __body: TBody\n readonly __return: TReturn\n}\n\ntype ExtractBody<TFn> = TFn extends (body: infer B) => any ? B : undefined\n\nexport function createHandler<TFn extends (...args: any[]) => any>(\n fn: TFn,\n): DevixHandler<ExtractBody<TFn>, Awaited<ReturnType<TFn>>> {\n return {[HANDLER_BRAND]: true, fn} as unknown as DevixHandler<ExtractBody<TFn>, Awaited<ReturnType<TFn>>>\n}\n", "export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS'\n\nexport class FetchError<E = unknown> extends Error {\n constructor(\n public readonly status: number,\n public readonly statusText: string,\n public readonly response: Response,\n public readonly body?: E,\n ) {\n super(`HTTP ${status}: ${statusText}`)\n this.name = 'FetchError'\n }\n}\n", "export {useRouter, useNavigate, useRevalidate, useParams, useLoaderData, RouterProvider} from \"./router-provider\"\n\nexport {Link} from \"./link\"\n\nexport type { Metadata, MetadataIcon, Viewport, LoaderContext, LoaderContextWithGuard, LoaderFunction, GuardFunction } from '../types'\nexport type { NavigateOptions } from './context'\nexport type { PageProps, LayoutProps, PageModule, LayoutModule, ErrorProps } from '../server/types'\nexport type { RouteHandler, RouteResult } from './api-context'\nexport {getCookie, setCookie, deleteCookie} from '../utils/cookies'\nexport type {CookieOptions} from '../utils/cookies'\nexport {json, text, redirect, error} from '../utils/response'\nexport type {JsonResponse, Redirect, RedirectOptions, RouteError} from '../utils/response'\nexport {createHandler} from './create-handler'\nexport type {DevixHandler} from './create-handler'\nexport {FetchError} from './fetch'\nexport type {HttpMethod} from './fetch'\n\nimport {FetchError, type HttpMethod} from './fetch'\n\nexport interface ApiRoutes {}\n\ntype ApiKey<M extends HttpMethod, P extends string> = `${M} ${P}`\ntype MatchingKey<M extends HttpMethod, P extends string> = {\n [K in keyof ApiRoutes]: K extends ApiKey<M, P> ? K : never\n}[keyof ApiRoutes]\ntype RouteData<M extends HttpMethod, P extends string> = ApiRoutes[MatchingKey<M, P>]\ntype AllApiPaths = {\n [K in keyof ApiRoutes]: K extends `${HttpMethod} ${infer P}` ? P : never\n}[keyof ApiRoutes]\ntype ApiPath = AllApiPaths | (string & {})\ntype ExtractBody<D> = D extends { __body: infer B } ? B : never\ntype ExtractResponse<D> = D extends { __response: infer R } ? R : D\ntype InferBody<M extends HttpMethod, P extends string> = ExtractBody<RouteData<M, P>>\ntype InferResult<M extends HttpMethod, P extends string> = ExtractResponse<RouteData<M, P>>\ntype BodyOption<M extends HttpMethod, P extends string> = [InferBody<M, P>] extends [never] ? unknown : InferBody<M, P>\n\nexport interface FetchOptions<M extends HttpMethod = 'GET', P extends string = string> {\n method?: M\n body?: BodyOption<M, P>\n headers?: HeadersInit\n signal?: AbortSignal\n}\n\nexport async function $fetch<P extends ApiPath = ApiPath, M extends HttpMethod = 'GET'>(\n path: P,\n options?: FetchOptions<M, P>\n): Promise<InferResult<M, P>> {\n const method = options?.method ?? 'GET'\n const headers = new Headers(options?.headers)\n\n let body: BodyInit | undefined\n if (options?.body !== undefined) {\n if (options.body instanceof FormData || options.body instanceof Blob || options.body instanceof ArrayBuffer) {\n body = options.body\n } else {\n body = JSON.stringify(options.body)\n if (!headers.has('Content-Type')) {\n headers.set('Content-Type', 'application/json')\n }\n }\n }\n\n const response = await fetch(path, {method, headers, body, signal: options?.signal})\n\n if (!response.ok) {\n const contentType = response.headers.get('Content-Type') ?? ''\n const errorBody = contentType.includes('application/json')\n ? await response.json()\n : undefined\n throw new FetchError(response.status, response.statusText, response, errorBody)\n }\n\n const contentType = response.headers.get('Content-Type') ?? ''\n if (contentType.includes('application/json')) {\n return response.json() as Promise<InferResult<M, P>>\n }\n\n return response.text() as unknown as Promise<InferResult<M, P>>\n}\n"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": ["useCallback", "useContext", "useEffect", "useRef", "useState", "RouterContext", "getDefaultErrorPage", "loadErrorPage", "matchClientRoute", "Fragment", "jsx", "collectTags", "metadata", "viewport", "tags", "ogTitle", "ogDesc", "twTitle", "twDesc", "lang", "href", "raw", "icon", "resolved", "parts", "HeadSlot", "buildHeadNodes", "t", "i", "createContext", "g", "RouterContext", "PageMetaContext", "RouteDataContext", "Component", "jsx", "DevixErrorBoundary", "err", "DevixError", "statusCode", "message", "jsx", "jsxs", "useRouter", "useContext", "RouterContext", "noopNavigate", "noopRevalidate", "useNavigate", "useRevalidate", "useParams", "ctx", "RouteDataContext", "useLoaderData", "RouterProvider", "initialData", "initialParams", "initialPage", "initialLayouts", "initialLayoutsData", "initialMeta", "initialViewport", "initialError", "initialErrorPage", "clientEntry", "state", "setState", "useState", "navigatingRef", "useRef", "isNavigating", "setIsNavigating", "prefetchCacheRef", "prefetchRoute", "useCallback", "href", "pathname", "matched", "matchClientRoute", "controller", "promise", "l", "pageMod", "layoutMods", "dataRes", "data", "expireTimer", "loadRoute", "to", "ErrorPage", "loadErrorPage", "getDefaultErrorPage", "prev", "cached", "prefetched", "pm", "lm", "ct", "errorBody", "headers", "value", "key", "m", "hash", "scrollBehavior", "navigate", "options", "run", "revalidate", "useEffect", "handlePop", "err", "content", "tree", "i", "Layout", "layoutData", "DevixErrorBoundary", "PageMetaContext", "HeadSlot", "useCallback", "useContext", "useRef", "jsx", "resolveHref", "href", "base", "resolved", "Link", "prefetch", "replace", "viewTransition", "children", "props", "router", "useContext", "RouterContext", "hoverTimerRef", "useRef", "cancelHoverTimer", "useCallback", "triggerPrefetch", "handleMouseEnter", "handleMouseLeave", "handleTouchStart", "e", "options", "getCookie", "req", "name", "header", "part", "key", "rest", "setCookie", "headers", "value", "options", "cookie", "deleteCookie", "json", "data", "status", "text", "body", "REDIRECT_BRAND", "redirect", "url", "statusOrOptions", "replace", "ERROR_BRAND", "error", "statusCode", "message", "data", "HANDLER_BRAND", "createHandler", "fn", "FetchError", "status", "statusText", "response", "body", "$fetch", "path", "options", "method", "headers", "body", "response", "errorBody", "FetchError"]
|
|
7
7
|
}
|
package/dist/utils/banner.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import o from"picocolors";import{networkInterfaces as r}from"node:os";function s(e){let l=r();for(let n of Object.values(l))for(let t of n??[])if(t.family==="IPv4"&&!t.internal)return`http://${t.address}:${e}/`;return null}function $(e){let l="0.4.1-beta.
|
|
1
|
+
import o from"picocolors";import{networkInterfaces as r}from"node:os";function s(e){let l=r();for(let n of Object.values(l))for(let t of n??[])if(t.family==="IPv4"&&!t.internal)return`http://${t.address}:${e}/`;return null}function $(e){let l="0.4.1-beta.15",n=s(e);console.log(),console.log(` ${o.bold(o.yellow("devix"))} ${o.dim(`v${l}`)}`),console.log(),console.log(` ${o.green("\u279C")} ${o.bold("Local:")} ${o.cyan(`http://localhost:${e}/`)}`),console.log(n?` ${o.green("\u279C")} ${o.bold("Network:")} ${o.cyan(n)}`:` ${o.green("\u279C")} ${o.bold("Network:")} ${o.dim("use --host to expose")}`),console.log()}export{$ as printDevBanner};
|
|
2
2
|
//# sourceMappingURL=banner.js.map
|