@devlusoft/devix 0.4.3 → 0.4.4
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 +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/runtime/index.js +1 -1
- package/dist/runtime/index.js.map +4 -4
- package/dist/runtime/link.js +1 -1
- package/dist/runtime/link.js.map +4 -4
- package/dist/runtime/router-provider.js +1 -1
- package/dist/runtime/router-provider.js.map +4 -4
- package/dist/runtime/url.d.ts +9 -0
- package/dist/runtime/url.js +2 -0
- package/dist/runtime/url.js.map +7 -0
- package/dist/utils/banner.js +1 -1
- package/package.json +1 -1
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.
|
|
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.4",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.3");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.4");break}case"--help":case"-h":console.log(`
|
|
261
261
|
devix \u2014 a lightweight SSR framework
|
|
262
262
|
|
|
263
263
|
Usage:
|
package/dist/runtime/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{useCallback as $,useContext as S,useEffect as ge,useRef as ee,useState as te}from"react";import{RouterContext as j}from"virtual:devix/context";import{getDefaultErrorPage as re,loadErrorPage as ne,matchClientRoute as oe}from"virtual:devix/client-routes";import{Fragment as Q,jsx as _}from"react/jsx-runtime";function ce(e,t){let r=[];e.title&&r.push({tag:"title",children:e.title}),e.description&&r.push({tag:"meta",name:"description",content:e.description}),e.keywords?.length&&r.push({tag:"meta",name:"keywords",content:e.keywords.join(", ")});let n=e.og?.title??e.title;n&&r.push({tag:"meta",property:"og:title",content:n});let o=e.og?.description??e.description;o&&r.push({tag:"meta",property:"og:description",content:o}),e.og?.image&&r.push({tag:"meta",property:"og:image",content:e.og.image}),e.og?.type&&r.push({tag:"meta",property:"og:type",content:e.og.type}),e.og?.url&&r.push({tag:"meta",property:"og:url",content:e.og.url});let l=e.twitter?.title??e.title;l&&r.push({tag:"meta",name:"twitter:title",content:l});let y=e.twitter?.description??e.description;if(y&&r.push({tag:"meta",name:"twitter:description",content:y}),e.twitter?.card&&r.push({tag:"meta",name:"twitter:card",content:e.twitter.card}),e.twitter?.image&&r.push({tag:"meta",name:"twitter:image",content:e.twitter.image}),e.twitter?.creator&&r.push({tag:"meta",name:"twitter:creator",content:e.twitter.creator}),e.canonical&&r.push({tag:"link",rel:"canonical",href:e.canonical}),e.robots&&r.push({tag:"meta",name:"robots",content:e.robots}),e.alternates)for(let[c,d]of Object.entries(e.alternates))r.push({tag:"link",rel:"alternate",href:d,hrefLang:c});if(e.icons){let c=Array.isArray(e.icons)?e.icons:[e.icons];for(let d of c){let g=typeof d=="string"?{href:d}:d;r.push({tag:"link",rel:g.rel??"icon",href:g.href,...g.type&&{type:g.type},...g.sizes&&{sizes:g.sizes}})}}if(t){let c=[];t.width!==void 0&&c.push(`width=${t.width}`),t.initialScale!==void 0&&c.push(`initial-scale=${t.initialScale}`),t.maximumScale!==void 0&&c.push(`maximum-scale=${t.maximumScale}`),t.userScalable!==void 0&&c.push(`user-scalable=${t.userScalable?"yes":"no"}`),c.length&&r.push({tag:"meta",name:"viewport",content:c.join(", ")}),t.themeColor&&r.push({tag:"meta",name:"theme-color",content:t.themeColor})}return r}function q({metadata:e,viewport:t}){return typeof window>"u"||!e?null:_(Q,{children:de(e,t)})}function de(e,t){let r=ce(e,t);return _(Q,{children:r.map((n,o)=>n.tag==="title"?_("title",{children:n.children},o):n.tag==="link"?_("link",{rel:n.rel,href:n.href,hrefLang:n.hrefLang,type:n.type,sizes:n.sizes},o):_("meta",{name:n.name,property:n.property,content:n.content},o))})}import{createContext as U}from"react";var b=globalThis;b.__devix_RouterContext__??=U(null);var X=b.__devix_RouterContext__;b.__devix_PageMetaContext__??=U(null);b.__devix_RouteDataContext__??=U(null);var Y=b.__devix_PageMetaContext__,A=b.__devix_RouteDataContext__;import{Component as fe}from"react";import{jsx as Z}from"react/jsx-runtime";var V=class extends fe{state={error:null};static getDerivedStateFromError(t){return t instanceof O?{error:{statusCode:t.statusCode,message:t.message}}:{error:{statusCode:500,message:t instanceof Error?t.message:"Unknown error"}}}render(){return this.state.error&&this.props.ErrorPage?Z(this.props.ErrorPage,{...this.state.error}):this.state.error?Z("h1",{children:this.state.error.statusCode}):this.props.children}},O=class extends Error{statusCode;constructor(t,r){super(r),this.statusCode=t}};import{jsx as h,jsxs as Ee}from"react/jsx-runtime";var ye={width:"device-width",initialScale:1};function me(){return S(j)}var he=()=>Promise.resolve(),xe=()=>Promise.resolve();function Re(){return S(j)?.navigate??he}function we(){return S(j)?.revalidate??xe}function Pe(){let e=S(A);if(!e)throw new Error("useParams must be used within a route or layout");return e.params}function Te(){let e=S(A);if(!e)throw new Error("useLoaderData must be used within a route or layout");return e.loaderData}function Ce({initialData:e,initialParams:t,initialPage:r,initialLayouts:n=[],initialLayoutsData:o=[],initialMeta:l,initialViewport:y,initialError:c,initialErrorPage:d,clientEntry:g}){let[a,C]=te({pathname:window.location.pathname,params:t,loaderData:e,layoutsData:o,Page:r,layouts:n,metadata:l??null,viewport:y,pendingError:c,ErrorPage:d}),E=ee(null),[z,x]=te(!1),P=ee(new Map),se=$(s=>{if(P.current.has(s))return;let p=s.split("?")[0].split("#")[0],u=oe(p);if(!u)return;let i=new AbortController,m=Promise.all([Promise.all([u.load(),...u.loadLayouts.map(R=>R())]),fetch(`/_data${s}`,{headers:{Accept:"application/json"},signal:i.signal})]).then(async([[R,...D],f])=>{if(!f.ok||!R.default)return null;let N=await f.json();return{pageMod:R,layoutMods:D,data:N}}).catch(()=>null),v=setTimeout(()=>{i.abort(),P.current.delete(s)},3e3);m.finally(()=>clearTimeout(v)),P.current.set(s,{promise:m,controller:i})},[]),M=$(async(s,p)=>{let u=s.split("?")[0].split("#")[0],i=oe(u);if(!i){let w=await ne()??re();C(K=>({...K,pathname:u,pendingError:{statusCode:404,message:"Not found"},ErrorPage:w??void 0}));return}let m=P.current.get(s);m&&P.current.delete(s);let v=m?await m.promise:null;if(p.signal.aborted)return;let R,D,f;if(v)({pageMod:R,layoutMods:D,data:f}=v);else{let[[w,...K],T]=await Promise.all([Promise.all([i.load(),...i.loadLayouts.map(B=>B())]),fetch(`/_data${s}`,{headers:{Accept:"application/json"},signal:p.signal})]);if(p.signal.aborted||!w.default)return;if(!T.ok){let B=T.headers.get("Content-Type")??"",k=null;try{B.includes("application/json")?k=await T.json():B.includes("text/plain")&&(k={message:await T.text()})}catch{}let W={};T.headers.forEach((J,ue)=>{W[ue]=J});let pe=await ne()??re();C(J=>({...J,pathname:u,pendingError:{statusCode:k?.statusCode??T.status,message:k?.message??"Server error",data:k?.data,headers:W},ErrorPage:pe??void 0}));return}R=w,D=K,f=await T.json()}if(f.redirect){f.redirectReplace?window.history.replaceState(null,"",f.redirect):window.history.pushState(null,"",f.redirect),await M(f.redirect,p);return}C({pathname:u,params:f.params??{},loaderData:f.loaderData,layoutsData:(f.layouts??[]).map(w=>w.loaderData),Page:R.default,layouts:D.map(w=>w.default),metadata:f.metadata??null,viewport:f.viewport??ye});let N=s.includes("#")?s.split("#")[1]:null,G=getComputedStyle(document.documentElement).scrollBehavior;N?requestAnimationFrame(()=>{document.getElementById(N)?.scrollIntoView({behavior:G})}):window.scrollTo({top:0,behavior:G})},[]),I=$(async(s,p)=>{E.current?.abort();let u=new AbortController;E.current=u,x(!0);let i=async()=>{window.history[p?.replace?"replaceState":"pushState"](null,"",s),await M(s,u)};try{p?.viewTransition&&"startViewTransition"in document?await document.startViewTransition(i).finished:await i()}finally{u.signal.aborted||x(!1)}},[M]),le=$(async()=>{let s=window.location.pathname+window.location.search,p=new AbortController,u=await fetch(`/_data${s}`,{headers:{Accept:"application/json"},signal:p.signal});if(!u.ok)return;let i=await u.json();if(i.redirect){await I(i.redirect,{replace:i.redirectReplace});return}C(m=>({...m,loaderData:i.loaderData,layoutsData:(i.layouts??[]).map(v=>v.loaderData),params:i.params??m.params,metadata:i.metadata??m.metadata,viewport:i.viewport??m.viewport}))},[I]);ge(()=>{let s=()=>{E.current?.abort();let p=new AbortController;E.current=p;let u=window.location.pathname+window.location.search;M(u,p).catch(i=>{i.name!=="AbortError"&&console.error("[router] popstate error:",i)})};return window.addEventListener("popstate",s),()=>window.removeEventListener("popstate",s)},[M]);let F;if(a.pendingError)F=a.ErrorPage?h(a.ErrorPage,{...a.pendingError}):h("h1",{children:a.pendingError.statusCode});else{let s=h(A,{value:{loaderData:a.loaderData,params:a.params},children:h(a.Page,{data:a.loaderData,params:a.params,url:a.pathname})});for(let p=a.layouts.length-1;p>=0;p--){let u=a.layouts[p],i=a.layoutsData[p];s=h(A,{value:{loaderData:i,params:a.params},children:h(u,{data:i,params:a.params,children:s})})}F=h(V,{ErrorPage:a.ErrorPage,children:s},a.pathname)}return Ee(Y,{value:{metadata:a.metadata,viewport:a.viewport,clientEntry:g},children:[h(q,{metadata:a.metadata,viewport:a.viewport}),h(j,{value:{...a,isNavigating:z,navigate:I,revalidate:le,prefetchRoute:se},children:F})]})}import{useCallback as L,useContext as ve,useRef as be}from"react";import{jsx as De}from"react/jsx-runtime";function ae(e){if(e.startsWith("/")||e.startsWith("http"))return e;let t=window.location.pathname.endsWith("/")?window.location.href:window.location.href+"/",r=new URL(e,t).pathname;return r.length>1?r.replace(/\/$/,""):r}function Me({href:e,prefetch:t="hover",replace:r=!1,viewTransition:n=!1,children:o,...l}){let y=ve(X),c=be(null),d=L(()=>{c.current!==null&&(clearTimeout(c.current),c.current=null)},[]),g=L(()=>{!y||t==="none"||y.prefetchRoute(ae(e))},[e,t,y]),a=L(()=>{t!=="none"&&(c.current=setTimeout(g,50))},[t,g]),C=L(()=>{d()},[d]),E=L(()=>{d(),g()},[d,g]);return De("a",{href:e,onClick:x=>{if(d(),!!y&&!x.ctrlKey&&!x.metaKey&&!x.shiftKey&&x.button===0){x.preventDefault();let P={replace:r,viewTransition:n};y.navigate(ae(e),P)}},onMouseEnter:a,onMouseLeave:C,onTouchStart:E,...l,children:o})}function ke(e,t){let r=e.headers.get("cookie");if(r)for(let n of r.split(";")){let[o,...l]=n.trim().split("=");if(o.trim()===t)return decodeURIComponent(l.join("="))}}function ie(e,t,r,n={}){let o=`${t}=${encodeURIComponent(r)}; Path=${n.path??"/"}`;n.domain&&(o+=`; Domain=${n.domain}`),n.maxAge!==void 0&&(o+=`; Max-Age=${n.maxAge}`),n.expires&&(o+=`; Expires=${n.expires.toUTCString()}`),n.httpOnly&&(o+="; HttpOnly"),n.secure&&(o+="; Secure"),n.sameSite&&(o+=`; SameSite=${n.sameSite}`),e.append("Set-Cookie",o)}function _e(e,t,r={}){ie(e,t,"",{...r,maxAge:0,expires:new Date(0)})}function Ae(e,t=200){return new Response(JSON.stringify(e),{status:t,headers:{"Content-Type":"application/json"}})}var Se=(e,t=200)=>new Response(e,{status:t,headers:{"Content-Type":"text/plain; charset=utf-8"}}),Le=Symbol.for("devix.redirect");function He(e,t){let r=typeof t=="number"?t:t?.status??302,n=typeof t=="object"?t?.replace??!1:!1;return{[Le]:!0,url:e,status:r,replace:n}}var Ne=Symbol.for("devix.loaderError");function Be(e,t,r){return{[Ne]:!0,statusCode:e,message:t,data:r}}var Ve="__devix_handler__";function Oe(e){return{[Ve]:!0,fn:e}}var H=class extends Error{constructor(r,n,o,l){super(`HTTP ${r}: ${n}`);this.status=r;this.statusText=n;this.response=o;this.body=l;this.name="FetchError"}};async function Rt(e,t){let r=t?.method??"GET",n=new Headers(t?.headers),o;t?.body!==void 0&&(t.body instanceof FormData||t.body instanceof Blob||t.body instanceof ArrayBuffer?o=t.body:(o=JSON.stringify(t.body),n.has("Content-Type")||n.set("Content-Type","application/json")));let l=await fetch(e,{method:r,headers:n,body:o,signal:t?.signal});if(!l.ok){let d=(l.headers.get("Content-Type")??"").includes("application/json")?await l.json():void 0;throw new H(l.status,l.statusText,l,d)}return(l.headers.get("Content-Type")??"").includes("application/json")?l.json():l.text()}export{Rt as $fetch,O as DevixError,H as FetchError,Me as Link,Ce as RouterProvider,Oe as createHandler,_e as deleteCookie,Be as error,ke as getCookie,Ae as json,He as redirect,ie as setCookie,Se as text,Te as useLoaderData,Re as useNavigate,Pe as useParams,we as useRevalidate,me as useRouter};
|
|
1
|
+
import{useCallback as I,useContext as H,useEffect as ge,useRef as te,useState as re}from"react";import{RouterContext as F}from"virtual:devix/context";import{getDefaultErrorPage as ne,loadErrorPage as oe,matchClientRoute as ae}from"virtual:devix/client-routes";import{Fragment as X,jsx as A}from"react/jsx-runtime";function ce(e,t){let r=[];e.title&&r.push({tag:"title",children:e.title}),e.description&&r.push({tag:"meta",name:"description",content:e.description}),e.keywords?.length&&r.push({tag:"meta",name:"keywords",content:e.keywords.join(", ")});let n=e.og?.title??e.title;n&&r.push({tag:"meta",property:"og:title",content:n});let o=e.og?.description??e.description;o&&r.push({tag:"meta",property:"og:description",content:o}),e.og?.image&&r.push({tag:"meta",property:"og:image",content:e.og.image}),e.og?.type&&r.push({tag:"meta",property:"og:type",content:e.og.type}),e.og?.url&&r.push({tag:"meta",property:"og:url",content:e.og.url});let p=e.twitter?.title??e.title;p&&r.push({tag:"meta",name:"twitter:title",content:p});let y=e.twitter?.description??e.description;if(y&&r.push({tag:"meta",name:"twitter:description",content:y}),e.twitter?.card&&r.push({tag:"meta",name:"twitter:card",content:e.twitter.card}),e.twitter?.image&&r.push({tag:"meta",name:"twitter:image",content:e.twitter.image}),e.twitter?.creator&&r.push({tag:"meta",name:"twitter:creator",content:e.twitter.creator}),e.canonical&&r.push({tag:"link",rel:"canonical",href:e.canonical}),e.robots&&r.push({tag:"meta",name:"robots",content:e.robots}),e.alternates)for(let[c,f]of Object.entries(e.alternates))r.push({tag:"link",rel:"alternate",href:f,hrefLang:c});if(e.icons){let c=Array.isArray(e.icons)?e.icons:[e.icons];for(let f of c){let m=typeof f=="string"?{href:f}:f;r.push({tag:"link",rel:m.rel??"icon",href:m.href,...m.type&&{type:m.type},...m.sizes&&{sizes:m.sizes}})}}if(t){let c=[];t.width!==void 0&&c.push(`width=${t.width}`),t.initialScale!==void 0&&c.push(`initial-scale=${t.initialScale}`),t.maximumScale!==void 0&&c.push(`maximum-scale=${t.maximumScale}`),t.userScalable!==void 0&&c.push(`user-scalable=${t.userScalable?"yes":"no"}`),c.length&&r.push({tag:"meta",name:"viewport",content:c.join(", ")}),t.themeColor&&r.push({tag:"meta",name:"theme-color",content:t.themeColor})}return r}function Q({metadata:e,viewport:t}){return typeof window>"u"||!e?null:A(X,{children:de(e,t)})}function de(e,t){let r=ce(e,t);return A(X,{children:r.map((n,o)=>n.tag==="title"?A("title",{children:n.children},o):n.tag==="link"?A("link",{rel:n.rel,href:n.href,hrefLang:n.hrefLang,type:n.type,sizes:n.sizes},o):A("meta",{name:n.name,property:n.property,content:n.content},o))})}import{createContext as G}from"react";var b=globalThis;b.__devix_RouterContext__??=G(null);var Y=b.__devix_RouterContext__;b.__devix_PageMetaContext__??=G(null);b.__devix_RouteDataContext__??=G(null);var Z=b.__devix_PageMetaContext__,S=b.__devix_RouteDataContext__;import{Component as fe}from"react";import{jsx as ee}from"react/jsx-runtime";var $=class extends fe{state={error:null};static getDerivedStateFromError(t){return t instanceof j?{error:{statusCode:t.statusCode,message:t.message}}:{error:{statusCode:500,message:t instanceof Error?t.message:"Unknown error"}}}render(){return this.state.error&&this.props.ErrorPage?ee(this.props.ErrorPage,{...this.state.error}):this.state.error?ee("h1",{children:this.state.error.statusCode}):this.props.children}},j=class extends Error{statusCode;constructor(t,r){super(r),this.statusCode=t}};function L(e){let t=new URL(window.location.href);t.pathname.endsWith("/")||(t.pathname+="/");let r=new URL(e,t);if(r.origin!==window.location.origin)return{kind:"external",url:r};let n=r.pathname.length>1?r.pathname.replace(/\/$/,""):r.pathname;return{kind:"internal",pathname:n,href:n+r.search+r.hash}}import{jsx as x,jsxs as Ee}from"react/jsx-runtime";var me={width:"device-width",initialScale:1};function ye(){return H(F)}var he=()=>Promise.resolve(),xe=()=>Promise.resolve();function Re(){return H(F)?.navigate??he}function we(){return H(F)?.revalidate??xe}function Pe(){let e=H(S);if(!e)throw new Error("useParams must be used within a route or layout");return e.params}function Te(){let e=H(S);if(!e)throw new Error("useLoaderData must be used within a route or layout");return e.loaderData}function Ce({initialData:e,initialParams:t,initialPage:r,initialLayouts:n=[],initialLayoutsData:o=[],initialMeta:p,initialViewport:y,initialError:c,initialErrorPage:f,clientEntry:m}){let[a,E]=re({pathname:window.location.pathname,params:t,loaderData:e,layoutsData:o,Page:r,layouts:n,metadata:p??null,viewport:y,pendingError:c,ErrorPage:f}),v=te(null),[W,R]=re(!1),T=te(new Map),se=I(u=>{let s=L(u);if(s.kind==="external")return;let l=s.href;if(T.current.has(l))return;let i=ae(s.pathname);if(!i)return;let d=new AbortController,h=Promise.all([Promise.all([i.load(),...i.loadLayouts.map(w=>w())]),fetch(`/_data${l}`,{headers:{Accept:"application/json"},signal:d.signal})]).then(async([[w,...g],D])=>{if(!D.ok||!w.default)return null;let V=await D.json();return{pageMod:w,layoutMods:g,data:V}}).catch(()=>null),k=setTimeout(()=>{d.abort(),T.current.delete(l)},3e3);h.finally(()=>clearTimeout(k)),T.current.set(l,{promise:h,controller:d})},[]),M=I(async(u,s)=>{let l=u.split("?")[0].split("#")[0],i=ae(l);if(!i){let P=await oe()??ne();E(J=>({...J,pathname:l,pendingError:{statusCode:404,message:"Not found"},ErrorPage:P??void 0}));return}let d=T.current.get(u);d&&T.current.delete(u);let h=d?await d.promise:null;if(s.signal.aborted)return;let k,w,g;if(h)({pageMod:k,layoutMods:w,data:g}=h);else{let[[P,...J],C]=await Promise.all([Promise.all([i.load(),...i.loadLayouts.map(O=>O())]),fetch(`/_data${u}`,{headers:{Accept:"application/json"},signal:s.signal})]);if(s.signal.aborted||!P.default)return;if(!C.ok){let O=C.headers.get("Content-Type")??"",_=null;try{O.includes("application/json")?_=await C.json():O.includes("text/plain")&&(_={message:await C.text()})}catch{}let q={};C.headers.forEach((z,ue)=>{q[ue]=z});let pe=await oe()??ne();E(z=>({...z,pathname:l,pendingError:{statusCode:_?.statusCode??C.status,message:_?.message??"Server error",data:_?.data,headers:q},ErrorPage:pe??void 0}));return}k=P,w=J,g=await C.json()}if(g.redirect){g.redirectReplace?window.history.replaceState(null,"",g.redirect):window.history.pushState(null,"",g.redirect),await M(g.redirect,s);return}E({pathname:l,params:g.params??{},loaderData:g.loaderData,layoutsData:(g.layouts??[]).map(P=>P.loaderData),Page:k.default,layouts:w.map(P=>P.default),metadata:g.metadata??null,viewport:g.viewport??me});let D=u.includes("#")?u.split("#")[1]:null,V=getComputedStyle(document.documentElement).scrollBehavior;D?requestAnimationFrame(()=>{document.getElementById(D)?.scrollIntoView({behavior:V})}):window.scrollTo({top:0,behavior:V})},[]),K=I(async(u,s)=>{let l=L(u);if(l.kind==="external"){window.location.href=l.url.href;return}let i=l.href;v.current?.abort();let d=new AbortController;v.current=d,R(!0);let h=async()=>{window.history[s?.replace?"replaceState":"pushState"](null,"",i),await M(i,d)};try{s?.viewTransition&&"startViewTransition"in document?await document.startViewTransition(h).finished:await h()}finally{d.signal.aborted||R(!1)}},[M]),le=I(async()=>{let u=window.location.pathname+window.location.search,s=new AbortController,l=await fetch(`/_data${u}`,{headers:{Accept:"application/json"},signal:s.signal});if(!l.ok)return;let i=await l.json();if(i.redirect){await K(i.redirect,{replace:i.redirectReplace});return}E(d=>({...d,loaderData:i.loaderData,layoutsData:(i.layouts??[]).map(h=>h.loaderData),params:i.params??d.params,metadata:i.metadata??d.metadata,viewport:i.viewport??d.viewport}))},[K]);ge(()=>{let u=()=>{v.current?.abort();let s=new AbortController;v.current=s;let l=window.location.pathname+window.location.search;M(l,s).catch(i=>{i.name!=="AbortError"&&console.error("[router] popstate error:",i)})};return window.addEventListener("popstate",u),()=>window.removeEventListener("popstate",u)},[M]);let U;if(a.pendingError)U=a.ErrorPage?x(a.ErrorPage,{...a.pendingError}):x("h1",{children:a.pendingError.statusCode});else{let u=x(S,{value:{loaderData:a.loaderData,params:a.params},children:x(a.Page,{data:a.loaderData,params:a.params,url:a.pathname})});for(let s=a.layouts.length-1;s>=0;s--){let l=a.layouts[s],i=a.layoutsData[s];u=x(S,{value:{loaderData:i,params:a.params},children:x(l,{data:i,params:a.params,children:u})})}U=x($,{ErrorPage:a.ErrorPage,children:u},a.pathname)}return Ee(Z,{value:{metadata:a.metadata,viewport:a.viewport,clientEntry:m},children:[x(Q,{metadata:a.metadata,viewport:a.viewport}),x(F,{value:{...a,isNavigating:W,navigate:K,revalidate:le,prefetchRoute:se},children:U})]})}import{useCallback as N,useContext as ve,useRef as be}from"react";import{jsx as ke}from"react/jsx-runtime";function Me({href:e,prefetch:t="hover",replace:r=!1,viewTransition:n=!1,children:o,...p}){let y=ve(Y),c=be(null),f=N(()=>{c.current!==null&&(clearTimeout(c.current),c.current=null)},[]),m=N(()=>{!y||t==="none"||y.prefetchRoute(e)},[e,t,y]),a=N(()=>{t!=="none"&&(c.current=setTimeout(m,50))},[t,m]),E=N(()=>{f()},[f]),v=N(()=>{f(),m()},[f,m]);return ke("a",{href:e,onClick:R=>{if(f(),!y||R.ctrlKey||R.metaKey||R.shiftKey||R.button!==0||L(e).kind==="external")return;R.preventDefault();let T={replace:r,viewTransition:n};y.navigate(e,T)},onMouseEnter:a,onMouseLeave:E,onTouchStart:v,...p,children:o})}function De(e,t){let r=e.headers.get("cookie");if(r)for(let n of r.split(";")){let[o,...p]=n.trim().split("=");if(o.trim()===t)return decodeURIComponent(p.join("="))}}function ie(e,t,r,n={}){let o=`${t}=${encodeURIComponent(r)}; Path=${n.path??"/"}`;n.domain&&(o+=`; Domain=${n.domain}`),n.maxAge!==void 0&&(o+=`; Max-Age=${n.maxAge}`),n.expires&&(o+=`; Expires=${n.expires.toUTCString()}`),n.httpOnly&&(o+="; HttpOnly"),n.secure&&(o+="; Secure"),n.sameSite&&(o+=`; SameSite=${n.sameSite}`),e.append("Set-Cookie",o)}function _e(e,t,r={}){ie(e,t,"",{...r,maxAge:0,expires:new Date(0)})}function Ae(e,t=200){return new Response(JSON.stringify(e),{status:t,headers:{"Content-Type":"application/json"}})}var Se=(e,t=200)=>new Response(e,{status:t,headers:{"Content-Type":"text/plain; charset=utf-8"}}),Le=Symbol.for("devix.redirect");function He(e,t){let r=typeof t=="number"?t:t?.status??302,n=typeof t=="object"?t?.replace??!1:!1;return{[Le]:!0,url:e,status:r,replace:n}}var Ne=Symbol.for("devix.loaderError");function Be(e,t,r){return{[Ne]:!0,statusCode:e,message:t,data:r}}var Ve="__devix_handler__";function Oe(e){return{[Ve]:!0,fn:e}}var B=class extends Error{constructor(r,n,o,p){super(`HTTP ${r}: ${n}`);this.status=r;this.statusText=n;this.response=o;this.body=p;this.name="FetchError"}};async function Tt(e,t){let r=t?.method??"GET",n=new Headers(t?.headers),o;t?.body!==void 0&&(t.body instanceof FormData||t.body instanceof Blob||t.body instanceof ArrayBuffer?o=t.body:(o=JSON.stringify(t.body),n.has("Content-Type")||n.set("Content-Type","application/json")));let p=await fetch(e,{method:r,headers:n,body:o,signal:t?.signal});if(!p.ok){let f=(p.headers.get("Content-Type")??"").includes("application/json")?await p.json():void 0;throw new B(p.status,p.statusText,p,f)}return(p.headers.get("Content-Type")??"").includes("application/json")?p.json():p.text()}export{Tt as $fetch,j as DevixError,B as FetchError,Me as Link,Ce as RouterProvider,Oe as createHandler,_e as deleteCookie,Be as error,De as getCookie,Ae as json,He as redirect,ie as setCookie,Se as text,Te as useLoaderData,Re as useNavigate,Pe as useParams,we as useRevalidate,ye as useRouter};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 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\";\n\nconst DEFAULT_VIEWPORT: Viewport = { width: 'device-width', initialScale: 1 }\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 ?? DEFAULT_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.for('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.for('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, MiddlewareModule } 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 {DevixError} from './error-boundary'\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
|
-
"mappings": "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",
|
|
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", "DEFAULT_VIEWPORT", "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", "
|
|
3
|
+
"sources": ["../../src/runtime/router-provider.tsx", "../../src/runtime/head.tsx", "../../src/runtime/context.tsx", "../../src/runtime/error-boundary.tsx", "../../src/runtime/url.ts", "../../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\";\n\nconst DEFAULT_VIEWPORT: Viewport = { width: 'device-width', initialScale: 1 }\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 { resolveTo } from \"./url\";\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 const resolved = resolveTo(href)\n if (resolved.kind === 'external') return\n\n const key = resolved.href\n if (prefetchCacheRef.current.has(key)) return\n const matched = matchClientRoute(resolved.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${key}`, { 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(key)\n }, 3000)\n promise.finally(() => clearTimeout(expireTimer))\n\n prefetchCacheRef.current.set(key, { 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 ?? DEFAULT_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 const resolved = resolveTo(to)\n if (resolved.kind === 'external') {\n window.location.href = resolved.url.href\n return\n }\n const href = resolved.href\n\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, '', href)\n await loadRoute(href, 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", "export type ResolvedTo =\n | { kind: 'internal'; pathname: string; href: string }\n | { kind: 'external'; url: URL }\n\nexport function resolveTo(to: string): ResolvedTo {\n const base = new URL(window.location.href)\n if (!base.pathname.endsWith('/')) base.pathname += '/'\n\n const url = new URL(to, base)\n\n if (url.origin !== window.location.origin) {\n return { kind: 'external', url }\n }\n\n const pathname = url.pathname.length > 1\n ? url.pathname.replace(/\\/$/, '')\n : url.pathname\n\n return {\n kind: 'internal',\n pathname,\n href: pathname + url.search + url.hash,\n }\n}\n", "import { AnchorHTMLAttributes, MouseEventHandler, useCallback, useContext, useRef } from \"react\"\nimport { NavigateOptions, RouterContext } from './context'\nimport { resolveTo } from './url'\n\ninterface LinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {\n href: string\n prefetch?: 'hover' | 'none'\n replace?: boolean\n viewTransition?: boolean\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(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) return\n if (resolveTo(href).kind === 'external') return\n e.preventDefault()\n const options: NavigateOptions = { replace, viewTransition }\n router.navigate(href, options)\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.for('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.for('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, MiddlewareModule } 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 {DevixError} from './error-boundary'\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
|
+
"mappings": "AAAA,OAAmC,eAAAA,EAAa,cAAAC,EAAY,aAAAC,GAAW,UAAAC,GAAQ,YAAAC,OAAgB,QAC/F,OAAS,iBAAAC,MAAqB,wBAK9B,OAAS,uBAAAC,GAAqB,iBAAAC,GAAe,oBAAAC,OAAwB,8BC4E1D,mBAAAC,EAAA,OAAAC,MAAA,oBA1EX,SAASC,GAAYC,EAAoBC,EAAgC,CACrE,IAAMC,EAAkB,CAAC,EAErBF,EAAS,OACTE,EAAK,KAAK,CAAE,IAAK,QAAS,SAAUF,EAAS,KAAM,CAAC,EACpDA,EAAS,aACTE,EAAK,KAAK,CAAE,IAAK,OAAQ,KAAM,cAAe,QAASF,EAAS,WAAY,CAAC,EAC7EA,EAAS,UAAU,QACnBE,EAAK,KAAK,CAAE,IAAK,OAAQ,KAAM,WAAY,QAASF,EAAS,SAAS,KAAK,IAAI,CAAE,CAAC,EAEtF,IAAMG,EAAUH,EAAS,IAAI,OAASA,EAAS,MAC3CG,GAASD,EAAK,KAAK,CAAE,IAAK,OAAQ,SAAU,WAAY,QAASC,CAAQ,CAAC,EAC9E,IAAMC,EAASJ,EAAS,IAAI,aAAeA,EAAS,YAChDI,GAAQF,EAAK,KAAK,CAAE,IAAK,OAAQ,SAAU,iBAAkB,QAASE,CAAO,CAAC,EAC9EJ,EAAS,IAAI,OAAOE,EAAK,KAAK,CAAE,IAAK,OAAQ,SAAU,WAAY,QAASF,EAAS,GAAG,KAAM,CAAC,EAC/FA,EAAS,IAAI,MAAME,EAAK,KAAK,CAAE,IAAK,OAAQ,SAAU,UAAW,QAASF,EAAS,GAAG,IAAK,CAAC,EAC5FA,EAAS,IAAI,KAAKE,EAAK,KAAK,CAAE,IAAK,OAAQ,SAAU,SAAU,QAASF,EAAS,GAAG,GAAI,CAAC,EAE7F,IAAMK,EAAUL,EAAS,SAAS,OAASA,EAAS,MAChDK,GAASH,EAAK,KAAK,CAAE,IAAK,OAAQ,KAAM,gBAAiB,QAASG,CAAQ,CAAC,EAC/E,IAAMC,EAASN,EAAS,SAAS,aAAeA,EAAS,YAiBzD,GAhBIM,GAAQJ,EAAK,KAAK,CAAE,IAAK,OAAQ,KAAM,sBAAuB,QAASI,CAAO,CAAC,EAC/EN,EAAS,SAAS,MAAME,EAAK,KAAK,CAClC,IAAK,OAAQ,KAAM,eAAgB,QAC/BF,EAAS,QAAQ,IACzB,CAAC,EACGA,EAAS,SAAS,OAAOE,EAAK,KAAK,CACnC,IAAK,OAAQ,KAAM,gBAAiB,QAChCF,EAAS,QAAQ,KACzB,CAAC,EACGA,EAAS,SAAS,SAASE,EAAK,KAAK,CACrC,IAAK,OAAQ,KAAM,kBAAmB,QAClCF,EAAS,QAAQ,OACzB,CAAC,EAEGA,EAAS,WAAWE,EAAK,KAAK,CAAE,IAAK,OAAQ,IAAK,YAAa,KAAMF,EAAS,SAAU,CAAC,EACzFA,EAAS,QAAQE,EAAK,KAAK,CAAE,IAAK,OAAQ,KAAM,SAAU,QAASF,EAAS,MAAO,CAAC,EACpFA,EAAS,WACT,OAAW,CAACO,EAAMC,CAAI,IAAK,OAAO,QAAQR,EAAS,UAAU,EACzDE,EAAK,KAAK,CAAE,IAAK,OAAQ,IAAK,YAAa,KAAAM,EAAM,SAAUD,CAAK,CAAC,EAGzE,GAAIP,EAAS,MAAO,CAChB,IAAMS,EAAM,MAAM,QAAQT,EAAS,KAAK,EAAIA,EAAS,MAAQ,CAACA,EAAS,KAAK,EAC5E,QAAWU,KAAQD,EAAK,CACpB,IAAME,EAAyB,OAAOD,GAAS,SAAW,CAAE,KAAMA,CAAK,EAAIA,EAC3ER,EAAK,KAAK,CACN,IAAK,OACL,IAAKS,EAAS,KAAO,OACrB,KAAMA,EAAS,KACf,GAAIA,EAAS,MAAQ,CAAE,KAAMA,EAAS,IAAK,EAC3C,GAAIA,EAAS,OAAS,CAAE,MAAOA,EAAS,KAAM,CAClD,CAAC,CACL,CACJ,CAEA,GAAIV,EAAU,CACV,IAAMW,EAAkB,CAAC,EACrBX,EAAS,QAAU,QAAWW,EAAM,KAAK,SAASX,EAAS,KAAK,EAAE,EAClEA,EAAS,eAAiB,QAAWW,EAAM,KAAK,iBAAiBX,EAAS,YAAY,EAAE,EACxFA,EAAS,eAAiB,QAAWW,EAAM,KAAK,iBAAiBX,EAAS,YAAY,EAAE,EACxFA,EAAS,eAAiB,QAAWW,EAAM,KAAK,iBAAiBX,EAAS,aAAe,MACzF,IAAI,EAAE,EACNW,EAAM,QAAQV,EAAK,KAAK,CAAE,IAAK,OAAQ,KAAM,WAAY,QAASU,EAAM,KAAK,IAAI,CAAE,CAAC,EACpFX,EAAS,YAAYC,EAAK,KAAK,CAC/B,IAAK,OAAQ,KAAM,cAAe,QAASD,EAAS,UACxD,CAAC,CACL,CAEA,OAAOC,CACX,CAEO,SAASW,EAAS,CAAE,SAAAb,EAAU,SAAAC,CAAS,EAAuD,CACjG,OAAI,OAAO,OAAW,KAAe,CAACD,EAAiB,KAChDF,EAAAD,EAAA,CAAG,SAAAiB,GAAed,EAAUC,CAAQ,EAAE,CACjD,CAEO,SAASa,GAAed,EAAoBC,EAAgC,CAC/E,IAAMC,EAAOH,GAAYC,EAAUC,CAAQ,EAE3C,OAAOH,EAAAD,EAAA,CACF,SAAAK,EAAK,IAAI,CAACa,EAAGC,IACND,EAAE,MAAQ,QAAgBjB,EAAC,SAAe,SAAAiB,EAAE,UAANC,CAAe,EACrDD,EAAE,MAAQ,OAAejB,EAAC,QAAa,IAAKiB,EAAE,IAAK,KAAMA,EAAE,KAAM,SAAUA,EAAE,SAAU,KAAMA,EAAE,KAAM,MAAOA,EAAE,OAA1EC,CAAiF,EAClHlB,EAAC,QAAa,KAAMiB,EAAE,KAAM,SAAUA,EAAE,SAAU,QAASA,EAAE,SAAlDC,CAA2D,CAChF,EACL,CACJ,CC/FA,OAAQ,iBAAAC,MAA4C,QAmCpD,IAAMC,EAAI,WAEVA,EAAE,0BAA4BD,EAAyC,IAAI,EACpE,IAAME,EAAoDD,EAAE,wBAEnEA,EAAE,4BAA8BD,EAA2C,IAAI,EAC/EC,EAAE,6BAA+BD,EAA4C,IAAI,EAE1E,IAAMG,EAAwDF,EAAE,0BAC1DG,EAA0DH,EAAE,2BC5CzE,OAAQ,aAAAI,OAA0C,QA4B/B,cAAAC,OAAA,oBAhBZ,IAAMC,EAAN,cAAiCF,EAAwB,CAC5D,MAAe,CAAE,MAAO,IAAK,EAE7B,OAAO,yBAAyBG,EAAqB,CACjD,OAAIA,aAAeC,EACR,CACH,MAAO,CAAC,WAAYD,EAAI,WAAY,QAASA,EAAI,OAAO,CAC5D,EAEI,CACJ,MAAO,CAAC,WAAY,IAAK,QAASA,aAAe,MAAQA,EAAI,QAAU,eAAe,CAC1F,CACJ,CAEA,QAAS,CACL,OAAI,KAAK,MAAM,OAAS,KAAK,MAAM,UACxBF,GAAC,KAAK,MAAM,UAAX,CAAsB,GAAG,KAAK,MAAM,MAAO,EAEnD,KAAK,MAAM,MACJA,GAAC,MAAI,cAAK,MAAM,MAAM,WAAW,EAErC,KAAK,MAAM,QACtB,CACJ,EAEaG,EAAN,cAAyB,KAAM,CAClC,WACA,YAAYC,EAAoBC,EAAiB,CAC7C,MAAMA,CAAO,EACb,KAAK,WAAaD,CACtB,CACJ,ECvCO,SAASE,EAAUC,EAAwB,CAC9C,IAAMC,EAAO,IAAI,IAAI,OAAO,SAAS,IAAI,EACpCA,EAAK,SAAS,SAAS,GAAG,IAAGA,EAAK,UAAY,KAEnD,IAAMC,EAAM,IAAI,IAAIF,EAAIC,CAAI,EAE5B,GAAIC,EAAI,SAAW,OAAO,SAAS,OAC/B,MAAO,CAAE,KAAM,WAAY,IAAAA,CAAI,EAGnC,IAAMC,EAAWD,EAAI,SAAS,OAAS,EACjCA,EAAI,SAAS,QAAQ,MAAO,EAAE,EAC9BA,EAAI,SAEV,MAAO,CACH,KAAM,WACN,SAAAC,EACA,KAAMA,EAAWD,EAAI,OAASA,EAAI,IACtC,CACJ,CJ+Rc,cAAAE,EA2BN,QAAAC,OA3BM,oBAjTd,IAAMC,GAA6B,CAAE,MAAO,eAAgB,aAAc,CAAE,EAqBrE,SAASC,IAAY,CACxB,OAAOC,EAAWC,CAAa,CACnC,CAEA,IAAMC,GAAe,IAAM,QAAQ,QAAQ,EACrCC,GAAiB,IAAM,QAAQ,QAAQ,EAEtC,SAASC,IAAc,CAE1B,OADYJ,EAAWC,CAAa,GACxB,UAAYC,EAC5B,CAEO,SAASG,IAAgB,CAE5B,OADYL,EAAWC,CAAa,GACxB,YAAcE,EAC9B,CAEO,SAASG,IAA8C,CAC1D,IAAMC,EAAMP,EAAWQ,CAAgB,EACvC,GAAI,CAACD,EAAK,MAAM,IAAI,MAAM,iDAAiD,EAC3E,OAAOA,EAAI,MACf,CAQO,SAASE,IAAmB,CAC/B,IAAMF,EAAMP,EAAWQ,CAAgB,EACvC,GAAI,CAACD,EAAK,MAAM,IAAI,MAAM,qDAAqD,EAC/E,OAAOA,EAAI,UACf,CAoBO,SAASG,GAAe,CAC3B,YAAAC,EACA,cAAAC,EACA,YAAAC,EACA,eAAAC,EAAiB,CAAC,EAClB,mBAAAC,EAAqB,CAAC,EACtB,YAAAC,EACA,gBAAAC,EACA,aAAAC,EACA,iBAAAC,EACA,YAAAC,CACJ,EAAwB,CAEpB,GAAM,CAACC,EAAOC,CAAQ,EAAIC,GAAqB,CAC3C,SAAU,OAAO,SAAS,SAC1B,OAAQX,EACR,WAAYD,EACZ,YAAaI,EACb,KAAMF,EACN,QAASC,EACT,SAAUE,GAAe,KACzB,SAAUC,EACV,aAAcC,EACd,UAAWC,CACf,CAAC,EAEKK,EAAgBC,GAA+B,IAAI,EACnD,CAACC,EAAcC,CAAe,EAAIJ,GAAS,EAAK,EAEhDK,EAAmBH,GAAmC,IAAI,GAAK,EAE/DI,GAAgBC,EAAaC,GAAiB,CAChD,IAAMC,EAAWC,EAAUF,CAAI,EAC/B,GAAIC,EAAS,OAAS,WAAY,OAElC,IAAME,EAAMF,EAAS,KACrB,GAAIJ,EAAiB,QAAQ,IAAIM,CAAG,EAAG,OACvC,IAAMC,EAAUC,GAAiBJ,EAAS,QAAQ,EAClD,GAAI,CAACG,EAAS,OAEd,IAAME,EAAa,IAAI,gBACjBC,EAAU,QAAQ,IAAI,CACxB,QAAQ,IAAI,CAACH,EAAQ,KAAK,EAAG,GAAGA,EAAQ,YAAY,IAAII,GAAKA,EAAE,CAAC,CAAC,CAAC,EAClE,MAAM,SAASL,CAAG,GAAI,CAAE,QAAS,CAAE,OAAQ,kBAAmB,EAAG,OAAQG,EAAW,MAAO,CAAC,CAChG,CAAC,EAAE,KAAK,MAAO,CAAC,CAACG,EAAY,GAAAC,CAAU,EAAGC,CAAO,IAAM,CACnD,GAAI,CAACA,EAAQ,IAAM,CAACF,EAAQ,QAAS,OAAO,KAC5C,IAAMG,EAAO,MAAMD,EAAQ,KAAK,EAChC,MAAO,CAAE,QAAAF,EAAS,WAAAC,EAAY,KAAAE,CAAK,CACvC,CAAC,EAAE,MAAM,IAAM,IAAI,EAEbC,EAAc,WAAW,IAAM,CACjCP,EAAW,MAAM,EACjBT,EAAiB,QAAQ,OAAOM,CAAG,CACvC,EAAG,GAAI,EACPI,EAAQ,QAAQ,IAAM,aAAaM,CAAW,CAAC,EAE/ChB,EAAiB,QAAQ,IAAIM,EAAK,CAAE,QAAAI,EAAS,WAAAD,CAAW,CAAC,CAC7D,EAAG,CAAC,CAAC,EAECQ,EAAYf,EAAY,MAAOgB,EAAYT,IAAgC,CAC7E,IAAMU,EAAWD,EAAG,MAAM,GAAG,EAAE,CAAC,EAAE,MAAM,GAAG,EAAE,CAAC,EACxCX,EAAUC,GAAiBW,CAAQ,EACzC,GAAI,CAACZ,EAAS,CACV,IAAMa,EAAY,MAAMC,GAAc,GAAKC,GAAoB,EAC/D5B,EAAS6B,IAAS,CACd,GAAGA,EACH,SAAUJ,EACV,aAAc,CAAE,WAAY,IAAK,QAAS,WAAY,EACtD,UAAWC,GAAa,MAC5B,EAAE,EACF,MACJ,CAEA,IAAMI,EAASxB,EAAiB,QAAQ,IAAIkB,CAAE,EAC1CM,GAAQxB,EAAiB,QAAQ,OAAOkB,CAAE,EAC9C,IAAMO,EAAaD,EAAS,MAAMA,EAAO,QAAU,KAEnD,GAAIf,EAAW,OAAO,QAAS,OAE/B,IAAIG,EAAcC,EAAmBE,EAErC,GAAIU,GACE,CAAE,QAAAb,EAAS,WAAAC,EAAY,KAAAE,CAAK,EAAIU,OAC/B,CACH,GAAM,CAAC,CAACC,EAAI,GAAGC,CAAE,EAAGb,CAAO,EAAI,MAAM,QAAQ,IAAI,CAC7C,QAAQ,IAAI,CACRP,EAAQ,KAAK,EACb,GAAGA,EAAQ,YAAY,IAAII,GAAKA,EAAE,CAAC,CACvC,CAAC,EACD,MAAM,SAASO,CAAE,GAAI,CACjB,QAAS,CAAE,OAAQ,kBAAmB,EACtC,OAAQT,EAAW,MACvB,CAAC,CACL,CAAC,EAGD,GADIA,EAAW,OAAO,SAClB,CAACiB,EAAG,QAAS,OAEjB,GAAI,CAACZ,EAAQ,GAAI,CACb,IAAMc,EAAKd,EAAQ,QAAQ,IAAI,cAAc,GAAK,GAC9Ce,EAA8E,KAClF,GAAI,CACID,EAAG,SAAS,kBAAkB,EAAGC,EAAY,MAAMf,EAAQ,KAAK,EAC3Dc,EAAG,SAAS,YAAY,IAAGC,EAAY,CAAE,QAAS,MAAMf,EAAQ,KAAK,CAAE,EACpF,MAAQ,CAAmC,CAE3C,IAAMgB,EAAkC,CAAC,EACzChB,EAAQ,QAAQ,QAAQ,CAACiB,EAAOzB,KAAQ,CAAEwB,EAAQxB,EAAG,EAAIyB,CAAM,CAAC,EAEhE,IAAMX,GAAY,MAAMC,GAAc,GAAKC,GAAoB,EAC/D5B,EAAS6B,IAAS,CACd,GAAGA,EACH,SAAAJ,EACA,aAAc,CACV,WAAYU,GAAW,YAAcf,EAAQ,OAC7C,QAASe,GAAW,SAAW,eAC/B,KAAMA,GAAW,KACjB,QAAAC,CACJ,EACA,UAAWV,IAAa,MAC5B,EAAE,EACF,MACJ,CAEAR,EAAUc,EACVb,EAAac,EACbZ,EAAO,MAAMD,EAAQ,KAAK,CAC9B,CAEA,GAAIC,EAAK,SAAU,CACXA,EAAK,gBACL,OAAO,QAAQ,aAAa,KAAM,GAAIA,EAAK,QAAQ,EAEnD,OAAO,QAAQ,UAAU,KAAM,GAAIA,EAAK,QAAQ,EAEpD,MAAME,EAAUF,EAAK,SAAUN,CAAU,EACzC,MACJ,CAEAf,EAAS,CACL,SAAAyB,EACA,OAAQJ,EAAK,QAAU,CAAC,EACxB,WAAYA,EAAK,WACjB,aAAcA,EAAK,SAAW,CAAC,GAAG,IAAKJ,GAAWA,EAAE,UAAU,EAC9D,KAAMC,EAAQ,QACd,QAASC,EAAW,IAAImB,GAAKA,EAAE,OAAO,EACtC,SAAUjB,EAAK,UAAY,KAC3B,SAAUA,EAAK,UAAY7C,EAC/B,CAAC,EAED,IAAM+D,EAAOf,EAAG,SAAS,GAAG,EAAIA,EAAG,MAAM,GAAG,EAAE,CAAC,EAAI,KAC7CgB,EAAiB,iBAAiB,SAAS,eAAe,EAAE,eAC9DD,EACA,sBAAsB,IAAM,CACxB,SAAS,eAAeA,CAAI,GAAG,eAAe,CAAE,SAAUC,CAAe,CAAC,CAC9E,CAAC,EAED,OAAO,SAAS,CAAE,IAAK,EAAG,SAAUA,CAAe,CAAC,CAE5D,EAAG,CAAC,CAAC,EAECC,EAAWjC,EAAY,MAAOgB,EAAYkB,IAA8B,CAC1E,IAAMhC,EAAWC,EAAUa,CAAE,EAC7B,GAAId,EAAS,OAAS,WAAY,CAC9B,OAAO,SAAS,KAAOA,EAAS,IAAI,KACpC,MACJ,CACA,IAAMD,EAAOC,EAAS,KAEtBR,EAAc,SAAS,MAAM,EAC7B,IAAMa,EAAa,IAAI,gBACvBb,EAAc,QAAUa,EAExBV,EAAgB,EAAI,EACpB,IAAMsC,EAAM,SAAY,CACpB,OAAO,QAAQD,GAAS,QAAU,eAAiB,WAAW,EAAE,KAAM,GAAIjC,CAAI,EAC9E,MAAMc,EAAUd,EAAMM,CAAU,CACpC,EACA,GAAI,CACI2B,GAAS,gBAAkB,wBAAyB,SACpD,MAAO,SAAiB,oBAAoBC,CAAG,EAAE,SAEjD,MAAMA,EAAI,CAElB,QAAE,CACO5B,EAAW,OAAO,SAASV,EAAgB,EAAK,CACzD,CACJ,EAAG,CAACkB,CAAS,CAAC,EAERqB,GAAapC,EAAY,SAAY,CACvC,IAAMgB,EAAK,OAAO,SAAS,SAAW,OAAO,SAAS,OAChDT,EAAa,IAAI,gBACjBK,EAAU,MAAM,MAAM,SAASI,CAAE,GAAI,CACvC,QAAS,CAAE,OAAQ,kBAAmB,EACtC,OAAQT,EAAW,MACvB,CAAC,EACD,GAAI,CAACK,EAAQ,GAAI,OACjB,IAAMC,EAAO,MAAMD,EAAQ,KAAK,EAChC,GAAIC,EAAK,SAAU,CACf,MAAMoB,EAASpB,EAAK,SAAU,CAAE,QAASA,EAAK,eAAgB,CAAC,EAC/D,MACJ,CACArB,EAAS6B,IAAS,CACd,GAAGA,EACH,WAAYR,EAAK,WACjB,aAAcA,EAAK,SAAW,CAAC,GAAG,IAAKJ,GAAWA,EAAE,UAAU,EAC9D,OAAQI,EAAK,QAAUQ,EAAK,OAC5B,SAAUR,EAAK,UAAYQ,EAAK,SAChC,SAAUR,EAAK,UAAYQ,EAAK,QACpC,EAAE,CACN,EAAG,CAACY,CAAQ,CAAC,EAEbI,GAAU,IAAM,CACZ,IAAMC,EAAY,IAAM,CACpB5C,EAAc,SAAS,MAAM,EAC7B,IAAMa,EAAa,IAAI,gBACvBb,EAAc,QAAUa,EAExB,IAAMS,EAAK,OAAO,SAAS,SAAW,OAAO,SAAS,OACtDD,EAAUC,EAAIT,CAAU,EAAE,MAAMgC,GAAO,CAC/BA,EAAI,OAAS,cAAc,QAAQ,MAAM,2BAA4BA,CAAG,CAChF,CAAC,CACL,EACA,cAAO,iBAAiB,WAAYD,CAAS,EACtC,IAAM,OAAO,oBAAoB,WAAYA,CAAS,CACjE,EAAG,CAACvB,CAAS,CAAC,EAEd,IAAIyB,EAEJ,GAAIjD,EAAM,aACNiD,EAAUjD,EAAM,UACVzB,EAACyB,EAAM,UAAN,CAAiB,GAAGA,EAAM,aAAc,EACzCzB,EAAC,MAAI,SAAAyB,EAAM,aAAa,WAAW,MACtC,CACH,IAAIkD,EACA3E,EAACY,EAAA,CAAiB,MAAO,CAAE,WAAYa,EAAM,WAAY,OAAQA,EAAM,MAAO,EAC1E,SAAAzB,EAACyB,EAAM,KAAN,CAAW,KAAMA,EAAM,WAAY,OAAQA,EAAM,OAAQ,IAAKA,EAAM,SAAU,EACnF,EAGJ,QAASmD,EAAInD,EAAM,QAAQ,OAAS,EAAGmD,GAAK,EAAGA,IAAK,CAChD,IAAMC,EAASpD,EAAM,QAAQmD,CAAC,EACxBE,EAAarD,EAAM,YAAYmD,CAAC,EACtCD,EACI3E,EAACY,EAAA,CAAiB,MAAO,CAAE,WAAYkE,EAAY,OAAQrD,EAAM,MAAO,EACpE,SAAAzB,EAAC6E,EAAA,CAAO,KAAMC,EAAY,OAAQrD,EAAM,OAAS,SAAAkD,EAAK,EAC1D,CAER,CAEAD,EACI1E,EAAC+E,EAAA,CAAwC,UAAWtD,EAAM,UACrD,SAAAkD,GADoBlD,EAAM,QAE/B,CAER,CAEA,OACIxB,GAAC+E,EAAA,CAAgB,MAAO,CACpB,SAAUvD,EAAM,SAChB,SAAUA,EAAM,SAChB,YAAAD,CACJ,EACI,UAAAxB,EAACiF,EAAA,CAAS,SAAUxD,EAAM,SAAU,SAAUA,EAAM,SAAU,EAC9DzB,EAACK,EAAA,CAAc,MAAO,CAAE,GAAGoB,EAAO,aAAAK,EAAc,SAAAqC,EAAU,WAAAG,GAAY,cAAArC,EAAc,EAC/E,SAAAyC,EACL,GACJ,CAER,CK5VA,OAAkD,eAAAQ,EAAa,cAAAC,GAAY,UAAAC,OAAc,QAoDjF,cAAAC,OAAA,oBAzCD,SAASC,GAAK,CAAE,KAAAC,EAAM,SAAAC,EAAW,QAAS,QAAAC,EAAU,GAAO,eAAAC,EAAiB,GAAO,SAAAC,EAAU,GAAGC,CAAM,EAAc,CACvH,IAAMC,EAASC,GAAWC,CAAa,EACjCC,EAAgBC,GAA6C,IAAI,EAEjEC,EAAmBC,EAAY,IAAM,CACnCH,EAAc,UAAY,OAC1B,aAAaA,EAAc,OAAO,EAClCA,EAAc,QAAU,KAEhC,EAAG,CAAC,CAAC,EAECI,EAAkBD,EAAY,IAAM,CAClC,CAACN,GAAUL,IAAa,QAC5BK,EAAO,cAAcN,CAAI,CAC7B,EAAG,CAACA,EAAMC,EAAUK,CAAM,CAAC,EAErBQ,EAAmBF,EAAY,IAAM,CACnCX,IAAa,SACjBQ,EAAc,QAAU,WAAWI,EAAiB,EAAE,EAC1D,EAAG,CAACZ,EAAUY,CAAe,CAAC,EAExBE,EAAmBH,EAAY,IAAM,CACvCD,EAAiB,CACrB,EAAG,CAACA,CAAgB,CAAC,EAEfK,EAAmBJ,EAAY,IAAM,CACvCD,EAAiB,EACjBE,EAAgB,CACpB,EAAG,CAACF,EAAkBE,CAAe,CAAC,EAYtC,OACIf,GAAC,KACG,KAAME,EACN,QAbmDiB,GAAM,CAI7D,GAHAN,EAAiB,EACb,CAACL,GACDW,EAAE,SAAWA,EAAE,SAAWA,EAAE,UAAYA,EAAE,SAAW,GACrDC,EAAUlB,CAAI,EAAE,OAAS,WAAY,OACzCiB,EAAE,eAAe,EACjB,IAAME,EAA2B,CAAE,QAAAjB,EAAS,eAAAC,CAAe,EAC3DG,EAAO,SAASN,EAAMmB,CAAO,CACjC,EAMQ,aAAcL,EACd,aAAcC,EACd,aAAcC,EACb,GAAGX,EAEH,SAAAD,EACL,CAER,CCrDO,SAASgB,GAAUC,EAAcC,EAAkC,CACtE,IAAMC,EAASF,EAAI,QAAQ,IAAI,QAAQ,EACvC,GAAKE,EACL,QAAWC,KAAQD,EAAO,MAAM,GAAG,EAAG,CAClC,GAAM,CAACE,EAAK,GAAGC,CAAI,EAAIF,EAAK,KAAK,EAAE,MAAM,GAAG,EAC5C,GAAIC,EAAI,KAAK,IAAMH,EAAM,OAAO,mBAAmBI,EAAK,KAAK,GAAG,CAAC,CACrE,CAEJ,CAEO,SAASC,GAAUC,EAAkBN,EAAcO,EAAeC,EAAyB,CAAC,EAAS,CACxG,IAAIC,EAAS,GAAGT,CAAI,IAAI,mBAAmBO,CAAK,CAAC,UAAUC,EAAQ,MAAQ,GAAG,GAC1EA,EAAQ,SAAoBC,GAAU,YAAYD,EAAQ,MAAM,IAChEA,EAAQ,SAAW,SAAWC,GAAU,aAAaD,EAAQ,MAAM,IACnEA,EAAQ,UAAoBC,GAAU,aAAaD,EAAQ,QAAQ,YAAY,CAAC,IAChFA,EAAQ,WAAoBC,GAAU,cACtCD,EAAQ,SAAoBC,GAAU,YACtCD,EAAQ,WAAoBC,GAAU,cAAcD,EAAQ,QAAQ,IACxEF,EAAQ,OAAO,aAAcG,CAAM,CACvC,CAEO,SAASC,GAAaJ,EAAkBN,EAAcQ,EAAkD,CAAC,EAAS,CACrHH,GAAUC,EAASN,EAAM,GAAI,CAAC,GAAGQ,EAAS,OAAQ,EAAG,QAAS,IAAI,KAAK,CAAC,CAAC,CAAC,CAC9E,CC1BO,SAASG,GAAcC,EAASC,EAAiB,IAA2B,CAC/E,OAAO,IAAI,SAAS,KAAK,UAAUD,CAAI,EAAG,CACtC,OAAAC,EACA,QAAS,CAAC,eAAgB,kBAAkB,CAChD,CAAC,CACL,CAEO,IAAMC,GAAO,CAACC,EAAcF,EAAS,MACxC,IAAI,SAASE,EAAM,CAAC,OAAAF,EAAQ,QAAS,CAAC,eAAgB,2BAA2B,CAAC,CAAC,EAEjFG,GAAiB,OAAO,IAAI,gBAAgB,EAc3C,SAASC,GAASC,EAAaC,EAAsD,CACxF,IAAMN,EAAS,OAAOM,GAAoB,SAAWA,EAAmBA,GAAiB,QAAU,IAC7FC,EAAU,OAAOD,GAAoB,SAAYA,GAAiB,SAAW,GAAS,GAC5F,MAAO,CAAC,CAACH,EAAc,EAAG,GAAM,IAAAE,EAAK,OAAAL,EAAQ,QAAAO,CAAO,CACxD,CAMA,IAAMC,GAAc,OAAO,IAAI,mBAAmB,EAS3C,SAASC,GAAMC,EAAoBC,EAAiBC,EAA4B,CACnF,MAAO,CAAE,CAACJ,EAAW,EAAG,GAAM,WAAAE,EAAY,QAAAC,EAAS,KAAAC,CAAK,CAC5D,CCpDO,IAAMC,GAAgB,oBAWtB,SAASC,GACZC,EACwD,CACxD,MAAO,CAAC,CAACF,EAAa,EAAG,GAAM,GAAAE,CAAE,CACrC,CCbO,IAAMC,EAAN,cAAsC,KAAM,CAC/C,YACoBC,EACAC,EACAC,EACAC,EAClB,CACE,MAAM,QAAQH,CAAM,KAAKC,CAAU,EAAE,EALrB,YAAAD,EACA,gBAAAC,EACA,cAAAC,EACA,UAAAC,EAGhB,KAAK,KAAO,YAChB,CACJ,ECgCA,eAAsBC,GAClBC,EACAC,EAC0B,CAC1B,IAAMC,EAASD,GAAS,QAAU,MAC5BE,EAAU,IAAI,QAAQF,GAAS,OAAO,EAExCG,EACAH,GAAS,OAAS,SACdA,EAAQ,gBAAgB,UAAYA,EAAQ,gBAAgB,MAAQA,EAAQ,gBAAgB,YAC5FG,EAAOH,EAAQ,MAEfG,EAAO,KAAK,UAAUH,EAAQ,IAAI,EAC7BE,EAAQ,IAAI,cAAc,GAC3BA,EAAQ,IAAI,eAAgB,kBAAkB,IAK1D,IAAME,EAAW,MAAM,MAAML,EAAM,CAAC,OAAAE,EAAQ,QAAAC,EAAS,KAAAC,EAAM,OAAQH,GAAS,MAAM,CAAC,EAEnF,GAAI,CAACI,EAAS,GAAI,CAEd,IAAMC,GADcD,EAAS,QAAQ,IAAI,cAAc,GAAK,IAC9B,SAAS,kBAAkB,EACnD,MAAMA,EAAS,KAAK,EACpB,OACN,MAAM,IAAIE,EAAWF,EAAS,OAAQA,EAAS,WAAYA,EAAUC,CAAS,CAClF,CAGA,OADoBD,EAAS,QAAQ,IAAI,cAAc,GAAK,IAC5C,SAAS,kBAAkB,EAChCA,EAAS,KAAK,EAGlBA,EAAS,KAAK,CACzB",
|
|
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", "resolveTo", "to", "base", "url", "pathname", "jsx", "jsxs", "DEFAULT_VIEWPORT", "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", "resolved", "resolveTo", "key", "matched", "matchClientRoute", "controller", "promise", "l", "pageMod", "layoutMods", "dataRes", "data", "expireTimer", "loadRoute", "to", "pathname", "ErrorPage", "loadErrorPage", "getDefaultErrorPage", "prev", "cached", "prefetched", "pm", "lm", "ct", "errorBody", "headers", "value", "m", "hash", "scrollBehavior", "navigate", "options", "run", "revalidate", "useEffect", "handlePop", "err", "content", "tree", "i", "Layout", "layoutData", "DevixErrorBoundary", "PageMetaContext", "HeadSlot", "useCallback", "useContext", "useRef", "jsx", "Link", "href", "prefetch", "replace", "viewTransition", "children", "props", "router", "useContext", "RouterContext", "hoverTimerRef", "useRef", "cancelHoverTimer", "useCallback", "triggerPrefetch", "handleMouseEnter", "handleMouseLeave", "handleTouchStart", "e", "resolveTo", "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/runtime/link.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{useCallback as l,useContext as
|
|
1
|
+
import{useCallback as l,useContext as _,useRef as R}from"react";import{createContext as c}from"react";var o=globalThis;o.__devix_RouterContext__??=c(null);var x=o.__devix_RouterContext__;o.__devix_PageMetaContext__??=c(null);o.__devix_RouteDataContext__??=c(null);var y=o.__devix_PageMetaContext__,L=o.__devix_RouteDataContext__;function d(n){let t=new URL(window.location.href);t.pathname.endsWith("/")||(t.pathname+="/");let e=new URL(n,t);if(e.origin!==window.location.origin)return{kind:"external",url:e};let u=e.pathname.length>1?e.pathname.replace(/\/$/,""):e.pathname;return{kind:"internal",pathname:u,href:u+e.search+e.hash}}import{jsx as T}from"react/jsx-runtime";function K({href:n,prefetch:t="hover",replace:e=!1,viewTransition:u=!1,children:g,...m}){let a=_(x),s=R(null),r=l(()=>{s.current!==null&&(clearTimeout(s.current),s.current=null)},[]),p=l(()=>{!a||t==="none"||a.prefetchRoute(n)},[n,t,a]),v=l(()=>{t!=="none"&&(s.current=setTimeout(p,50))},[t,p]),h=l(()=>{r()},[r]),C=l(()=>{r(),p()},[r,p]);return T("a",{href:n,onClick:i=>{if(r(),!a||i.ctrlKey||i.metaKey||i.shiftKey||i.button!==0||d(n).kind==="external")return;i.preventDefault();let f={replace:e,viewTransition:u};a.navigate(n,f)},onMouseEnter:v,onMouseLeave:h,onTouchStart:C,...m,children:g})}export{K as Link};
|
|
2
2
|
//# sourceMappingURL=link.js.map
|
package/dist/runtime/link.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../../src/runtime/link.tsx", "../../src/runtime/context.tsx"],
|
|
4
|
-
"sourcesContent": ["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\
|
|
5
|
-
"mappings": "AAAA,OAAkD,eAAAA,EAAa,cAAAC,EAAY,UAAAC,MAAc,QCAzF,OAAQ,iBAAAC,MAA4C,QAmCpD,IAAMC,EAAI,WAEVA,EAAE,0BAA4BD,EAAyC,IAAI,EACpE,IAAME,EAAoDD,EAAE,wBAEnEA,EAAE,4BAA8BD,EAA2C,IAAI,EAC/EC,EAAE,6BAA+BD,EAA4C,IAAI,EAE1E,IAAMG,EAAwDF,EAAE,0BAC1DG,EAA0DH,EAAE,
|
|
6
|
-
"names": ["useCallback", "useContext", "useRef", "createContext", "g", "RouterContext", "PageMetaContext", "RouteDataContext", "
|
|
3
|
+
"sources": ["../../src/runtime/link.tsx", "../../src/runtime/context.tsx", "../../src/runtime/url.ts"],
|
|
4
|
+
"sourcesContent": ["import { AnchorHTMLAttributes, MouseEventHandler, useCallback, useContext, useRef } from \"react\"\nimport { NavigateOptions, RouterContext } from './context'\nimport { resolveTo } from './url'\n\ninterface LinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {\n href: string\n prefetch?: 'hover' | 'none'\n replace?: boolean\n viewTransition?: boolean\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(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) return\n if (resolveTo(href).kind === 'external') return\n e.preventDefault()\n const options: NavigateOptions = { replace, viewTransition }\n router.navigate(href, options)\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}", "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", "export type ResolvedTo =\n | { kind: 'internal'; pathname: string; href: string }\n | { kind: 'external'; url: URL }\n\nexport function resolveTo(to: string): ResolvedTo {\n const base = new URL(window.location.href)\n if (!base.pathname.endsWith('/')) base.pathname += '/'\n\n const url = new URL(to, base)\n\n if (url.origin !== window.location.origin) {\n return { kind: 'external', url }\n }\n\n const pathname = url.pathname.length > 1\n ? url.pathname.replace(/\\/$/, '')\n : url.pathname\n\n return {\n kind: 'internal',\n pathname,\n href: pathname + url.search + url.hash,\n }\n}\n"],
|
|
5
|
+
"mappings": "AAAA,OAAkD,eAAAA,EAAa,cAAAC,EAAY,UAAAC,MAAc,QCAzF,OAAQ,iBAAAC,MAA4C,QAmCpD,IAAMC,EAAI,WAEVA,EAAE,0BAA4BD,EAAyC,IAAI,EACpE,IAAME,EAAoDD,EAAE,wBAEnEA,EAAE,4BAA8BD,EAA2C,IAAI,EAC/EC,EAAE,6BAA+BD,EAA4C,IAAI,EAE1E,IAAMG,EAAwDF,EAAE,0BAC1DG,EAA0DH,EAAE,2BCxClE,SAASI,EAAUC,EAAwB,CAC9C,IAAMC,EAAO,IAAI,IAAI,OAAO,SAAS,IAAI,EACpCA,EAAK,SAAS,SAAS,GAAG,IAAGA,EAAK,UAAY,KAEnD,IAAMC,EAAM,IAAI,IAAIF,EAAIC,CAAI,EAE5B,GAAIC,EAAI,SAAW,OAAO,SAAS,OAC/B,MAAO,CAAE,KAAM,WAAY,IAAAA,CAAI,EAGnC,IAAMC,EAAWD,EAAI,SAAS,OAAS,EACjCA,EAAI,SAAS,QAAQ,MAAO,EAAE,EAC9BA,EAAI,SAEV,MAAO,CACH,KAAM,WACN,SAAAC,EACA,KAAMA,EAAWD,EAAI,OAASA,EAAI,IACtC,CACJ,CF6BQ,cAAAE,MAAA,oBAzCD,SAASC,EAAK,CAAE,KAAAC,EAAM,SAAAC,EAAW,QAAS,QAAAC,EAAU,GAAO,eAAAC,EAAiB,GAAO,SAAAC,EAAU,GAAGC,CAAM,EAAc,CACvH,IAAMC,EAASC,EAAWC,CAAa,EACjCC,EAAgBC,EAA6C,IAAI,EAEjEC,EAAmBC,EAAY,IAAM,CACnCH,EAAc,UAAY,OAC1B,aAAaA,EAAc,OAAO,EAClCA,EAAc,QAAU,KAEhC,EAAG,CAAC,CAAC,EAECI,EAAkBD,EAAY,IAAM,CAClC,CAACN,GAAUL,IAAa,QAC5BK,EAAO,cAAcN,CAAI,CAC7B,EAAG,CAACA,EAAMC,EAAUK,CAAM,CAAC,EAErBQ,EAAmBF,EAAY,IAAM,CACnCX,IAAa,SACjBQ,EAAc,QAAU,WAAWI,EAAiB,EAAE,EAC1D,EAAG,CAACZ,EAAUY,CAAe,CAAC,EAExBE,EAAmBH,EAAY,IAAM,CACvCD,EAAiB,CACrB,EAAG,CAACA,CAAgB,CAAC,EAEfK,EAAmBJ,EAAY,IAAM,CACvCD,EAAiB,EACjBE,EAAgB,CACpB,EAAG,CAACF,EAAkBE,CAAe,CAAC,EAYtC,OACIf,EAAC,KACG,KAAME,EACN,QAbmDiB,GAAM,CAI7D,GAHAN,EAAiB,EACb,CAACL,GACDW,EAAE,SAAWA,EAAE,SAAWA,EAAE,UAAYA,EAAE,SAAW,GACrDC,EAAUlB,CAAI,EAAE,OAAS,WAAY,OACzCiB,EAAE,eAAe,EACjB,IAAME,EAA2B,CAAE,QAAAjB,EAAS,eAAAC,CAAe,EAC3DG,EAAO,SAASN,EAAMmB,CAAO,CACjC,EAMQ,aAAcL,EACd,aAAcC,EACd,aAAcC,EACb,GAAGX,EAEH,SAAAD,EACL,CAER",
|
|
6
|
+
"names": ["useCallback", "useContext", "useRef", "createContext", "g", "RouterContext", "PageMetaContext", "RouteDataContext", "resolveTo", "to", "base", "url", "pathname", "jsx", "Link", "href", "prefetch", "replace", "viewTransition", "children", "props", "router", "useContext", "RouterContext", "hoverTimerRef", "useRef", "cancelHoverTimer", "useCallback", "triggerPrefetch", "handleMouseEnter", "handleMouseLeave", "handleTouchStart", "e", "resolveTo", "options"]
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{useCallback as
|
|
1
|
+
import{useCallback as j,useContext as k,useEffect as ue,useRef as X,useState as Y}from"react";import{RouterContext as $}from"virtual:devix/context";import{getDefaultErrorPage as Z,loadErrorPage as ee,matchClientRoute as te}from"virtual:devix/client-routes";import{Fragment as J,jsx as D}from"react/jsx-runtime";function se(e,r){let t=[];e.title&&t.push({tag:"title",children:e.title}),e.description&&t.push({tag:"meta",name:"description",content:e.description}),e.keywords?.length&&t.push({tag:"meta",name:"keywords",content:e.keywords.join(", ")});let s=e.og?.title??e.title;s&&t.push({tag:"meta",property:"og:title",content:s});let f=e.og?.description??e.description;f&&t.push({tag:"meta",property:"og:description",content:f}),e.og?.image&&t.push({tag:"meta",property:"og:image",content:e.og.image}),e.og?.type&&t.push({tag:"meta",property:"og:type",content:e.og.type}),e.og?.url&&t.push({tag:"meta",property:"og:url",content:e.og.url});let _=e.twitter?.title??e.title;_&&t.push({tag:"meta",name:"twitter:title",content:_});let M=e.twitter?.description??e.description;if(M&&t.push({tag:"meta",name:"twitter:description",content:M}),e.twitter?.card&&t.push({tag:"meta",name:"twitter:card",content:e.twitter.card}),e.twitter?.image&&t.push({tag:"meta",name:"twitter:image",content:e.twitter.image}),e.twitter?.creator&&t.push({tag:"meta",name:"twitter:creator",content:e.twitter.creator}),e.canonical&&t.push({tag:"link",rel:"canonical",href:e.canonical}),e.robots&&t.push({tag:"meta",name:"robots",content:e.robots}),e.alternates)for(let[p,y]of Object.entries(e.alternates))t.push({tag:"link",rel:"alternate",href:y,hrefLang:p});if(e.icons){let p=Array.isArray(e.icons)?e.icons:[e.icons];for(let y of p){let m=typeof y=="string"?{href:y}:y;t.push({tag:"link",rel:m.rel??"icon",href:m.href,...m.type&&{type:m.type},...m.sizes&&{sizes:m.sizes}})}}if(r){let p=[];r.width!==void 0&&p.push(`width=${r.width}`),r.initialScale!==void 0&&p.push(`initial-scale=${r.initialScale}`),r.maximumScale!==void 0&&p.push(`maximum-scale=${r.maximumScale}`),r.userScalable!==void 0&&p.push(`user-scalable=${r.userScalable?"yes":"no"}`),p.length&&t.push({tag:"meta",name:"viewport",content:p.join(", ")}),r.themeColor&&t.push({tag:"meta",name:"theme-color",content:r.themeColor})}return t}function G({metadata:e,viewport:r}){return typeof window>"u"||!e?null:D(J,{children:le(e,r)})}function le(e,r){let t=se(e,r);return D(J,{children:t.map((s,f)=>s.tag==="title"?D("title",{children:s.children},f):s.tag==="link"?D("link",{rel:s.rel,href:s.href,hrefLang:s.hrefLang,type:s.type,sizes:s.sizes},f):D("meta",{name:s.name,property:s.property,content:s.content},f))})}import{createContext as U}from"react";var P=globalThis;P.__devix_RouterContext__??=U(null);var Pe=P.__devix_RouterContext__;P.__devix_PageMetaContext__??=U(null);P.__devix_RouteDataContext__??=U(null);var K=P.__devix_PageMetaContext__,b=P.__devix_RouteDataContext__;import{Component as ce}from"react";import{jsx as Q}from"react/jsx-runtime";var A=class extends ce{state={error:null};static getDerivedStateFromError(r){return r instanceof F?{error:{statusCode:r.statusCode,message:r.message}}:{error:{statusCode:500,message:r instanceof Error?r.message:"Unknown error"}}}render(){return this.state.error&&this.props.ErrorPage?Q(this.props.ErrorPage,{...this.state.error}):this.state.error?Q("h1",{children:this.state.error.statusCode}):this.props.children}},F=class extends Error{statusCode;constructor(r,t){super(t),this.statusCode=r}};function H(e){let r=new URL(window.location.href);r.pathname.endsWith("/")||(r.pathname+="/");let t=new URL(e,r);if(t.origin!==window.location.origin)return{kind:"external",url:t};let s=t.pathname.length>1?t.pathname.replace(/\/$/,""):t.pathname;return{kind:"internal",pathname:s,href:s+t.search+t.hash}}import{jsx as g,jsxs as fe}from"react/jsx-runtime";var pe={width:"device-width",initialScale:1};function ze(){return k($)}var de=()=>Promise.resolve(),ge=()=>Promise.resolve();function Be(){return k($)?.navigate??de}function Ie(){return k($)?.revalidate??ge}function Oe(){let e=k(b);if(!e)throw new Error("useParams must be used within a route or layout");return e.params}function Ue(){let e=k(b);if(!e)throw new Error("useLoaderData must be used within a route or layout");return e.loaderData}function Fe({initialData:e,initialParams:r,initialPage:t,initialLayouts:s=[],initialLayoutsData:f=[],initialMeta:_,initialViewport:M,initialError:p,initialErrorPage:y,clientEntry:m}){let[a,L]=Y({pathname:window.location.pathname,params:r,loaderData:e,layoutsData:f,Page:t,layouts:s,metadata:_??null,viewport:M,pendingError:p,ErrorPage:y}),S=X(null),[re,W]=Y(!1),C=X(new Map),oe=j(l=>{let n=H(l);if(n.kind==="external")return;let i=n.href;if(C.current.has(i))return;let o=te(n.pathname);if(!o)return;let c=new AbortController,d=Promise.all([Promise.all([o.load(),...o.loadLayouts.map(h=>h())]),fetch(`/_data${i}`,{headers:{Accept:"application/json"},signal:c.signal})]).then(async([[h,...u],E])=>{if(!E.ok||!h.default)return null;let V=await E.json();return{pageMod:h,layoutMods:u,data:V}}).catch(()=>null),v=setTimeout(()=>{c.abort(),C.current.delete(i)},3e3);d.finally(()=>clearTimeout(v)),C.current.set(i,{promise:d,controller:c})},[]),R=j(async(l,n)=>{let i=l.split("?")[0].split("#")[0],o=te(i);if(!o){let w=await ee()??Z();L(I=>({...I,pathname:i,pendingError:{statusCode:404,message:"Not found"},ErrorPage:w??void 0}));return}let c=C.current.get(l);c&&C.current.delete(l);let d=c?await c.promise:null;if(n.signal.aborted)return;let v,h,u;if(d)({pageMod:v,layoutMods:h,data:u}=d);else{let[[w,...I],x]=await Promise.all([Promise.all([o.load(),...o.loadLayouts.map(N=>N())]),fetch(`/_data${l}`,{headers:{Accept:"application/json"},signal:n.signal})]);if(n.signal.aborted||!w.default)return;if(!x.ok){let N=x.headers.get("Content-Type")??"",T=null;try{N.includes("application/json")?T=await x.json():N.includes("text/plain")&&(T={message:await x.text()})}catch{}let q={};x.headers.forEach((O,ie)=>{q[ie]=O});let ne=await ee()??Z();L(O=>({...O,pathname:i,pendingError:{statusCode:T?.statusCode??x.status,message:T?.message??"Server error",data:T?.data,headers:q},ErrorPage:ne??void 0}));return}v=w,h=I,u=await x.json()}if(u.redirect){u.redirectReplace?window.history.replaceState(null,"",u.redirect):window.history.pushState(null,"",u.redirect),await R(u.redirect,n);return}L({pathname:i,params:u.params??{},loaderData:u.loaderData,layoutsData:(u.layouts??[]).map(w=>w.loaderData),Page:v.default,layouts:h.map(w=>w.default),metadata:u.metadata??null,viewport:u.viewport??pe});let E=l.includes("#")?l.split("#")[1]:null,V=getComputedStyle(document.documentElement).scrollBehavior;E?requestAnimationFrame(()=>{document.getElementById(E)?.scrollIntoView({behavior:V})}):window.scrollTo({top:0,behavior:V})},[]),z=j(async(l,n)=>{let i=H(l);if(i.kind==="external"){window.location.href=i.url.href;return}let o=i.href;S.current?.abort();let c=new AbortController;S.current=c,W(!0);let d=async()=>{window.history[n?.replace?"replaceState":"pushState"](null,"",o),await R(o,c)};try{n?.viewTransition&&"startViewTransition"in document?await document.startViewTransition(d).finished:await d()}finally{c.signal.aborted||W(!1)}},[R]),ae=j(async()=>{let l=window.location.pathname+window.location.search,n=new AbortController,i=await fetch(`/_data${l}`,{headers:{Accept:"application/json"},signal:n.signal});if(!i.ok)return;let o=await i.json();if(o.redirect){await z(o.redirect,{replace:o.redirectReplace});return}L(c=>({...c,loaderData:o.loaderData,layoutsData:(o.layouts??[]).map(d=>d.loaderData),params:o.params??c.params,metadata:o.metadata??c.metadata,viewport:o.viewport??c.viewport}))},[z]);ue(()=>{let l=()=>{S.current?.abort();let n=new AbortController;S.current=n;let i=window.location.pathname+window.location.search;R(i,n).catch(o=>{o.name!=="AbortError"&&console.error("[router] popstate error:",o)})};return window.addEventListener("popstate",l),()=>window.removeEventListener("popstate",l)},[R]);let B;if(a.pendingError)B=a.ErrorPage?g(a.ErrorPage,{...a.pendingError}):g("h1",{children:a.pendingError.statusCode});else{let l=g(b,{value:{loaderData:a.loaderData,params:a.params},children:g(a.Page,{data:a.loaderData,params:a.params,url:a.pathname})});for(let n=a.layouts.length-1;n>=0;n--){let i=a.layouts[n],o=a.layoutsData[n];l=g(b,{value:{loaderData:o,params:a.params},children:g(i,{data:o,params:a.params,children:l})})}B=g(A,{ErrorPage:a.ErrorPage,children:l},a.pathname)}return fe(K,{value:{metadata:a.metadata,viewport:a.viewport,clientEntry:m},children:[g(G,{metadata:a.metadata,viewport:a.viewport}),g($,{value:{...a,isNavigating:re,navigate:z,revalidate:ae,prefetchRoute:oe},children:B})]})}export{Fe as RouterProvider,Ue as useLoaderData,Be as useNavigate,Oe as useParams,Ie as useRevalidate,ze as useRouter};
|
|
2
2
|
//# sourceMappingURL=router-provider.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../../src/runtime/router-provider.tsx", "../../src/runtime/head.tsx", "../../src/runtime/context.tsx", "../../src/runtime/error-boundary.tsx"],
|
|
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\";\n\nconst DEFAULT_VIEWPORT: Viewport = { width: 'device-width', initialScale: 1 }\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 ?? DEFAULT_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"],
|
|
5
|
-
"mappings": "AAAA,OAAmC,eAAAA,EAAa,cAAAC,EAAY,aAAAC,GAAW,UAAAC,EAAQ,YAAAC,MAAgB,QAC/F,OAAS,iBAAAC,MAAqB,wBAK9B,OAAS,uBAAAC,EAAqB,iBAAAC,EAAe,oBAAAC,OAAwB,8BC4E1D,mBAAAC,EAAA,OAAAC,MAAA,oBA1EX,SAASC,GAAYC,EAAoBC,EAAgC,CACrE,IAAMC,EAAkB,CAAC,EAErBF,EAAS,OACTE,EAAK,KAAK,CAAE,IAAK,QAAS,SAAUF,EAAS,KAAM,CAAC,EACpDA,EAAS,aACTE,EAAK,KAAK,CAAE,IAAK,OAAQ,KAAM,cAAe,QAASF,EAAS,WAAY,CAAC,EAC7EA,EAAS,UAAU,QACnBE,EAAK,KAAK,CAAE,IAAK,OAAQ,KAAM,WAAY,QAASF,EAAS,SAAS,KAAK,IAAI,CAAE,CAAC,EAEtF,IAAMG,EAAUH,EAAS,IAAI,OAASA,EAAS,MAC3CG,GAASD,EAAK,KAAK,CAAE,IAAK,OAAQ,SAAU,WAAY,QAASC,CAAQ,CAAC,EAC9E,IAAMC,EAASJ,EAAS,IAAI,aAAeA,EAAS,YAChDI,GAAQF,EAAK,KAAK,CAAE,IAAK,OAAQ,SAAU,iBAAkB,QAASE,CAAO,CAAC,EAC9EJ,EAAS,IAAI,OAAOE,EAAK,KAAK,CAAE,IAAK,OAAQ,SAAU,WAAY,QAASF,EAAS,GAAG,KAAM,CAAC,EAC/FA,EAAS,IAAI,MAAME,EAAK,KAAK,CAAE,IAAK,OAAQ,SAAU,UAAW,QAASF,EAAS,GAAG,IAAK,CAAC,EAC5FA,EAAS,IAAI,KAAKE,EAAK,KAAK,CAAE,IAAK,OAAQ,SAAU,SAAU,QAASF,EAAS,GAAG,GAAI,CAAC,EAE7F,IAAMK,EAAUL,EAAS,SAAS,OAASA,EAAS,MAChDK,GAASH,EAAK,KAAK,CAAE,IAAK,OAAQ,KAAM,gBAAiB,QAASG,CAAQ,CAAC,EAC/E,IAAMC,EAASN,EAAS,SAAS,aAAeA,EAAS,YAiBzD,GAhBIM,GAAQJ,EAAK,KAAK,CAAE,IAAK,OAAQ,KAAM,sBAAuB,QAASI,CAAO,CAAC,EAC/EN,EAAS,SAAS,MAAME,EAAK,KAAK,CAClC,IAAK,OAAQ,KAAM,eAAgB,QAC/BF,EAAS,QAAQ,IACzB,CAAC,EACGA,EAAS,SAAS,OAAOE,EAAK,KAAK,CACnC,IAAK,OAAQ,KAAM,gBAAiB,QAChCF,EAAS,QAAQ,KACzB,CAAC,EACGA,EAAS,SAAS,SAASE,EAAK,KAAK,CACrC,IAAK,OAAQ,KAAM,kBAAmB,QAClCF,EAAS,QAAQ,OACzB,CAAC,EAEGA,EAAS,WAAWE,EAAK,KAAK,CAAE,IAAK,OAAQ,IAAK,YAAa,KAAMF,EAAS,SAAU,CAAC,EACzFA,EAAS,QAAQE,EAAK,KAAK,CAAE,IAAK,OAAQ,KAAM,SAAU,QAASF,EAAS,MAAO,CAAC,EACpFA,EAAS,WACT,OAAW,CAACO,EAAMC,CAAI,IAAK,OAAO,QAAQR,EAAS,UAAU,EACzDE,EAAK,KAAK,CAAE,IAAK,OAAQ,IAAK,YAAa,KAAAM,EAAM,SAAUD,CAAK,CAAC,EAGzE,GAAIP,EAAS,MAAO,CAChB,IAAMS,EAAM,MAAM,QAAQT,EAAS,KAAK,EAAIA,EAAS,MAAQ,CAACA,EAAS,KAAK,EAC5E,QAAWU,KAAQD,EAAK,CACpB,IAAME,EAAyB,OAAOD,GAAS,SAAW,CAAE,KAAMA,CAAK,EAAIA,EAC3ER,EAAK,KAAK,CACN,IAAK,OACL,IAAKS,EAAS,KAAO,OACrB,KAAMA,EAAS,KACf,GAAIA,EAAS,MAAQ,CAAE,KAAMA,EAAS,IAAK,EAC3C,GAAIA,EAAS,OAAS,CAAE,MAAOA,EAAS,KAAM,CAClD,CAAC,CACL,CACJ,CAEA,GAAIV,EAAU,CACV,IAAMW,EAAkB,CAAC,EACrBX,EAAS,QAAU,QAAWW,EAAM,KAAK,SAASX,EAAS,KAAK,EAAE,EAClEA,EAAS,eAAiB,QAAWW,EAAM,KAAK,iBAAiBX,EAAS,YAAY,EAAE,EACxFA,EAAS,eAAiB,QAAWW,EAAM,KAAK,iBAAiBX,EAAS,YAAY,EAAE,EACxFA,EAAS,eAAiB,QAAWW,EAAM,KAAK,iBAAiBX,EAAS,aAAe,MACzF,IAAI,EAAE,EACNW,EAAM,QAAQV,EAAK,KAAK,CAAE,IAAK,OAAQ,KAAM,WAAY,QAASU,EAAM,KAAK,IAAI,CAAE,CAAC,EACpFX,EAAS,YAAYC,EAAK,KAAK,CAC/B,IAAK,OAAQ,KAAM,cAAe,QAASD,EAAS,UACxD,CAAC,CACL,CAEA,OAAOC,CACX,CAEO,SAASW,EAAS,CAAE,SAAAb,EAAU,SAAAC,CAAS,EAAuD,CACjG,OAAI,OAAO,OAAW,KAAe,CAACD,EAAiB,KAChDF,EAAAD,EAAA,CAAG,SAAAiB,GAAed,EAAUC,CAAQ,EAAE,CACjD,CAEO,SAASa,GAAed,EAAoBC,EAAgC,CAC/E,IAAMC,EAAOH,GAAYC,EAAUC,CAAQ,EAE3C,OAAOH,EAAAD,EAAA,CACF,SAAAK,EAAK,IAAI,CAACa,EAAGC,IACND,EAAE,MAAQ,QAAgBjB,EAAC,SAAe,SAAAiB,EAAE,UAANC,CAAe,EACrDD,EAAE,MAAQ,OAAejB,EAAC,QAAa,IAAKiB,EAAE,IAAK,KAAMA,EAAE,KAAM,SAAUA,EAAE,SAAU,KAAMA,EAAE,KAAM,MAAOA,EAAE,OAA1EC,CAAiF,EAClHlB,EAAC,QAAa,KAAMiB,EAAE,KAAM,SAAUA,EAAE,SAAU,QAASA,EAAE,SAAlDC,CAA2D,CAChF,EACL,CACJ,CC/FA,OAAQ,iBAAAC,MAA4C,QAmCpD,IAAMC,EAAI,WAEVA,EAAE,0BAA4BD,EAAyC,IAAI,EACpE,IAAME,GAAoDD,EAAE,wBAEnEA,EAAE,4BAA8BD,EAA2C,IAAI,EAC/EC,EAAE,6BAA+BD,EAA4C,IAAI,EAE1E,IAAMG,EAAwDF,EAAE,0BAC1DG,EAA0DH,EAAE,2BC5CzE,OAAQ,aAAAI,OAA0C,QA4B/B,cAAAC,MAAA,oBAhBZ,IAAMC,EAAN,cAAiCF,EAAwB,CAC5D,MAAe,CAAE,MAAO,IAAK,EAE7B,OAAO,yBAAyBG,EAAqB,CACjD,OAAIA,aAAeC,EACR,CACH,MAAO,CAAC,WAAYD,EAAI,WAAY,QAASA,EAAI,OAAO,CAC5D,EAEI,CACJ,MAAO,CAAC,WAAY,IAAK,QAASA,aAAe,MAAQA,EAAI,QAAU,eAAe,CAC1F,CACJ,CAEA,QAAS,CACL,OAAI,KAAK,MAAM,OAAS,KAAK,MAAM,UACxBF,EAAC,KAAK,MAAM,UAAX,CAAsB,GAAG,KAAK,MAAM,MAAO,EAEnD,KAAK,MAAM,MACJA,EAAC,MAAI,cAAK,MAAM,MAAM,WAAW,EAErC,KAAK,MAAM,QACtB,CACJ,EAEaG,EAAN,cAAyB,KAAM,CAClC,WACA,YAAYC,EAAoBC,EAAiB,CAC7C,MAAMA,CAAO,EACb,KAAK,WAAaD,CACtB,CACJ,EHgQc,cAAAE,EA2BN,QAAAC,OA3BM,oBAtSd,IAAMC,GAA6B,CAAE,MAAO,eAAgB,aAAc,CAAE,EAoBrE,SAASC,IAAY,CACxB,OAAOC,EAAWC,CAAa,CACnC,CAEA,IAAMC,GAAe,IAAM,QAAQ,QAAQ,EACrCC,GAAiB,IAAM,QAAQ,QAAQ,EAEtC,SAASC,IAAc,CAE1B,OADYJ,EAAWC,CAAa,GACxB,UAAYC,EAC5B,CAEO,SAASG,IAAgB,CAE5B,OADYL,EAAWC,CAAa,GACxB,YAAcE,EAC9B,CAEO,SAASG,IAA8C,CAC1D,IAAMC,EAAMP,EAAWQ,CAAgB,EACvC,GAAI,CAACD,EAAK,MAAM,IAAI,MAAM,iDAAiD,EAC3E,OAAOA,EAAI,MACf,CAQO,SAASE,IAAmB,CAC/B,IAAMF,EAAMP,EAAWQ,CAAgB,EACvC,GAAI,CAACD,EAAK,MAAM,IAAI,MAAM,qDAAqD,EAC/E,OAAOA,EAAI,UACf,CAoBO,SAASG,GAAe,CAC3B,YAAAC,EACA,cAAAC,EACA,YAAAC,EACA,eAAAC,EAAiB,CAAC,EAClB,mBAAAC,EAAqB,CAAC,EACtB,YAAAC,EACA,gBAAAC,EACA,aAAAC,EACA,iBAAAC,EACA,YAAAC,CACJ,EAAwB,CAEpB,GAAM,CAACC,EAAOC,CAAQ,EAAIC,EAAqB,CAC3C,SAAU,OAAO,SAAS,SAC1B,OAAQX,EACR,WAAYD,EACZ,YAAaI,EACb,KAAMF,EACN,QAASC,EACT,SAAUE,GAAe,KACzB,SAAUC,EACV,aAAcC,EACd,UAAWC,CACf,CAAC,EAEKK,EAAgBC,EAA+B,IAAI,EACnD,CAACC,GAAcC,CAAe,EAAIJ,EAAS,EAAK,EAEhDK,EAAmBH,EAAmC,IAAI,GAAK,EAE/DI,GAAgBC,EAAaC,GAAiB,CAChD,GAAIH,EAAiB,QAAQ,IAAIG,CAAI,EAAG,OACxC,IAAMC,EAAWD,EAAK,MAAM,GAAG,EAAE,CAAC,EAAE,MAAM,GAAG,EAAE,CAAC,EAC1CE,EAAUC,GAAiBF,CAAQ,EACzC,GAAI,CAACC,EAAS,OAEd,IAAME,EAAa,IAAI,gBACjBC,EAAU,QAAQ,IAAI,CACxB,QAAQ,IAAI,CAACH,EAAQ,KAAK,EAAG,GAAGA,EAAQ,YAAY,IAAII,GAAKA,EAAE,CAAC,CAAC,CAAC,EAClE,MAAM,SAASN,CAAI,GAAI,CAAE,QAAS,CAAE,OAAQ,kBAAmB,EAAG,OAAQI,EAAW,MAAO,CAAC,CACjG,CAAC,EAAE,KAAK,MAAO,CAAC,CAACG,EAAY,GAAAC,CAAU,EAAGC,CAAO,IAAM,CACnD,GAAI,CAACA,EAAQ,IAAM,CAACF,EAAQ,QAAS,OAAO,KAC5C,IAAMG,EAAO,MAAMD,EAAQ,KAAK,EAChC,MAAO,CAAE,QAAAF,EAAS,WAAAC,EAAY,KAAAE,CAAK,CACvC,CAAC,EAAE,MAAM,IAAM,IAAI,EAEbC,EAAc,WAAW,IAAM,CACjCP,EAAW,MAAM,EACjBP,EAAiB,QAAQ,OAAOG,CAAI,CACxC,EAAG,GAAI,EACPK,EAAQ,QAAQ,IAAM,aAAaM,CAAW,CAAC,EAE/Cd,EAAiB,QAAQ,IAAIG,EAAM,CAAE,QAAAK,EAAS,WAAAD,CAAW,CAAC,CAC9D,EAAG,CAAC,CAAC,EAECQ,EAAYb,EAAY,MAAOc,EAAYT,IAAgC,CAC7E,IAAMH,EAAWY,EAAG,MAAM,GAAG,EAAE,CAAC,EAAE,MAAM,GAAG,EAAE,CAAC,EACxCX,EAAUC,GAAiBF,CAAQ,EACzC,GAAI,CAACC,EAAS,CACV,IAAMY,EAAY,MAAMC,EAAc,GAAKC,EAAoB,EAC/DzB,EAAS0B,IAAS,CACd,GAAGA,EACH,SAAUhB,EACV,aAAc,CAAE,WAAY,IAAK,QAAS,WAAY,EACtD,UAAWa,GAAa,MAC5B,EAAE,EACF,MACJ,CAEA,IAAMI,EAASrB,EAAiB,QAAQ,IAAIgB,CAAE,EAC1CK,GAAQrB,EAAiB,QAAQ,OAAOgB,CAAE,EAC9C,IAAMM,EAAaD,EAAS,MAAMA,EAAO,QAAU,KAEnD,GAAId,EAAW,OAAO,QAAS,OAE/B,IAAIG,EAAcC,EAAmBE,EAErC,GAAIS,GACE,CAAE,QAAAZ,EAAS,WAAAC,EAAY,KAAAE,CAAK,EAAIS,OAC/B,CACH,GAAM,CAAC,CAACC,EAAI,GAAGC,CAAE,EAAGZ,CAAO,EAAI,MAAM,QAAQ,IAAI,CAC7C,QAAQ,IAAI,CACRP,EAAQ,KAAK,EACb,GAAGA,EAAQ,YAAY,IAAII,GAAKA,EAAE,CAAC,CACvC,CAAC,EACD,MAAM,SAASO,CAAE,GAAI,CACjB,QAAS,CAAE,OAAQ,kBAAmB,EACtC,OAAQT,EAAW,MACvB,CAAC,CACL,CAAC,EAGD,GADIA,EAAW,OAAO,SAClB,CAACgB,EAAG,QAAS,OAEjB,GAAI,CAACX,EAAQ,GAAI,CACb,IAAMa,EAAKb,EAAQ,QAAQ,IAAI,cAAc,GAAK,GAC9Cc,EAA8E,KAClF,GAAI,CACID,EAAG,SAAS,kBAAkB,EAAGC,EAAY,MAAMd,EAAQ,KAAK,EAC3Da,EAAG,SAAS,YAAY,IAAGC,EAAY,CAAE,QAAS,MAAMd,EAAQ,KAAK,CAAE,EACpF,MAAQ,CAAmC,CAE3C,IAAMe,EAAkC,CAAC,EACzCf,EAAQ,QAAQ,QAAQ,CAACgB,EAAOC,KAAQ,CAAEF,EAAQE,EAAG,EAAID,CAAM,CAAC,EAEhE,IAAMX,GAAY,MAAMC,EAAc,GAAKC,EAAoB,EAC/DzB,EAAS0B,IAAS,CACd,GAAGA,EACH,SAAAhB,EACA,aAAc,CACV,WAAYsB,GAAW,YAAcd,EAAQ,OAC7C,QAASc,GAAW,SAAW,eAC/B,KAAMA,GAAW,KACjB,QAAAC,CACJ,EACA,UAAWV,IAAa,MAC5B,EAAE,EACF,MACJ,CAEAP,EAAUa,EACVZ,EAAaa,EACbX,EAAO,MAAMD,EAAQ,KAAK,CAC9B,CAEA,GAAIC,EAAK,SAAU,CACXA,EAAK,gBACL,OAAO,QAAQ,aAAa,KAAM,GAAIA,EAAK,QAAQ,EAEnD,OAAO,QAAQ,UAAU,KAAM,GAAIA,EAAK,QAAQ,EAEpD,MAAME,EAAUF,EAAK,SAAUN,CAAU,EACzC,MACJ,CAEAb,EAAS,CACL,SAAAU,EACA,OAAQS,EAAK,QAAU,CAAC,EACxB,WAAYA,EAAK,WACjB,aAAcA,EAAK,SAAW,CAAC,GAAG,IAAKJ,GAAWA,EAAE,UAAU,EAC9D,KAAMC,EAAQ,QACd,QAASC,EAAW,IAAImB,GAAKA,EAAE,OAAO,EACtC,SAAUjB,EAAK,UAAY,KAC3B,SAAUA,EAAK,UAAY3C,EAC/B,CAAC,EAED,IAAM6D,EAAOf,EAAG,SAAS,GAAG,EAAIA,EAAG,MAAM,GAAG,EAAE,CAAC,EAAI,KAC7CgB,EAAiB,iBAAiB,SAAS,eAAe,EAAE,eAC9DD,EACA,sBAAsB,IAAM,CACxB,SAAS,eAAeA,CAAI,GAAG,eAAe,CAAE,SAAUC,CAAe,CAAC,CAC9E,CAAC,EAED,OAAO,SAAS,CAAE,IAAK,EAAG,SAAUA,CAAe,CAAC,CAE5D,EAAG,CAAC,CAAC,EAECC,EAAW/B,EAAY,MAAOc,EAAYkB,IAA8B,CAC1EtC,EAAc,SAAS,MAAM,EAC7B,IAAMW,EAAa,IAAI,gBACvBX,EAAc,QAAUW,EAExBR,EAAgB,EAAI,EACpB,IAAMoC,EAAM,SAAY,CACpB,OAAO,QAAQD,GAAS,QAAU,eAAiB,WAAW,EAAE,KAAM,GAAIlB,CAAE,EAC5E,MAAMD,EAAUC,EAAIT,CAAU,CAClC,EACA,GAAI,CACI2B,GAAS,gBAAkB,wBAAyB,SACpD,MAAO,SAAiB,oBAAoBC,CAAG,EAAE,SAEjD,MAAMA,EAAI,CAElB,QAAE,CACO5B,EAAW,OAAO,SAASR,EAAgB,EAAK,CACzD,CACJ,EAAG,CAACgB,CAAS,CAAC,EAERqB,GAAalC,EAAY,SAAY,CACvC,IAAMc,EAAK,OAAO,SAAS,SAAW,OAAO,SAAS,OAChDT,EAAa,IAAI,gBACjBK,EAAU,MAAM,MAAM,SAASI,CAAE,GAAI,CACvC,QAAS,CAAE,OAAQ,kBAAmB,EACtC,OAAQT,EAAW,MACvB,CAAC,EACD,GAAI,CAACK,EAAQ,GAAI,OACjB,IAAMC,EAAO,MAAMD,EAAQ,KAAK,EAChC,GAAIC,EAAK,SAAU,CACf,MAAMoB,EAASpB,EAAK,SAAU,CAAE,QAASA,EAAK,eAAgB,CAAC,EAC/D,MACJ,CACAnB,EAAS0B,IAAS,CACd,GAAGA,EACH,WAAYP,EAAK,WACjB,aAAcA,EAAK,SAAW,CAAC,GAAG,IAAKJ,GAAWA,EAAE,UAAU,EAC9D,OAAQI,EAAK,QAAUO,EAAK,OAC5B,SAAUP,EAAK,UAAYO,EAAK,SAChC,SAAUP,EAAK,UAAYO,EAAK,QACpC,EAAE,CACN,EAAG,CAACa,CAAQ,CAAC,EAEbI,GAAU,IAAM,CACZ,IAAMC,EAAY,IAAM,CACpB1C,EAAc,SAAS,MAAM,EAC7B,IAAMW,EAAa,IAAI,gBACvBX,EAAc,QAAUW,EAExB,IAAMS,EAAK,OAAO,SAAS,SAAW,OAAO,SAAS,OACtDD,EAAUC,EAAIT,CAAU,EAAE,MAAMgC,GAAO,CAC/BA,EAAI,OAAS,cAAc,QAAQ,MAAM,2BAA4BA,CAAG,CAChF,CAAC,CACL,EACA,cAAO,iBAAiB,WAAYD,CAAS,EACtC,IAAM,OAAO,oBAAoB,WAAYA,CAAS,CACjE,EAAG,CAACvB,CAAS,CAAC,EAEd,IAAIyB,EAEJ,GAAI/C,EAAM,aACN+C,EAAU/C,EAAM,UACVzB,EAACyB,EAAM,UAAN,CAAiB,GAAGA,EAAM,aAAc,EACzCzB,EAAC,MAAI,SAAAyB,EAAM,aAAa,WAAW,MACtC,CACH,IAAIgD,EACAzE,EAACY,EAAA,CAAiB,MAAO,CAAE,WAAYa,EAAM,WAAY,OAAQA,EAAM,MAAO,EAC1E,SAAAzB,EAACyB,EAAM,KAAN,CAAW,KAAMA,EAAM,WAAY,OAAQA,EAAM,OAAQ,IAAKA,EAAM,SAAU,EACnF,EAGJ,QAAS,EAAIA,EAAM,QAAQ,OAAS,EAAG,GAAK,EAAG,IAAK,CAChD,IAAMiD,EAASjD,EAAM,QAAQ,CAAC,EACxBkD,EAAalD,EAAM,YAAY,CAAC,EACtCgD,EACIzE,EAACY,EAAA,CAAiB,MAAO,CAAE,WAAY+D,EAAY,OAAQlD,EAAM,MAAO,EACpE,SAAAzB,EAAC0E,EAAA,CAAO,KAAMC,EAAY,OAAQlD,EAAM,OAAS,SAAAgD,EAAK,EAC1D,CAER,CAEAD,EACIxE,EAAC4E,EAAA,CAAwC,UAAWnD,EAAM,UACrD,SAAAgD,GADoBhD,EAAM,QAE/B,CAER,CAEA,OACIxB,GAAC4E,EAAA,CAAgB,MAAO,CACpB,SAAUpD,EAAM,SAChB,SAAUA,EAAM,SAChB,YAAAD,CACJ,EACI,UAAAxB,EAAC8E,EAAA,CAAS,SAAUrD,EAAM,SAAU,SAAUA,EAAM,SAAU,EAC9DzB,EAACK,EAAA,CAAc,MAAO,CAAE,GAAGoB,EAAO,aAAAK,GAAc,SAAAmC,EAAU,WAAAG,GAAY,cAAAnC,EAAc,EAC/E,SAAAuC,EACL,GACJ,CAER",
|
|
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", "DEFAULT_VIEWPORT", "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", "
|
|
3
|
+
"sources": ["../../src/runtime/router-provider.tsx", "../../src/runtime/head.tsx", "../../src/runtime/context.tsx", "../../src/runtime/error-boundary.tsx", "../../src/runtime/url.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\";\n\nconst DEFAULT_VIEWPORT: Viewport = { width: 'device-width', initialScale: 1 }\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 { resolveTo } from \"./url\";\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 const resolved = resolveTo(href)\n if (resolved.kind === 'external') return\n\n const key = resolved.href\n if (prefetchCacheRef.current.has(key)) return\n const matched = matchClientRoute(resolved.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${key}`, { 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(key)\n }, 3000)\n promise.finally(() => clearTimeout(expireTimer))\n\n prefetchCacheRef.current.set(key, { 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 ?? DEFAULT_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 const resolved = resolveTo(to)\n if (resolved.kind === 'external') {\n window.location.href = resolved.url.href\n return\n }\n const href = resolved.href\n\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, '', href)\n await loadRoute(href, 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", "export type ResolvedTo =\n | { kind: 'internal'; pathname: string; href: string }\n | { kind: 'external'; url: URL }\n\nexport function resolveTo(to: string): ResolvedTo {\n const base = new URL(window.location.href)\n if (!base.pathname.endsWith('/')) base.pathname += '/'\n\n const url = new URL(to, base)\n\n if (url.origin !== window.location.origin) {\n return { kind: 'external', url }\n }\n\n const pathname = url.pathname.length > 1\n ? url.pathname.replace(/\\/$/, '')\n : url.pathname\n\n return {\n kind: 'internal',\n pathname,\n href: pathname + url.search + url.hash,\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
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", "resolveTo", "to", "base", "url", "pathname", "jsx", "jsxs", "DEFAULT_VIEWPORT", "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", "resolved", "resolveTo", "key", "matched", "matchClientRoute", "controller", "promise", "l", "pageMod", "layoutMods", "dataRes", "data", "expireTimer", "loadRoute", "to", "pathname", "ErrorPage", "loadErrorPage", "getDefaultErrorPage", "prev", "cached", "prefetched", "pm", "lm", "ct", "errorBody", "headers", "value", "m", "hash", "scrollBehavior", "navigate", "options", "run", "revalidate", "useEffect", "handlePop", "err", "content", "tree", "i", "Layout", "layoutData", "DevixErrorBoundary", "PageMetaContext", "HeadSlot"]
|
|
7
7
|
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
function r(a){let e=new URL(window.location.href);e.pathname.endsWith("/")||(e.pathname+="/");let n=new URL(a,e);if(n.origin!==window.location.origin)return{kind:"external",url:n};let t=n.pathname.length>1?n.pathname.replace(/\/$/,""):n.pathname;return{kind:"internal",pathname:t,href:t+n.search+n.hash}}export{r as resolveTo};
|
|
2
|
+
//# sourceMappingURL=url.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/runtime/url.ts"],
|
|
4
|
+
"sourcesContent": ["export type ResolvedTo =\n | { kind: 'internal'; pathname: string; href: string }\n | { kind: 'external'; url: URL }\n\nexport function resolveTo(to: string): ResolvedTo {\n const base = new URL(window.location.href)\n if (!base.pathname.endsWith('/')) base.pathname += '/'\n\n const url = new URL(to, base)\n\n if (url.origin !== window.location.origin) {\n return { kind: 'external', url }\n }\n\n const pathname = url.pathname.length > 1\n ? url.pathname.replace(/\\/$/, '')\n : url.pathname\n\n return {\n kind: 'internal',\n pathname,\n href: pathname + url.search + url.hash,\n }\n}\n"],
|
|
5
|
+
"mappings": "AAIO,SAASA,EAAUC,EAAwB,CAC9C,IAAMC,EAAO,IAAI,IAAI,OAAO,SAAS,IAAI,EACpCA,EAAK,SAAS,SAAS,GAAG,IAAGA,EAAK,UAAY,KAEnD,IAAMC,EAAM,IAAI,IAAIF,EAAIC,CAAI,EAE5B,GAAIC,EAAI,SAAW,OAAO,SAAS,OAC/B,MAAO,CAAE,KAAM,WAAY,IAAAA,CAAI,EAGnC,IAAMC,EAAWD,EAAI,SAAS,OAAS,EACjCA,EAAI,SAAS,QAAQ,MAAO,EAAE,EAC9BA,EAAI,SAEV,MAAO,CACH,KAAM,WACN,SAAAC,EACA,KAAMA,EAAWD,EAAI,OAASA,EAAI,IACtC,CACJ",
|
|
6
|
+
"names": ["resolveTo", "to", "base", "url", "pathname"]
|
|
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
|
+
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.4",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
|