@modastar/z-router 0.0.7 → 0.0.8

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/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";var Y=Object.defineProperty;var Dt=Object.getOwnPropertyDescriptor;var Et=Object.getOwnPropertyNames;var Ft=Object.prototype.hasOwnProperty;var It=(t,n)=>{for(var o in n)Y(t,o,{get:n[o],enumerable:!0})},Nt=(t,n,o,s)=>{if(n&&typeof n=="object"||typeof n=="function")for(let e of Et(n))!Ft.call(t,e)&&e!==o&&Y(t,e,{get:()=>n[e],enumerable:!(s=Dt(n,e))||s.enumerable});return t};var $t=t=>Nt(Y({},"__esModule",{value:!0}),t);var qt={};It(qt,{DefaultTransitionDuration:()=>D,Link:()=>Bt,LocationContext:()=>N,LocationProvider:()=>M,Outlet:()=>et,RootRouteContext:()=>W,RouterContext:()=>I,RouterProvider:()=>Xt,Stack:()=>Ut,buildPathnameFromMatches:()=>Ot,createRouterOptions:()=>Wt,matchPattern:()=>St,matchRoute:()=>rt,parseLocation:()=>it,parseRoute:()=>st,redirect:()=>Gt,useLocation:()=>$,useRootRoute:()=>X,useRoute:()=>tt,useRouter:()=>b});module.exports=$t(qt);var ct=require("react");var ut=require("react"),I=(0,ut.createContext)(null);var b=()=>{let t=(0,ct.useContext)(I);if(t===null)throw new Error("useRouter must be used within a Stack");return t};var pt=require("react/jsx-runtime"),Bt=({to:t,replace:n,transition:o,duration:s,onFinish:e,...r})=>{let i=b();return(0,pt.jsx)("a",{...r,href:t,onClick:u=>{u.preventDefault(),i.navigate({to:t,replace:n,transition:o,duration:s,onFinish:e})}})};var mt=require("react"),N=(0,mt.createContext)(null);var U=require("react"),dt=require("react/jsx-runtime"),M=({location:t,...n})=>{let o=b(),s=(0,U.useCallback)(i=>t.state[i],[t]),e=(0,U.useCallback)((i,u)=>{o.setLocationState(t.index,{...t.state,[i]:u})},[o,t]),r=(0,U.useCallback)(i=>{delete t.state[i],o.setLocationState(t.index,t.state)},[o,t]);return(0,dt.jsx)(N.Provider,{value:{...t,canGoBack:t.index>0,canGoForward:t.index<o.history.length-1,getState:s,setState:e,deleteState:r},...n})};var ft=require("react"),q=(0,ft.createContext)(0);var lt=require("react"),Rt=()=>(0,lt.useContext)(q);var ht=require("react"),A=(0,ht.createContext)(null);var gt=require("react"),z=()=>{let t=(0,gt.useContext)(A);if(t===null)throw new Error("useRouteMatch must be used within a RouteMatchProvider");return t};var yt=require("react/jsx-runtime"),xt=({depth:t,...n})=>(0,yt.jsx)(q.Provider,{value:t,...n});var vt=require("react");var $=()=>{let t=(0,vt.useContext)(N);if(t===null)throw new Error("useLocation must be used within a LocationProvider");return t};var wt=require("react"),B=(0,wt.createContext)(null);var Pt=require("react"),tt=()=>{let t=(0,Pt.useContext)(B);if(t===null)throw new Error("useRoute must be used within a RouteProvider");return t};var _=require("react");var G=require("react/jsx-runtime"),K=({depth:t=0})=>{let n=b(),o=$(),s=z(),e=tt(),r=`_Z.${e.id}.pending`,[i,u]=(0,_.useState)(!!e?.beforeLoad&&e?.getState(r)!==!1);if((0,_.useEffect)(()=>{!e||t>=s.matches.length||i&&e?.beforeLoad&&(e.setState(r,!0),e.beforeLoad({location:o}).catch(({cause:p})=>{"to"in p&&n.navigate(p)}).finally(()=>{e.setState(r,!1),u(!1)}))},[]),!e)return null;if(t>=s.matches.length){let p=e.notFoundComponent;return(0,G.jsx)(p,{})}if(i){let p=e.pendingComponent;return(0,G.jsx)(p,{})}let d=e.component;return d?(0,G.jsx)(d,{}):(0,G.jsx)(et,{})};var bt=require("react");var Ct=require("react"),W=(0,Ct.createContext)(null);var X=()=>{let t=(0,bt.useContext)(W);if(t===null)throw new Error("useRootRoute must be used within a RootRouteProvider");return t};var ot=require("react"),nt=require("react/jsx-runtime"),Z=({route:t,...n})=>{if(!t)return(0,nt.jsx)(B.Provider,{value:null,...n});let o=X(),s=(0,ot.useCallback)(r=>o.getRouteState(t.id,r),[o.getRouteState]),e=(0,ot.useCallback)((r,i)=>{o.setRouteState(t.id,r,i)},[o.setRouteState]);return(0,nt.jsx)(B.Provider,{value:{...t,getState:s,setState:e},...n})};var H=require("react/jsx-runtime"),et=()=>{let t=z(),n=Rt()+1;return(0,H.jsx)(xt,{depth:n,children:(0,H.jsx)(Z,{route:t.matches.at(n),children:(0,H.jsx)(K,{depth:n})})})};var g=require("react");var Lt={defaultTransitionDuration:300};var D=300,Gt=t=>new Error("",{cause:t}),St=(t,n)=>{try{let o,s;if(n.startsWith("http://")||n.startsWith("https://")){let c=new URL(n);o=c.pathname,s=c.searchParams}else{let[c,w]=n.split("?");if(!c)return null;o=c,s=new URLSearchParams(w||"")}let e=o.replaceAll(/^\/|\/$/g,""),r=t.replaceAll(/^\/|\/$/g,""),i=e.split("/"),u=r.split("/");if(i.length!==u.length)return null;let d={};for(let c=0;c<u.length;c++){let w=u[c],v=i[c];if(w.startsWith(":")){let E=w.slice(1);d[E]=decodeURIComponent(v)}else if(w!==v)return null}let p=Object.fromEntries(s.entries());return{params:d,query:p}}catch{return null}},rt=(t,n)=>{let o=(s,{children:e})=>{if(e&&e.length>0){for(let i of e){let u=o([...s,i],i);if(u)return u}return null}let r=St(Ot(s),n);return r?{matches:s,...r}:null};return o([t],t)||{matches:[],params:{},query:{}}},Ot=t=>{let n=[];for(let o of t)o.pathname!==void 0&&n.push(o.pathname.replaceAll(/^\/|\/$/g,""));return"/"+n.join("/")},it=t=>({index:0,state:{},pathname:t.pathname,search:Object.fromEntries(new URLSearchParams(t.search))}),Wt=t=>({...Lt,...t}),st=t=>{let n=(o,s)=>{let e=o.name??(o.pathname?`${s}/${o.pathname.replaceAll(/^\/|\/$/g,"")}`:s);return{...o,id:e,children:o.children?.map(i=>n(i,e))}};return n(t,"")};var at=require("react/jsx-runtime"),Xt=({options:t,...n})=>{let[o,s]=(0,g.useState)([it(window.location)]),[e,r]=(0,g.useState)(0),i=o.at(e),[u,d]=(0,g.useState)(!1),[p,c]=(0,g.useState)(D),[w,v]=(0,g.useState)();(0,g.useEffect)(()=>{window.history.replaceState({index:0},"");let m=({state:l})=>{r(l?.index??0)};return window.addEventListener("popstate",m),()=>{window.removeEventListener("popstate",m)}},[r]);let E=(0,g.useCallback)((m,l)=>{s(y=>y.map(f=>f.index===m?{...f,state:l}:f)),m===e&&window.history.replaceState({index:m,...l},"",i.pathname)},[e]),P=(0,g.useCallback)(({to:m,replace:l,transition:y,duration:f,updateHistory:h=!0,onFinish:k,...V})=>{if(u)return;let R=l?e:e+1,O;if(m.startsWith(".")){let L=i.pathname.split("/").filter(C=>C.length>0),Mt=m.split("/").filter(C=>C.length>0);for(let C of Mt)if(C.startsWith(".")){if(C===".")continue;if(C==="..")L.pop();else throw new Error(`Invalid relative path segment: ${C} in ${m}`)}else C.length>0&&L.push(C);O="/"+L.join("/")}else O=m;if(s(L=>[...R===o.length?o:L.slice(0,R),{index:R,search:{},state:{},pathname:O,...V}]),!l&&e>=0&&(y??t.defaultUseTransition?.(i,o.at(R)))){let L=f??D;d(!0),c(L),v(R),setTimeout(()=>{d(!1),v(void 0),r(R),k?.(),h&&window.history.pushState({index:R},"",m)},L)}else l?h&&window.history.replaceState({index:R},"",m):(r(R),h&&window.history.pushState({index:R},"",m))},[e,o,u,t]),F=(0,g.useCallback)(({transition:m,duration:l,onFinish:y,depth:f}={})=>{if(e===0||u)return;let h=e-(f??1);if(e>0&&(m??t.defaultUseTransition?.(i,o.at(h)))){let k=l??D;d(!0),c(k),v(h),setTimeout(()=>{d(!1),v(void 0),r(h),y?.(),window.history.back()},k)}else r(h),y?.(),window.history.back()},[e,o,u,t]),T=(0,g.useCallback)(({transition:m,duration:l,onFinish:y}={})=>{if(e+1>=o.length||u)return;let f=e+1;if(f<o.length&&(m??t.defaultUseTransition?.(i,o.at(f)))){let h=l??D;d(!0),c(h),v(f),setTimeout(()=>{d(!1),v(void 0),r(f),y?.(),window.history.forward()},h)}else r(f),y?.(),window.history.forward()},[e,o,u,t]);return(0,at.jsx)(I.Provider,{value:{options:t,history:o,location:i,canGoBack:e>0,canGoForward:e<o.length-1,isTransitioning:u,transitionDuration:p,transitioningToIndex:w,navigate:P,back:F,forward:T,setLocationState:E},children:(0,at.jsx)(M,{location:i,...n})})};var S=require("react");var J=require("react/jsx-runtime"),Q=()=>{let t=X(),n=$(),o=rt(t,n.pathname);return(0,J.jsx)(A.Provider,{value:o,children:(0,J.jsx)(Z,{route:t,children:(0,J.jsx)(K,{})})})};var j=require("react"),kt=require("react/jsx-runtime"),Tt=({rootRoute:t,...n})=>{let o=st(t),[s,e]=(0,j.useState)({}),r=(0,j.useCallback)((u,d)=>s[u]?.[d],[s]),i=(0,j.useCallback)((u,d,p)=>{e(c=>({...c,[u]:{...c[u],[d]:p}}))},[]);return(0,kt.jsx)(W.Provider,{value:{...o,getRouteState:r,setRouteState:i},...n})};var x=require("react/jsx-runtime"),jt=()=>{let{history:t,location:n,canGoBack:o,canGoForward:s,isTransitioning:e,transitioningToIndex:r,transitionDuration:i,back:u,forward:d}=b(),p=n?.index,[c,w]=(0,S.useState)(!1),[v,E]=(0,S.useState)(0),[P,F]=(0,S.useState)(0),[T,m]=(0,S.useState)(!1),[l,y]=(0,S.useState)(!1);if((0,S.useEffect)(()=>{!e||r===null||(y(!0),setTimeout(()=>{y(!1)},i))},[e,r]),p===void 0)return;let f=()=>{w(!1),F(0),m(!1)},h=R=>{e||!s&&!o||(w(!0),E(R.touches[0].clientX))},k=R=>{if(!c)return;let O=R.touches[0].clientX-v;if(O>0&&p===0||O<0&&p+1===t.length){F(0);return}F(Math.min(window.innerWidth,O))},V=()=>{c&&(P>window.innerWidth*.3&&o?u({onFinish:f}):P<-window.innerWidth*.3&&s?d({onFinish:f}):(m(!0),setTimeout(f,i)))};return(0,x.jsxs)("div",{style:{position:"relative",inset:0,height:"100%",width:"100%",overflow:"hidden"},children:[p>=1&&(c&&P>0||e&&r!==void 0&&r<p)&&(0,x.jsx)("div",{style:{position:"absolute",inset:0,zIndex:-10},children:(0,x.jsx)(M,{location:t.at(p-1),children:(0,x.jsx)(Q,{},p-1)})}),(0,x.jsx)("div",{style:{background:"white",position:"absolute",inset:0,overflow:"hidden",transform:e&&r!==void 0&&r<p?"translateX(100%)":c&&P>0&&!T?`translateX(${P}px)`:"translateX(0px)",transition:T||e&&r!==void 0&&r<p?`transform ${i}ms ease-out`:"",boxShadow:c&&P>0?"-4px 0 8px rgba(0,0,0,0.1)":"none"},onTouchStart:h,onTouchMove:k,onTouchEnd:V,children:(0,x.jsx)(Q,{})},p),(c&&P<0||e&&r!==void 0&&p<r)&&(0,x.jsx)("div",{style:{background:"white",position:"absolute",inset:0,zIndex:10,overflow:"hidden",transition:"transform ease-in",transform:l?"translateX(0px)":c&&!T?`translateX(${window.innerWidth+P}px)`:"translateX(100%)",transitionDuration:e||T?`${i}ms`:"0ms"},children:(0,x.jsx)(M,{location:c?t.at(p+1):t.at(r),children:(0,x.jsx)(Q,{},r)})},r)]})},Ut=({rootRoute:t})=>(0,x.jsx)(Tt,{rootRoute:t,children:(0,x.jsx)(jt,{})});0&&(module.exports={DefaultTransitionDuration,Link,LocationContext,LocationProvider,Outlet,RootRouteContext,RouterContext,RouterProvider,Stack,buildPathnameFromMatches,createRouterOptions,matchPattern,matchRoute,parseLocation,parseRoute,redirect,useLocation,useRootRoute,useRoute,useRouter});
1
+ "use strict";var tt=Object.defineProperty;var Ft=Object.getOwnPropertyDescriptor;var Nt=Object.getOwnPropertyNames;var $t=Object.prototype.hasOwnProperty;var Bt=(t,n)=>{for(var o in n)tt(t,o,{get:n[o],enumerable:!0})},Gt=(t,n,o,s)=>{if(n&&typeof n=="object"||typeof n=="function")for(let e of Nt(n))!$t.call(t,e)&&e!==o&&tt(t,e,{get:()=>n[e],enumerable:!(s=Ft(n,e))||s.enumerable});return t};var It=t=>Gt(tt({},"__esModule",{value:!0}),t);var zt={};Bt(zt,{DefaultTransitionDuration:()=>Wt,Link:()=>Xt,LocationContext:()=>$,LocationProvider:()=>E,Outlet:()=>ot,RootRouteContext:()=>X,RouterContext:()=>N,RouterProvider:()=>qt,Stack:()=>Ht,buildPathnameFromMatches:()=>kt,createRouterOptions:()=>Ut,matchPattern:()=>Tt,matchRoute:()=>it,parseLocation:()=>st,parseRoute:()=>at,redirect:()=>jt,useLocation:()=>B,useRootRoute:()=>W,useRoute:()=>et,useRouter:()=>w});module.exports=It(zt);var mt=require("react");var pt=require("react"),N=(0,pt.createContext)(null);var w=()=>{let t=(0,mt.useContext)(N);if(t===null)throw new Error("useRouter must be used within a Stack");return t};var dt=require("react/jsx-runtime"),Xt=({to:t,replace:n,transition:o,duration:s,onFinish:e,...r})=>{let i=w();return(0,dt.jsx)("a",{...r,href:t,onClick:u=>{u.preventDefault(),i.navigate({to:t,replace:n,transition:o,duration:s,onFinish:e})}})};var lt=require("react"),$=(0,lt.createContext)(null);var q=require("react"),ft=require("react/jsx-runtime"),E=({location:t,...n})=>{let o=w(),s=(0,q.useCallback)(i=>t.state[i],[t]),e=(0,q.useCallback)((i,u)=>{o.setLocationState(t.index,{...t.state,[i]:u})},[o,t]),r=(0,q.useCallback)(i=>{delete t.state[i],o.setLocationState(t.index,t.state)},[o,t]);return(0,ft.jsx)($.Provider,{value:{...t,canGoBack:t.index>0,canGoForward:t.index<o.history.length-1,getState:s,setState:e,deleteState:r},...n})};var Rt=require("react"),A=(0,Rt.createContext)(0);var ht=require("react"),gt=()=>(0,ht.useContext)(A);var xt=require("react"),H=(0,xt.createContext)(null);var yt=require("react"),z=()=>{let t=(0,yt.useContext)(H);if(t===null)throw new Error("useRouteMatch must be used within a RouteMatchProvider");return t};var Pt=require("react/jsx-runtime"),vt=({depth:t,...n})=>(0,Pt.jsx)(A.Provider,{value:t,...n});var Ct=require("react");var B=()=>{let t=(0,Ct.useContext)($);if(t===null)throw new Error("useLocation must be used within a LocationProvider");return t};var Lt=require("react"),G=(0,Lt.createContext)(null);var wt=require("react"),et=()=>{let t=(0,wt.useContext)(G);if(t===null)throw new Error("useRoute must be used within a RouteProvider");return t};var _=require("react");var I=require("react/jsx-runtime"),K=({depth:t=0})=>{let n=w(),o=B(),s=z(),e=et(),r=`_Z.${e.id}.pending`,[i,u]=(0,_.useState)(!!e?.beforeLoad&&e?.getState(r)!==!1);if((0,_.useEffect)(()=>{!e||t>=s.matches.length||i&&e?.beforeLoad&&(e.setState(r,!0),e.beforeLoad({location:o}).catch(({cause:c})=>{"to"in c&&n.navigate(c)}).finally(()=>{e.setState(r,!1),u(!1)}))},[]),!e)return null;if(t>=s.matches.length){let c=e.notFoundComponent;return(0,I.jsx)(c,{})}if(i){let c=e.pendingComponent;return(0,I.jsx)(c,{})}let l=e.component;return l?(0,I.jsx)(l,{}):(0,I.jsx)(ot,{})};var St=require("react");var bt=require("react"),X=(0,bt.createContext)(null);var W=()=>{let t=(0,St.useContext)(X);if(t===null)throw new Error("useRootRoute must be used within a RootRouteProvider");return t};var nt=require("react"),rt=require("react/jsx-runtime"),Z=({route:t,...n})=>{if(!t)return(0,rt.jsx)(G.Provider,{value:null,...n});let o=W(),s=(0,nt.useCallback)(r=>o.getRouteState(t.id,r),[o.getRouteState]),e=(0,nt.useCallback)((r,i)=>{o.setRouteState(t.id,r,i)},[o.setRouteState]);return(0,rt.jsx)(G.Provider,{value:{...t,getState:s,setState:e},...n})};var J=require("react/jsx-runtime"),ot=()=>{let t=z(),n=gt()+1;return(0,J.jsx)(vt,{depth:n,children:(0,J.jsx)(Z,{route:t.matches.at(n),children:(0,J.jsx)(K,{depth:n})})})};var g=require("react");var Ot={defaultTransitionDuration:300};var Wt=300,jt=t=>new Error("",{cause:t}),Tt=(t,n)=>{try{let o,s;if(n.startsWith("http://")||n.startsWith("https://")){let m=new URL(n);o=m.pathname,s=m.searchParams}else{let[m,f]=n.split("?");if(!m)return null;o=m,s=new URLSearchParams(f||"")}let e=o.replaceAll(/^\/|\/$/g,""),r=t.replaceAll(/^\/|\/$/g,""),i=e.split("/"),u=r.split("/");if(i.length!==u.length)return null;let l={};for(let m=0;m<u.length;m++){let f=u[m],b=i[m];if(f.startsWith(":")){let T=f.slice(1);l[T]=decodeURIComponent(b)}else if(f!==b)return null}let c=Object.fromEntries(s.entries());return{params:l,query:c}}catch{return null}},it=(t,n)=>{let o=(s,{children:e})=>{if(e&&e.length>0){for(let i of e){let u=o([...s,i],i);if(u)return u}return null}let r=Tt(kt(s),n);return r?{matches:s,...r}:null};return o([t],t)||{matches:[],params:{},query:{}}},kt=t=>{let n=[];for(let o of t)o.pathname!==void 0&&n.push(o.pathname.replaceAll(/^\/|\/$/g,""));return"/"+n.join("/")},st=t=>({index:0,state:{index:0},pathname:t.pathname,search:Object.fromEntries(new URLSearchParams(t.search))}),Ut=t=>({...Ot,...t}),at=t=>{let n=(o,s)=>{let e=o.name??(o.pathname?`${s}/${o.pathname.replaceAll(/^\/|\/$/g,"")}`:s);return{...o,id:e,children:o.children?.map(i=>n(i,e))}};return n(t,"")};var ut=require("react/jsx-runtime"),qt=({options:t,...n})=>{let[o,s]=(0,g.useState)([st(window.location)]),[e,r]=(0,g.useState)(0),i=o.at(e),[u,l]=(0,g.useState)(!1),[c,m]=(0,g.useState)(0),[f,b]=(0,g.useState)();(0,g.useEffect)(()=>{window.history.replaceState(o[0].state,"",o[0].pathname);let p=({state:d})=>{r(d?.index??0)};return addEventListener("popstate",p),()=>{removeEventListener("popstate",p)}},[]);let T=(p,d=t.defaultTransitionDuration,y)=>{l(!0),m(d),b(p),setTimeout(()=>{l(!1),b(void 0),r(p.index),y?.()},d)},Y=(0,g.useCallback)((p,d)=>{s(y=>y.map(h=>h.index===p?{...h,state:d}:h)),p===e&&window.history.replaceState(d,"",i.pathname)},[e]),P=(0,g.useCallback)(({to:p,replace:d,transition:y,duration:h,onFinish:C,...v})=>{if(u)return;let R=d?e:e+1,L;if(p.startsWith("/"))L=p;else{let S=i.pathname.split("/").filter(M=>M.length>0),Dt=p.split("/").filter(M=>M.length>0);for(let M of Dt)M!=="."&&(M===".."?S.pop():S.push(M));L="/"+S.join("/")}let k={index:R},U={index:R,search:{},state:k,pathname:L,...v},ct=()=>{d?(s(S=>[...S.slice(0,R),U,...S.slice(R+1)]),window.history.replaceState(k,"",L)):(s(S=>[...S.slice(0,R),U]),r(R),window.history.pushState(k,"",L)),C?.()};y??t.defaultUseTransition?.(i,U)?T(U,h,ct):ct()},[e,o,u,t]),D=(0,g.useCallback)(({transition:p,duration:d,onFinish:y,depth:h}={})=>{if(e===0||u)return;let C=h??1,v=o.at(e-C),R=()=>{window.history.go(-C),y?.()};v&&(p??t.defaultUseTransition?.(i,v))?T(v,d,R):R()},[e,o,u,t]),F=(0,g.useCallback)(({transition:p,duration:d,depth:y,onFinish:h}={})=>{if(e+1>=o.length||u)return;let C=y??1,v=o.at(e+C),R=()=>{window.history.go(C),h?.()};v&&(p??t.defaultUseTransition?.(i,v))?T(v,d,R):R()},[e,o,u,t]);return(0,ut.jsx)(N.Provider,{value:{options:t,history:o,location:i,canGoBack:e>0,canGoForward:e<o.length-1,isTransitioning:u,transitionDuration:c,transitioningToLocation:f,navigate:P,back:D,forward:F,setLocationState:Y},children:(0,ut.jsx)(E,{location:i,...n})})};var O=require("react");var Q=require("react/jsx-runtime"),V=()=>{let t=W(),n=B(),o=it(t,n.pathname);return(0,Q.jsx)(H.Provider,{value:o,children:(0,Q.jsx)(Z,{route:t,children:(0,Q.jsx)(K,{})})})};var j=require("react"),Et=require("react/jsx-runtime"),Mt=({rootRoute:t,...n})=>{let o=at(t),[s,e]=(0,j.useState)({}),r=(0,j.useCallback)((u,l)=>s[u]?.[l],[s]),i=(0,j.useCallback)((u,l,c)=>{e(m=>({...m,[u]:{...m[u],[l]:c}}))},[]);return(0,Et.jsx)(X.Provider,{value:{...o,getRouteState:r,setRouteState:i},...n})};var x=require("react/jsx-runtime"),At=()=>{let{history:t,location:n,canGoBack:o,canGoForward:s,isTransitioning:e,transitioningToLocation:r,transitionDuration:i,back:u,forward:l}=w(),c=n?.index,m=r?.index,[f,b]=(0,O.useState)(!1),[T,Y]=(0,O.useState)(0),[P,D]=(0,O.useState)(0),[F,p]=(0,O.useState)(!1),[d,y]=(0,O.useState)(!1);if((0,O.useEffect)(()=>{!e||!r||(y(!0),setTimeout(()=>{y(!1)},i))},[e,r]),c===void 0)return;let h=()=>{b(!1),D(0),p(!1)},C=L=>{e||!s&&!o||(b(!0),Y(L.touches[0].clientX))},v=L=>{if(!f)return;let k=L.touches[0].clientX-T;if(k>0&&c===0||k<0&&c+1===t.length){D(0);return}D(Math.min(innerWidth,k))},R=()=>{f&&(P>innerWidth*.3&&o?u({onFinish:h}):P<-innerWidth*.3&&s?l({onFinish:h}):(p(!0),setTimeout(h,i)))};return(0,x.jsxs)("div",{style:{position:"relative",inset:0,height:"100%",width:"100%",overflow:"hidden"},children:[c>=1&&(f&&P>0||e&&r&&r.index<c)&&(0,x.jsx)("div",{style:{position:"absolute",inset:0,zIndex:-10},children:(0,x.jsx)(E,{location:t.at(c-1),children:(0,x.jsx)(V,{},c-1)})}),(0,x.jsx)("div",{style:{background:"white",position:"absolute",inset:0,overflow:"hidden",transform:e&&r&&r.index<c?"translateX(100%)":f&&P>0&&!F?`translateX(${P}px)`:"translateX(0px)",transition:F||e&&r&&r.index<c?`transform ${i}ms ease-out`:"",boxShadow:f&&P>0?"-4px 0 8px rgba(0,0,0,0.1)":"none"},onTouchStart:C,onTouchMove:v,onTouchEnd:R,children:(0,x.jsx)(V,{})},c),(f&&P<0||e&&r&&c<=r.index)&&(0,x.jsx)("div",{style:{background:"white",position:"absolute",inset:0,zIndex:10,overflow:"hidden",transition:"transform ease-in",transform:d?"translateX(0px)":e?"translateX(100%)":`translateX(${innerWidth+P}px)`,transitionDuration:e||F?`${i}ms`:"0ms"},children:(0,x.jsx)(E,{location:e?r:t.at(c+1),children:(0,x.jsx)(V,{},m)})})]})},Ht=({rootRoute:t})=>(0,x.jsx)(Mt,{rootRoute:t,children:(0,x.jsx)(At,{})});0&&(module.exports={DefaultTransitionDuration,Link,LocationContext,LocationProvider,Outlet,RootRouteContext,RouterContext,RouterProvider,Stack,buildPathnameFromMatches,createRouterOptions,matchPattern,matchRoute,parseLocation,parseRoute,redirect,useLocation,useRootRoute,useRoute,useRouter});
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/hooks/useRouter.ts","../src/context/router-context.ts","../src/components/link.tsx","../src/context/location-context.ts","../src/components/location-provider.tsx","../src/context/outlet-context.ts","../src/hooks/useOutlet.ts","../src/context/route-match-context.ts","../src/hooks/useRouteMatch.ts","../src/components/outlet-provider.tsx","../src/hooks/useLocation.ts","../src/context/route-context.ts","../src/hooks/useRoute.ts","../src/components/route-component.tsx","../src/hooks/useRootRoute.ts","../src/context/root-route-context.ts","../src/components/route-provider.tsx","../src/components/outlet.tsx","../src/components/router-provider.tsx","../src/constants.ts","../src/utils.ts","../src/components/stack.tsx","../src/components/page-renderer.tsx","../src/components/root-route-provider.tsx"],"sourcesContent":["export * from \"./components/index.js\";\nexport * from \"./context/index.js\";\nexport * from \"./hooks/index.js\";\nexport * from \"./types.d.js\";\nexport * from \"./utils.js\";\n","import { useContext } from \"react\";\n\nimport { RouterContext } from \"@/context/router-context.js\";\n\nexport const useRouter = () => {\n const router = useContext(RouterContext);\n if (router === null) {\n throw new Error(\"useRouter must be used within a Stack\");\n }\n return router;\n};\n","import { createContext } from \"react\";\n\nimport type {\n BackOptions,\n ForwardOptions,\n Location,\n NavigateOptions,\n RouterOptions,\n} from \"@/types.js\";\n\nexport interface RouterContextType {\n // Router Config\n options: RouterOptions;\n\n // Navigation State\n history: Location[];\n location?: Location;\n canGoBack: boolean;\n canGoForward: boolean;\n\n // Transition state\n isTransitioning: boolean;\n transitionDuration: number;\n transitioningToIndex?: number;\n\n // Actions\n navigate: (options: NavigateOptions) => void;\n back: (options?: BackOptions) => void;\n forward: (options?: ForwardOptions) => void;\n\n // Low-level state action\n setLocationState: (index: number, state: Record<string, any>) => void;\n}\n\nexport const RouterContext = createContext<RouterContextType | null>(null);\n","import { useRouter } from \"@/hooks/useRouter.js\";\nimport type { NavigateOptions } from \"@/types.js\";\n\nexport type LinkProps = React.ComponentPropsWithoutRef<\"a\"> & NavigateOptions;\n\nexport const Link: React.FC<LinkProps> = ({\n to,\n replace,\n transition,\n duration,\n onFinish,\n ...props\n}) => {\n const router = useRouter();\n return (\n <a\n {...props}\n href={to}\n onClick={(e) => {\n e.preventDefault();\n router.navigate({ to, replace, transition, duration, onFinish });\n }}\n />\n );\n};\n","import { createContext } from \"react\";\n\nimport type { Location } from \"@/types.js\";\n\nexport interface LocationContextType extends Location {\n canGoBack: boolean;\n canGoForward: boolean;\n getState: (key: string) => any;\n setState: (key: string, value: any) => void;\n deleteState: (key: string) => void;\n}\n\nexport const LocationContext = createContext<LocationContextType | null>(null);\n","import { LocationContext } from \"@/context/location-context.js\";\nimport { useRouter } from \"@/hooks/useRouter.js\";\nimport type { Location } from \"@/types.js\";\nimport { useCallback } from \"react\";\n\nexport const LocationProvider = ({\n location,\n ...props\n}: {\n location: Location;\n children: React.ReactNode;\n}) => {\n const router = useRouter();\n const getState = useCallback(\n (key: string) => {\n return location.state[key];\n },\n [location]\n );\n const setState = useCallback(\n (key: string, value: any) => {\n router.setLocationState(location.index, {\n ...location.state,\n [key]: value,\n });\n },\n [router, location]\n );\n const deleteState = useCallback(\n (key: string) => {\n delete location.state[key];\n router.setLocationState(location.index, location.state);\n },\n [router, location]\n );\n return (\n <LocationContext.Provider\n value={{\n ...location,\n canGoBack: location.index > 0,\n canGoForward: location.index < router.history.length - 1,\n getState,\n setState,\n deleteState,\n }}\n {...props}\n />\n );\n};\n","import { createContext } from \"react\";\n\nexport const OutletContext = createContext<number>(0);\n","import { OutletContext } from \"@/context/outlet-context.js\";\nimport { useContext } from \"react\";\n\nexport const useOutlet = () => useContext(OutletContext);\n","import type { RouteMatch } from \"@/types.js\";\nimport { createContext } from \"react\";\n\nexport const RouteMatchContext = createContext<RouteMatch | null>(null);\n","import { RouteMatchContext } from \"@/context/route-match-context.js\";\nimport { useContext } from \"react\";\n\nexport const useRouteMatch = () => {\n const routeMatch = useContext(RouteMatchContext);\n if (routeMatch === null) {\n throw new Error(\"useRouteMatch must be used within a RouteMatchProvider\");\n }\n return routeMatch;\n};\n","import { OutletContext } from \"@/context/outlet-context.js\";\n\nexport const OutletProvider = ({\n depth,\n ...props\n}: {\n depth: number;\n children?: React.ReactNode;\n}) => <OutletContext.Provider value={depth} {...props} />;\n","import { useContext } from \"react\";\n\nimport { LocationContext } from \"@/context/location-context.js\";\n\nexport const useLocation = () => {\n const context = useContext(LocationContext);\n if (context === null) {\n throw new Error(\"useLocation must be used within a LocationProvider\");\n }\n return context;\n};\n","import type { ParsedRoute } from \"@/types.js\";\nimport { createContext } from \"react\";\n\nexport interface RouteContextType extends ParsedRoute {\n getState: (key: string) => any;\n setState: (key: string, value: any) => void;\n}\n\nexport const RouteContext = createContext<RouteContextType | null>(null);\n","import { RouteContext } from \"@/context/route-context.js\";\nimport { useContext } from \"react\";\n\nexport const useRoute = () => {\n const route = useContext(RouteContext);\n if (route === null) {\n throw new Error(\"useRoute must be used within a RouteProvider\");\n }\n return route;\n};\n","import { useLocation } from \"@/hooks/useLocation.js\";\nimport { useRoute } from \"@/hooks/useRoute.js\";\nimport { useRouteMatch } from \"@/hooks/useRouteMatch.js\";\nimport { useRouter } from \"@/hooks/useRouter.js\";\nimport { useEffect, useState } from \"react\";\nimport { Outlet } from \"./outlet.js\";\n\nexport const RouteComponent = ({ depth = 0 }: { depth?: number }) => {\n const router = useRouter();\n const location = useLocation();\n const routeMatch = useRouteMatch();\n const route = useRoute();\n\n const pendingStateKey = `_Z.${route.id}.pending`;\n\n const [pending, setPending] = useState(\n !!route?.beforeLoad && route?.getState(pendingStateKey) !== false\n );\n\n useEffect(() => {\n if (!route || depth >= routeMatch.matches.length) {\n return;\n }\n // TODO: push location still loading. Maybe store state in route () instead of location\n if (pending && route?.beforeLoad) {\n route.setState(pendingStateKey, true);\n route\n .beforeLoad({ location })\n .catch(({ cause }: Error) => {\n if (\"to\" in (cause as any)) {\n router.navigate(cause as any);\n }\n })\n .finally(() => {\n route.setState(pendingStateKey, false);\n setPending(false);\n });\n }\n }, []);\n\n if (!route) {\n return null;\n }\n\n if (depth >= routeMatch.matches.length) {\n const NotFoundComponent = route.notFoundComponent!;\n return <NotFoundComponent />;\n }\n\n if (pending) {\n const PendingComponent = route.pendingComponent!;\n return <PendingComponent />;\n }\n\n const Component = route.component;\n return Component ? <Component /> : <Outlet />;\n};\n","import { useContext } from \"react\";\n\nimport { RootRouteContext } from \"@/context/root-route-context.js\";\n\nexport const useRootRoute = () => {\n const route = useContext(RootRouteContext);\n if (route === null) {\n throw new Error(\"useRootRoute must be used within a RootRouteProvider\");\n }\n return route;\n};\n","import { createContext } from \"react\";\n\nimport type { ParsedRoute } from \"@/types.js\";\n\nexport interface RootRouteContextType extends ParsedRoute {\n getRouteState: (id: string, key: string) => any;\n setRouteState: (id: string, key: string, value: any) => void;\n}\n\nexport const RootRouteContext = createContext<RootRouteContextType | null>(\n null\n);\n","import { RouteContext } from \"@/context/route-context.js\";\nimport { useRootRoute } from \"@/hooks/useRootRoute.js\";\nimport type { ParsedRoute } from \"@/types.js\";\nimport { useCallback } from \"react\";\n\nexport const RouteProvider = ({\n route,\n ...props\n}: {\n route?: ParsedRoute;\n children?: React.ReactNode;\n}) => {\n if (!route) {\n return <RouteContext.Provider value={null} {...props} />;\n }\n\n const rootRoute = useRootRoute();\n\n const getState = useCallback(\n (key: string) => {\n return rootRoute.getRouteState(route.id, key);\n },\n [rootRoute.getRouteState]\n );\n\n const setState = useCallback(\n (key: string, value: any) => {\n rootRoute.setRouteState(route.id, key, value);\n },\n [rootRoute.setRouteState]\n );\n\n return (\n <RouteContext.Provider\n value={{ ...route, getState, setState }}\n {...props}\n />\n );\n};\n","import { useOutlet } from \"@/hooks/useOutlet.js\";\nimport { useRouteMatch } from \"@/hooks/useRouteMatch.js\";\nimport { OutletProvider } from \"./outlet-provider.js\";\nimport { RouteComponent } from \"./route-component.js\";\nimport { RouteProvider } from \"./route-provider.js\";\n\nexport const Outlet = () => {\n const routeMatch = useRouteMatch();\n const depth = useOutlet() + 1;\n return (\n <OutletProvider depth={depth}>\n <RouteProvider route={routeMatch.matches.at(depth)}>\n <RouteComponent depth={depth} />\n </RouteProvider>\n </OutletProvider>\n );\n};\n","import { useCallback, useEffect, useState } from \"react\";\n\nimport { RouterContext } from \"@/context/router-context.js\";\nimport type {\n BackOptions,\n ForwardOptions,\n Location,\n NavigateOptions,\n RouterOptions,\n} from \"@/types.js\";\nimport { DefaultTransitionDuration, parseLocation } from \"@/utils.js\";\nimport { LocationProvider } from \"./location-provider.js\";\n\nexport const RouterProvider = ({\n options,\n ...props\n}: {\n options: RouterOptions;\n children: React.ReactNode;\n}) => {\n const [history, setHistory] = useState<Location[]>([\n parseLocation(window.location),\n ]);\n const [currentLocationIndex, setCurrentLocationIndex] = useState<number>(0);\n const location = history.at(currentLocationIndex)!;\n const [isTransitioning, setIsTransitioning] = useState<boolean>(false);\n const [transitionDuration, setTransitionDuration] = useState<number>(\n DefaultTransitionDuration\n );\n const [transitioningToIndex, setTransitioningToIndex] = useState<number>();\n\n useEffect(() => {\n window.history.replaceState(\n {\n index: 0,\n },\n \"\"\n );\n const handlePopState = ({ state }: PopStateEvent) => {\n setCurrentLocationIndex(state?.index ?? 0);\n };\n\n window.addEventListener(\"popstate\", handlePopState);\n return () => {\n window.removeEventListener(\"popstate\", handlePopState);\n };\n }, [setCurrentLocationIndex]);\n\n // Update location state\n const setLocationState = useCallback(\n (index: number, state: Record<string, any>) => {\n setHistory((prevHistory) =>\n prevHistory.map((location) =>\n location.index === index ? { ...location, state } : location\n )\n );\n if (index === currentLocationIndex) {\n window.history.replaceState(\n {\n index,\n ...state,\n },\n \"\",\n location.pathname\n );\n }\n },\n [currentLocationIndex]\n );\n\n const navigate = useCallback(\n ({\n to,\n replace,\n transition,\n duration,\n updateHistory = true,\n onFinish,\n ...locationOptions\n }: NavigateOptions) => {\n if (isTransitioning) return;\n\n const index = replace ? currentLocationIndex : currentLocationIndex + 1;\n\n // Resolve to with absolute or relative paths like \"..\" or \".\"\n let pathname: string;\n if (to.startsWith(\".\")) {\n const currentPathSegments = location.pathname\n .split(\"/\")\n .filter((seg) => seg.length > 0);\n const toPathSegments = to.split(\"/\").filter((seg) => seg.length > 0);\n for (const segment of toPathSegments) {\n if (segment.startsWith(\".\")) {\n if (segment === \".\") {\n continue;\n } else if (segment === \"..\") {\n currentPathSegments.pop();\n } else {\n throw new Error(\n `Invalid relative path segment: ${segment} in ${to}`\n );\n }\n } else if (segment.length > 0) {\n currentPathSegments.push(segment);\n }\n }\n pathname = \"/\" + currentPathSegments.join(\"/\");\n } else {\n pathname = to;\n }\n\n setHistory((prevHistory) => [\n ...(index === history.length ? history : prevHistory.slice(0, index)),\n {\n index,\n search: {},\n state: {},\n pathname,\n ...locationOptions,\n },\n ]);\n if (\n !replace &&\n currentLocationIndex >= 0 &&\n (transition ??\n options.defaultUseTransition?.(location, history.at(index)))\n ) {\n const currentDuration = duration ?? DefaultTransitionDuration;\n setIsTransitioning(true);\n setTransitionDuration(currentDuration);\n setTransitioningToIndex(index);\n setTimeout(() => {\n setIsTransitioning(false);\n setTransitioningToIndex(undefined);\n setCurrentLocationIndex(index);\n onFinish?.();\n if (updateHistory) {\n window.history.pushState(\n {\n index,\n },\n \"\",\n to\n );\n }\n }, currentDuration);\n } else if (!replace) {\n setCurrentLocationIndex(index);\n if (updateHistory) {\n window.history.pushState(\n {\n index,\n },\n \"\",\n to\n );\n }\n } else if (updateHistory) {\n window.history.replaceState(\n {\n index,\n },\n \"\",\n to\n );\n }\n },\n [currentLocationIndex, history, isTransitioning, options]\n );\n\n const back = useCallback(\n ({ transition, duration, onFinish, depth }: BackOptions = {}) => {\n if (currentLocationIndex === 0 || isTransitioning) return;\n const newLocationIndex = currentLocationIndex - (depth ?? 1);\n if (\n currentLocationIndex > 0 &&\n (transition ??\n options.defaultUseTransition?.(\n location,\n history.at(newLocationIndex)\n ))\n ) {\n const finalDuration = duration ?? DefaultTransitionDuration;\n setIsTransitioning(true);\n setTransitionDuration(finalDuration);\n setTransitioningToIndex(newLocationIndex);\n setTimeout(() => {\n setIsTransitioning(false);\n setTransitioningToIndex(undefined);\n setCurrentLocationIndex(newLocationIndex);\n onFinish?.();\n window.history.back();\n }, finalDuration);\n } else {\n setCurrentLocationIndex(newLocationIndex);\n onFinish?.();\n window.history.back();\n }\n },\n [currentLocationIndex, history, isTransitioning, options]\n );\n\n const forward = useCallback(\n ({ transition, duration, onFinish }: ForwardOptions = {}) => {\n if (currentLocationIndex + 1 >= history.length || isTransitioning) return;\n const newLocationIndex = currentLocationIndex + 1;\n if (\n newLocationIndex < history.length &&\n (transition ??\n options.defaultUseTransition?.(\n location,\n history.at(newLocationIndex)\n ))\n ) {\n const finalDuration = duration ?? DefaultTransitionDuration;\n setIsTransitioning(true);\n setTransitionDuration(finalDuration);\n setTransitioningToIndex(newLocationIndex);\n setTimeout(() => {\n setIsTransitioning(false);\n setTransitioningToIndex(undefined);\n setCurrentLocationIndex(newLocationIndex);\n onFinish?.();\n window.history.forward();\n }, finalDuration);\n } else {\n setCurrentLocationIndex(newLocationIndex);\n onFinish?.();\n window.history.forward();\n }\n },\n [currentLocationIndex, history, isTransitioning, options]\n );\n\n return (\n <RouterContext.Provider\n value={{\n options,\n\n history,\n location,\n canGoBack: currentLocationIndex > 0,\n canGoForward: currentLocationIndex < history.length - 1,\n\n isTransitioning,\n transitionDuration,\n transitioningToIndex,\n\n navigate,\n back,\n forward,\n\n setLocationState,\n }}\n >\n <LocationProvider location={location} {...props} />\n </RouterContext.Provider>\n );\n};\n","import type { RouterOptions } from \"./types.js\";\n\nexport const DefaultRouterOptions: RouterOptions = {\n defaultTransitionDuration: 300,\n};\n","import { DefaultRouterOptions } from \"./constants.js\";\nimport type {\n Location,\n ParsedRoute,\n Route,\n RouteMatch,\n RouterOptions,\n} from \"./types.js\";\n\nexport const DefaultTransitionDuration = 300;\n\nexport const redirect = (options: { to: string; replace?: boolean }) => {\n return new Error(\"\", { cause: options });\n};\n\n/**\n * @param pattern pathname pattern like `/users/:id`. Leading and trailing slashes are optional.\n * @param url URL to match against the pattern. Can be href or pathname with query string.\n * @returns extracted params and query if matched, otherwise null\n */\nexport const matchPattern = (\n pattern: string,\n url: string\n): { params: Record<string, string>; query: Record<string, string> } | null => {\n try {\n // 解析 URL\n let pathname, searchParams;\n\n if (url.startsWith(\"http://\") || url.startsWith(\"https://\")) {\n const urlObj = new URL(url);\n pathname = urlObj.pathname;\n searchParams = urlObj.searchParams;\n } else {\n // 處理相對路徑\n const [path, queryString] = url.split(\"?\");\n if (!path) {\n return null;\n }\n pathname = path;\n searchParams = new URLSearchParams(queryString || \"\");\n }\n\n // 移除路徑首尾的斜線以便比較\n const cleanPath = pathname.replaceAll(/^\\/|\\/$/g, \"\");\n const cleanPattern = pattern.replaceAll(/^\\/|\\/$/g, \"\");\n\n // 分割路徑段\n const pathSegments = cleanPath.split(\"/\");\n const patternSegments = cleanPattern.split(\"/\");\n\n // 路徑段數量不同則不匹配\n if (pathSegments.length !== patternSegments.length) {\n return null;\n }\n\n // 提取路徑參數\n const params: Record<string, string> = {};\n for (let i = 0; i < patternSegments.length; i++) {\n const patternSegment = patternSegments[i];\n const pathSegment = pathSegments[i];\n\n if (patternSegment.startsWith(\":\")) {\n // 動態參數\n const paramName = patternSegment.slice(1);\n params[paramName] = decodeURIComponent(pathSegment);\n } else if (patternSegment !== pathSegment) {\n // 靜態段不匹配\n return null;\n }\n }\n\n // 提取查詢參數\n const query = Object.fromEntries(searchParams.entries());\n\n return { params, query };\n } catch {\n return null;\n }\n};\n\nexport const matchRoute = (route: ParsedRoute, url: string): RouteMatch => {\n const _matchRoute = (\n matches: ParsedRoute[],\n { children }: ParsedRoute\n ): RouteMatch | null => {\n if (children && children.length > 0) {\n for (const childRoute of children) {\n const matchesResult = _matchRoute([...matches, childRoute], childRoute);\n if (matchesResult) {\n return matchesResult;\n }\n }\n return null;\n }\n\n const result = matchPattern(buildPathnameFromMatches(matches), url);\n return result ? { matches, ...result } : null;\n };\n\n return (\n _matchRoute([route], route) || {\n matches: [],\n params: {},\n query: {},\n }\n );\n};\n\nexport const buildPathnameFromMatches = (matches: Route[]): string => {\n let cleanedPathnames: string[] = []; // pathnames without leading/trailing slashes\n for (const match of matches) {\n if (match.pathname === undefined) continue;\n cleanedPathnames.push(match.pathname.replaceAll(/^\\/|\\/$/g, \"\"));\n }\n return \"/\" + cleanedPathnames.join(\"/\");\n};\n\nexport const parseLocation = (location: globalThis.Location): Location => ({\n index: 0,\n state: {},\n pathname: location.pathname,\n search: Object.fromEntries(new URLSearchParams(location.search)),\n});\n\nexport const createRouterOptions = (\n options?: RouterOptions\n): RouterOptions => ({\n ...DefaultRouterOptions,\n ...options,\n});\n\nexport const parseRoute = (route: Route): ParsedRoute => {\n const parseRouteRecursive = (route: Route, parentId: string): ParsedRoute => {\n const id =\n route.name ??\n (route.pathname\n ? `${parentId}/${route.pathname.replaceAll(/^\\/|\\/$/g, \"\")}`\n : parentId);\n\n const parsedRoute: ParsedRoute = {\n ...route,\n id,\n children: route.children?.map((child) => parseRouteRecursive(child, id)),\n };\n\n return parsedRoute;\n };\n return parseRouteRecursive(route, \"\");\n};\n","import { useEffect, useState } from \"react\";\n\nimport { useRouter } from \"@/hooks/useRouter.js\";\nimport type { Route } from \"@/types.js\";\n\nimport { LocationProvider } from \"./location-provider.js\";\nimport { PageRenderer } from \"./page-renderer.js\";\nimport { RootRouteProvider } from \"./root-route-provider.js\";\n\nconst StackComponent = () => {\n const {\n history,\n location,\n canGoBack,\n canGoForward,\n isTransitioning,\n transitioningToIndex,\n transitionDuration,\n back,\n forward,\n } = useRouter();\n const currentLocationIndex = location?.index;\n\n const [isDragging, setIsDragging] = useState(false);\n const [startX, setStartX] = useState(0);\n const [dragOffset, setDragOffset] = useState(0);\n const [isCanceling, setIsCanceling] = useState(false);\n const [isTransitionStarted, setIsTransitionStarted] = useState(false);\n\n useEffect(() => {\n if (!isTransitioning || transitioningToIndex === null) return;\n setIsTransitionStarted(true);\n setTimeout(() => {\n setIsTransitionStarted(false);\n }, transitionDuration);\n }, [isTransitioning, transitioningToIndex]);\n\n if (currentLocationIndex === undefined) return;\n\n const reset = () => {\n setIsDragging(false);\n setDragOffset(0);\n setIsCanceling(false);\n };\n\n const handleTouchStart = (e: React.TouchEvent) => {\n if (isTransitioning || (!canGoForward && !canGoBack)) return;\n setIsDragging(true);\n setStartX(e.touches[0].clientX);\n };\n\n const handleTouchMove = (e: React.TouchEvent) => {\n if (!isDragging) return;\n const offset = e.touches[0].clientX - startX;\n if (\n (offset > 0 && currentLocationIndex === 0) ||\n (offset < 0 && currentLocationIndex + 1 === history.length)\n ) {\n setDragOffset(0);\n return;\n }\n setDragOffset(Math.min(window.innerWidth, offset));\n };\n\n const handleTouchEnd = () => {\n if (!isDragging) return;\n\n if (dragOffset > window.innerWidth * 0.3 && canGoBack) {\n back({\n onFinish: reset,\n });\n } else if (dragOffset < -window.innerWidth * 0.3 && canGoForward) {\n forward({\n onFinish: reset,\n });\n } else {\n setIsCanceling(true);\n setTimeout(reset, transitionDuration);\n }\n };\n\n return (\n <div\n style={{\n position: \"relative\",\n inset: 0,\n height: \"100%\",\n width: \"100%\",\n overflow: \"hidden\",\n }}\n >\n {currentLocationIndex >= 1 &&\n ((isDragging && dragOffset > 0) ||\n (isTransitioning &&\n transitioningToIndex !== undefined &&\n transitioningToIndex < currentLocationIndex)) && (\n <div\n style={{\n position: \"absolute\",\n inset: 0,\n zIndex: -10,\n }}\n >\n <LocationProvider location={history.at(currentLocationIndex - 1)!}>\n <PageRenderer key={currentLocationIndex - 1} />\n </LocationProvider>\n </div>\n )}\n <div\n key={currentLocationIndex}\n style={{\n background: \"white\",\n position: \"absolute\",\n inset: 0,\n overflow: \"hidden\",\n transform:\n isTransitioning &&\n transitioningToIndex !== undefined &&\n transitioningToIndex < currentLocationIndex\n ? `translateX(100%)`\n : isDragging && dragOffset > 0 && !isCanceling\n ? `translateX(${dragOffset}px)`\n : \"translateX(0px)\",\n transition:\n isCanceling ||\n (isTransitioning &&\n transitioningToIndex !== undefined &&\n transitioningToIndex < currentLocationIndex)\n ? `transform ${transitionDuration}ms ease-out`\n : \"\",\n boxShadow:\n isDragging && dragOffset > 0\n ? \"-4px 0 8px rgba(0,0,0,0.1)\"\n : \"none\",\n }}\n onTouchStart={handleTouchStart}\n onTouchMove={handleTouchMove}\n onTouchEnd={handleTouchEnd}\n >\n <PageRenderer />\n </div>\n {((isDragging && dragOffset < 0) ||\n (isTransitioning &&\n transitioningToIndex !== undefined &&\n currentLocationIndex < transitioningToIndex)) && (\n <div\n key={transitioningToIndex}\n style={{\n background: \"white\",\n position: \"absolute\",\n inset: 0,\n zIndex: 10,\n overflow: \"hidden\",\n transition: \"transform ease-in\",\n transform: isTransitionStarted\n ? `translateX(0px)`\n : isDragging && !isCanceling\n ? `translateX(${window.innerWidth + dragOffset}px)`\n : \"translateX(100%)\",\n transitionDuration:\n isTransitioning || isCanceling\n ? `${transitionDuration}ms`\n : \"0ms\",\n }}\n >\n <LocationProvider\n location={\n isDragging\n ? history.at(currentLocationIndex + 1)!\n : history.at(transitioningToIndex!)!\n }\n >\n <PageRenderer key={transitioningToIndex} />\n </LocationProvider>\n </div>\n )}\n </div>\n );\n};\n\nexport const Stack = ({ rootRoute }: { rootRoute: Route }) => (\n <RootRouteProvider rootRoute={rootRoute}>\n <StackComponent />\n </RootRouteProvider>\n);\n","import { RouteMatchContext } from \"@/context/route-match-context.js\";\nimport { useLocation } from \"@/hooks/useLocation.js\";\nimport { useRootRoute } from \"@/hooks/useRootRoute.js\";\nimport { matchRoute } from \"@/utils.js\";\nimport { RouteComponent } from \"./route-component.js\";\nimport { RouteProvider } from \"./route-provider.js\";\n\nexport const PageRenderer = () => {\n const rootRoute = useRootRoute();\n const location = useLocation();\n const routeMatch = matchRoute(rootRoute, location.pathname);\n return (\n <RouteMatchContext.Provider value={routeMatch}>\n <RouteProvider route={rootRoute}>\n <RouteComponent />\n </RouteProvider>\n </RouteMatchContext.Provider>\n );\n};\n","import { RootRouteContext } from \"@/context/root-route-context.js\";\nimport type { Route } from \"@/types.js\";\nimport { parseRoute } from \"@/utils.js\";\nimport { useCallback, useState } from \"react\";\n\nexport const RootRouteProvider = ({\n rootRoute,\n ...props\n}: {\n rootRoute: Route;\n children: React.ReactNode;\n}) => {\n const parsedRoute = parseRoute(rootRoute);\n const [state, setState] = useState<Record<string, Record<string, any>>>({});\n\n const getRouteState = useCallback(\n (id: string, key: string) => {\n return state[id]?.[key];\n },\n [state]\n );\n\n const setRouteState = useCallback((id: string, key: string, value: any) => {\n setState((prevState) => ({\n ...prevState,\n [id]: {\n ...prevState[id],\n [key]: value,\n },\n }));\n }, []);\n\n return (\n <RootRouteContext.Provider\n value={{ ...parsedRoute, getRouteState, setRouteState }}\n {...props}\n />\n );\n};\n"],"mappings":"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","names":["index_exports","__export","DefaultTransitionDuration","Link","LocationContext","LocationProvider","Outlet","RootRouteContext","RouterContext","RouterProvider","Stack","buildPathnameFromMatches","createRouterOptions","matchPattern","matchRoute","parseLocation","parseRoute","redirect","useLocation","useRootRoute","useRoute","useRouter","__toCommonJS","import_react","import_react","RouterContext","useRouter","router","RouterContext","import_jsx_runtime","Link","to","replace","transition","duration","onFinish","props","router","useRouter","e","import_react","LocationContext","import_react","import_jsx_runtime","LocationProvider","location","props","router","useRouter","getState","key","setState","value","deleteState","LocationContext","import_react","OutletContext","import_react","useOutlet","OutletContext","import_react","RouteMatchContext","import_react","useRouteMatch","routeMatch","RouteMatchContext","import_jsx_runtime","OutletProvider","depth","props","OutletContext","import_react","useLocation","context","LocationContext","import_react","RouteContext","import_react","useRoute","route","RouteContext","import_react","import_jsx_runtime","RouteComponent","depth","router","useRouter","location","useLocation","routeMatch","useRouteMatch","route","useRoute","pendingStateKey","pending","setPending","cause","NotFoundComponent","PendingComponent","Component","Outlet","import_react","import_react","RootRouteContext","useRootRoute","route","RootRouteContext","import_react","import_jsx_runtime","RouteProvider","route","props","RouteContext","rootRoute","useRootRoute","getState","key","setState","value","import_jsx_runtime","Outlet","routeMatch","useRouteMatch","depth","useOutlet","OutletProvider","RouteProvider","RouteComponent","import_react","DefaultRouterOptions","DefaultTransitionDuration","redirect","options","matchPattern","pattern","url","pathname","searchParams","urlObj","path","queryString","cleanPath","cleanPattern","pathSegments","patternSegments","params","i","patternSegment","pathSegment","paramName","query","matchRoute","route","_matchRoute","matches","children","childRoute","matchesResult","result","buildPathnameFromMatches","cleanedPathnames","match","parseLocation","location","createRouterOptions","DefaultRouterOptions","parseRoute","parseRouteRecursive","parentId","id","child","import_jsx_runtime","RouterProvider","options","props","history","setHistory","parseLocation","currentLocationIndex","setCurrentLocationIndex","location","isTransitioning","setIsTransitioning","transitionDuration","setTransitionDuration","DefaultTransitionDuration","transitioningToIndex","setTransitioningToIndex","handlePopState","state","setLocationState","index","prevHistory","navigate","to","replace","transition","duration","updateHistory","onFinish","locationOptions","pathname","currentPathSegments","seg","toPathSegments","segment","currentDuration","back","depth","newLocationIndex","finalDuration","forward","RouterContext","LocationProvider","import_react","import_jsx_runtime","PageRenderer","rootRoute","useRootRoute","location","useLocation","routeMatch","matchRoute","RouteMatchContext","RouteProvider","RouteComponent","import_react","import_jsx_runtime","RootRouteProvider","rootRoute","props","parsedRoute","parseRoute","state","setState","getRouteState","id","key","setRouteState","value","prevState","RootRouteContext","import_jsx_runtime","StackComponent","history","location","canGoBack","canGoForward","isTransitioning","transitioningToIndex","transitionDuration","back","forward","useRouter","currentLocationIndex","isDragging","setIsDragging","startX","setStartX","dragOffset","setDragOffset","isCanceling","setIsCanceling","isTransitionStarted","setIsTransitionStarted","reset","handleTouchStart","e","handleTouchMove","offset","handleTouchEnd","LocationProvider","PageRenderer","Stack","rootRoute","RootRouteProvider"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/hooks/useRouter.ts","../src/context/router-context.ts","../src/components/link.tsx","../src/context/location-context.ts","../src/components/location-provider.tsx","../src/context/outlet-context.ts","../src/hooks/useOutlet.ts","../src/context/route-match-context.ts","../src/hooks/useRouteMatch.ts","../src/components/outlet-provider.tsx","../src/hooks/useLocation.ts","../src/context/route-context.ts","../src/hooks/useRoute.ts","../src/components/route-component.tsx","../src/hooks/useRootRoute.ts","../src/context/root-route-context.ts","../src/components/route-provider.tsx","../src/components/outlet.tsx","../src/components/router-provider.tsx","../src/constants.ts","../src/utils.ts","../src/components/stack.tsx","../src/components/page-renderer.tsx","../src/components/root-route-provider.tsx"],"sourcesContent":["export * from \"./components/index.js\";\nexport * from \"./context/index.js\";\nexport * from \"./hooks/index.js\";\nexport * from \"./types.d.js\";\nexport * from \"./utils.js\";\n","import { useContext } from \"react\";\n\nimport { RouterContext } from \"@/context/router-context.js\";\n\nexport const useRouter = () => {\n const router = useContext(RouterContext);\n if (router === null) {\n throw new Error(\"useRouter must be used within a Stack\");\n }\n return router;\n};\n","import { createContext } from \"react\";\n\nimport type {\n BackOptions,\n ForwardOptions,\n Location,\n NavigateOptions,\n RouterOptions,\n} from \"@/types.js\";\n\nexport interface RouterContextType {\n // Router Config\n options: RouterOptions;\n\n // Navigation State\n history: Location[];\n location?: Location;\n canGoBack: boolean;\n canGoForward: boolean;\n\n // Transition state\n isTransitioning: boolean;\n transitionDuration: number;\n transitioningToLocation?: Location;\n\n // Actions\n navigate: (options: NavigateOptions) => void;\n back: (options?: BackOptions) => void;\n forward: (options?: ForwardOptions) => void;\n\n // Low-level state action\n setLocationState: (index: number, state: Record<string, any>) => void;\n}\n\nexport const RouterContext = createContext<RouterContextType | null>(null);\n","import { useRouter } from \"@/hooks/useRouter.js\";\nimport type { NavigateOptions } from \"@/types.js\";\n\nexport type LinkProps = React.ComponentPropsWithoutRef<\"a\"> & NavigateOptions;\n\nexport const Link: React.FC<LinkProps> = ({\n to,\n replace,\n transition,\n duration,\n onFinish,\n ...props\n}) => {\n const router = useRouter();\n return (\n <a\n {...props}\n href={to}\n onClick={(e) => {\n e.preventDefault();\n router.navigate({ to, replace, transition, duration, onFinish });\n }}\n />\n );\n};\n","import { createContext } from \"react\";\n\nimport type { Location } from \"@/types.js\";\n\nexport interface LocationContextType extends Location {\n canGoBack: boolean;\n canGoForward: boolean;\n getState: (key: string) => any;\n setState: (key: string, value: any) => void;\n deleteState: (key: string) => void;\n}\n\nexport const LocationContext = createContext<LocationContextType | null>(null);\n","import { LocationContext } from \"@/context/location-context.js\";\nimport { useRouter } from \"@/hooks/useRouter.js\";\nimport type { Location } from \"@/types.js\";\nimport { useCallback } from \"react\";\n\nexport const LocationProvider = ({\n location,\n ...props\n}: {\n location: Location;\n children: React.ReactNode;\n}) => {\n const router = useRouter();\n const getState = useCallback(\n (key: string) => {\n return location.state[key];\n },\n [location]\n );\n const setState = useCallback(\n (key: string, value: any) => {\n router.setLocationState(location.index, {\n ...location.state,\n [key]: value,\n });\n },\n [router, location]\n );\n const deleteState = useCallback(\n (key: string) => {\n delete location.state[key];\n router.setLocationState(location.index, location.state);\n },\n [router, location]\n );\n return (\n <LocationContext.Provider\n value={{\n ...location,\n canGoBack: location.index > 0,\n canGoForward: location.index < router.history.length - 1,\n getState,\n setState,\n deleteState,\n }}\n {...props}\n />\n );\n};\n","import { createContext } from \"react\";\n\nexport const OutletContext = createContext<number>(0);\n","import { OutletContext } from \"@/context/outlet-context.js\";\nimport { useContext } from \"react\";\n\nexport const useOutlet = () => useContext(OutletContext);\n","import type { RouteMatch } from \"@/types.js\";\nimport { createContext } from \"react\";\n\nexport const RouteMatchContext = createContext<RouteMatch | null>(null);\n","import { RouteMatchContext } from \"@/context/route-match-context.js\";\nimport { useContext } from \"react\";\n\nexport const useRouteMatch = () => {\n const routeMatch = useContext(RouteMatchContext);\n if (routeMatch === null) {\n throw new Error(\"useRouteMatch must be used within a RouteMatchProvider\");\n }\n return routeMatch;\n};\n","import { OutletContext } from \"@/context/outlet-context.js\";\n\nexport const OutletProvider = ({\n depth,\n ...props\n}: {\n depth: number;\n children?: React.ReactNode;\n}) => <OutletContext.Provider value={depth} {...props} />;\n","import { useContext } from \"react\";\n\nimport { LocationContext } from \"@/context/location-context.js\";\n\nexport const useLocation = () => {\n const context = useContext(LocationContext);\n if (context === null) {\n throw new Error(\"useLocation must be used within a LocationProvider\");\n }\n return context;\n};\n","import type { ParsedRoute } from \"@/types.js\";\nimport { createContext } from \"react\";\n\nexport interface RouteContextType extends ParsedRoute {\n getState: (key: string) => any;\n setState: (key: string, value: any) => void;\n}\n\nexport const RouteContext = createContext<RouteContextType | null>(null);\n","import { RouteContext } from \"@/context/route-context.js\";\nimport { useContext } from \"react\";\n\nexport const useRoute = () => {\n const route = useContext(RouteContext);\n if (route === null) {\n throw new Error(\"useRoute must be used within a RouteProvider\");\n }\n return route;\n};\n","import { useLocation } from \"@/hooks/useLocation.js\";\nimport { useRoute } from \"@/hooks/useRoute.js\";\nimport { useRouteMatch } from \"@/hooks/useRouteMatch.js\";\nimport { useRouter } from \"@/hooks/useRouter.js\";\nimport { useEffect, useState } from \"react\";\nimport { Outlet } from \"./outlet.js\";\n\nexport const RouteComponent = ({ depth = 0 }: { depth?: number }) => {\n const router = useRouter();\n const location = useLocation();\n const routeMatch = useRouteMatch();\n const route = useRoute();\n\n const pendingStateKey = `_Z.${route.id}.pending`;\n\n const [pending, setPending] = useState(\n !!route?.beforeLoad && route?.getState(pendingStateKey) !== false\n );\n\n useEffect(() => {\n if (!route || depth >= routeMatch.matches.length) {\n return;\n }\n // TODO: push location still loading. Maybe store state in route () instead of location\n if (pending && route?.beforeLoad) {\n route.setState(pendingStateKey, true);\n route\n .beforeLoad({ location })\n .catch(({ cause }: Error) => {\n if (\"to\" in (cause as any)) {\n router.navigate(cause as any);\n }\n })\n .finally(() => {\n route.setState(pendingStateKey, false);\n setPending(false);\n });\n }\n }, []);\n\n if (!route) {\n return null;\n }\n\n if (depth >= routeMatch.matches.length) {\n const NotFoundComponent = route.notFoundComponent!;\n return <NotFoundComponent />;\n }\n\n if (pending) {\n const PendingComponent = route.pendingComponent!;\n return <PendingComponent />;\n }\n\n const Component = route.component;\n return Component ? <Component /> : <Outlet />;\n};\n","import { useContext } from \"react\";\n\nimport { RootRouteContext } from \"@/context/root-route-context.js\";\n\nexport const useRootRoute = () => {\n const route = useContext(RootRouteContext);\n if (route === null) {\n throw new Error(\"useRootRoute must be used within a RootRouteProvider\");\n }\n return route;\n};\n","import { createContext } from \"react\";\n\nimport type { ParsedRoute } from \"@/types.js\";\n\nexport interface RootRouteContextType extends ParsedRoute {\n getRouteState: (id: string, key: string) => any;\n setRouteState: (id: string, key: string, value: any) => void;\n}\n\nexport const RootRouteContext = createContext<RootRouteContextType | null>(\n null\n);\n","import { RouteContext } from \"@/context/route-context.js\";\nimport { useRootRoute } from \"@/hooks/useRootRoute.js\";\nimport type { ParsedRoute } from \"@/types.js\";\nimport { useCallback } from \"react\";\n\nexport const RouteProvider = ({\n route,\n ...props\n}: {\n route?: ParsedRoute;\n children?: React.ReactNode;\n}) => {\n if (!route) {\n return <RouteContext.Provider value={null} {...props} />;\n }\n\n const rootRoute = useRootRoute();\n\n const getState = useCallback(\n (key: string) => {\n return rootRoute.getRouteState(route.id, key);\n },\n [rootRoute.getRouteState]\n );\n\n const setState = useCallback(\n (key: string, value: any) => {\n rootRoute.setRouteState(route.id, key, value);\n },\n [rootRoute.setRouteState]\n );\n\n return (\n <RouteContext.Provider\n value={{ ...route, getState, setState }}\n {...props}\n />\n );\n};\n","import { useOutlet } from \"@/hooks/useOutlet.js\";\nimport { useRouteMatch } from \"@/hooks/useRouteMatch.js\";\nimport { OutletProvider } from \"./outlet-provider.js\";\nimport { RouteComponent } from \"./route-component.js\";\nimport { RouteProvider } from \"./route-provider.js\";\n\nexport const Outlet = () => {\n const routeMatch = useRouteMatch();\n const depth = useOutlet() + 1;\n return (\n <OutletProvider depth={depth}>\n <RouteProvider route={routeMatch.matches.at(depth)}>\n <RouteComponent depth={depth} />\n </RouteProvider>\n </OutletProvider>\n );\n};\n","import { useCallback, useEffect, useState } from \"react\";\n\nimport { RouterContext } from \"@/context/router-context.js\";\nimport type {\n BackOptions,\n ForwardOptions,\n Location,\n NavigateOptions,\n RouterOptions,\n} from \"@/types.js\";\nimport { parseLocation } from \"@/utils.js\";\nimport { LocationProvider } from \"./location-provider.js\";\n\nexport const RouterProvider = ({\n options,\n ...props\n}: {\n options: RouterOptions;\n children: React.ReactNode;\n}) => {\n const [history, setHistory] = useState<Location[]>([\n parseLocation(window.location),\n ]);\n const [currentLocationIndex, setCurrentLocationIndex] = useState<number>(0);\n const location = history.at(currentLocationIndex)!;\n const [isTransitioning, setIsTransitioning] = useState<boolean>(false);\n const [transitionDuration, setTransitionDuration] = useState<number>(0);\n const [transitioningToLocation, setTransitioningToLocation] =\n useState<Location>();\n\n useEffect(() => {\n window.history.replaceState(history[0].state, \"\", history[0].pathname);\n const handlePopState = ({ state }: PopStateEvent) => {\n setCurrentLocationIndex(state?.index ?? 0);\n };\n\n addEventListener(\"popstate\", handlePopState);\n return () => {\n removeEventListener(\"popstate\", handlePopState);\n };\n }, []);\n\n const transitionTo = (\n location: Location,\n duration: number = options.defaultTransitionDuration,\n callback?: () => void\n ) => {\n setIsTransitioning(true);\n setTransitionDuration(duration);\n setTransitioningToLocation(location);\n setTimeout(() => {\n setIsTransitioning(false);\n setTransitioningToLocation(undefined);\n // TODO: May can be deleted\n setCurrentLocationIndex(location.index);\n callback?.();\n }, duration);\n };\n\n // Update location state\n const setLocationState = useCallback(\n (index: number, state: Record<string, any>) => {\n setHistory((prevHistory) =>\n prevHistory.map((location) =>\n location.index === index ? { ...location, state } : location\n )\n );\n if (index === currentLocationIndex) {\n window.history.replaceState(state, \"\", location.pathname);\n }\n },\n [currentLocationIndex]\n );\n\n const navigate = useCallback(\n ({\n to,\n replace,\n transition,\n duration,\n onFinish,\n ...locationOptions\n }: NavigateOptions) => {\n if (isTransitioning) return;\n\n const index = replace ? currentLocationIndex : currentLocationIndex + 1;\n\n // Resolve to with absolute or relative paths like \"..\" or \".\"\n // TODO: Wrap into a utility function\n let pathname: string;\n if (to.startsWith(\"/\")) {\n pathname = to;\n } else {\n const currentPathSegments = location.pathname\n .split(\"/\")\n .filter((seg) => seg.length > 0);\n const toPathSegments = to.split(\"/\").filter((seg) => seg.length > 0);\n for (const segment of toPathSegments) {\n if (segment === \".\") {\n continue;\n } else if (segment === \"..\") {\n currentPathSegments.pop();\n } else {\n currentPathSegments.push(segment);\n }\n }\n pathname = \"/\" + currentPathSegments.join(\"/\");\n }\n const state = {\n index,\n };\n const newLocation = {\n index,\n search: {},\n state,\n pathname,\n ...locationOptions,\n };\n\n const updateHistory = () => {\n if (replace) {\n setHistory((prevHistory) => [\n ...prevHistory.slice(0, index),\n newLocation,\n ...prevHistory.slice(index + 1),\n ]);\n window.history.replaceState(state, \"\", pathname);\n } else {\n setHistory((prevHistory) => [\n ...prevHistory.slice(0, index),\n newLocation,\n ]);\n setCurrentLocationIndex(index);\n window.history.pushState(state, \"\", pathname);\n }\n onFinish?.();\n };\n\n if (transition ?? options.defaultUseTransition?.(location, newLocation)) {\n transitionTo(newLocation, duration, updateHistory);\n } else {\n updateHistory();\n }\n },\n [currentLocationIndex, history, isTransitioning, options]\n );\n\n const back = useCallback(\n ({ transition, duration, onFinish, depth }: BackOptions = {}) => {\n if (currentLocationIndex === 0 || isTransitioning) return;\n const backDepth = depth ?? 1;\n const newLocation = history.at(currentLocationIndex - backDepth);\n\n const updateHistory = () => {\n window.history.go(-backDepth);\n onFinish?.();\n };\n\n if (\n newLocation &&\n (transition ?? options.defaultUseTransition?.(location, newLocation))\n ) {\n transitionTo(newLocation, duration, updateHistory);\n } else {\n updateHistory();\n }\n },\n [currentLocationIndex, history, isTransitioning, options]\n );\n\n const forward = useCallback(\n ({ transition, duration, depth, onFinish }: ForwardOptions = {}) => {\n if (currentLocationIndex + 1 >= history.length || isTransitioning) return;\n const forwardDepth = depth ?? 1;\n const newLocation = history.at(currentLocationIndex + forwardDepth);\n\n const updateHistory = () => {\n window.history.go(forwardDepth);\n onFinish?.();\n };\n\n if (\n newLocation &&\n (transition ?? options.defaultUseTransition?.(location, newLocation))\n ) {\n transitionTo(newLocation, duration, updateHistory);\n } else {\n updateHistory();\n }\n },\n [currentLocationIndex, history, isTransitioning, options]\n );\n\n return (\n <RouterContext.Provider\n value={{\n options,\n\n history,\n location,\n canGoBack: currentLocationIndex > 0,\n canGoForward: currentLocationIndex < history.length - 1,\n\n isTransitioning,\n transitionDuration,\n transitioningToLocation,\n\n navigate,\n back,\n forward,\n\n setLocationState,\n }}\n >\n <LocationProvider location={location} {...props} />\n </RouterContext.Provider>\n );\n};\n","import type { RouterOptions } from \"./types.js\";\n\nexport const DefaultRouterOptions: RouterOptions = {\n defaultTransitionDuration: 300,\n};\n","import { DefaultRouterOptions } from \"./constants.js\";\nimport type {\n Location,\n ParsedRoute,\n Route,\n RouteMatch,\n RouterOptions,\n} from \"./types.js\";\n\nexport const DefaultTransitionDuration = 300;\n\nexport const redirect = (options: { to: string; replace?: boolean }) => {\n return new Error(\"\", { cause: options });\n};\n\n/**\n * @param pattern pathname pattern like `/users/:id`. Leading and trailing slashes are optional.\n * @param url URL to match against the pattern. Can be href or pathname with query string.\n * @returns extracted params and query if matched, otherwise null\n */\nexport const matchPattern = (\n pattern: string,\n url: string\n): { params: Record<string, string>; query: Record<string, string> } | null => {\n try {\n // 解析 URL\n let pathname, searchParams;\n\n if (url.startsWith(\"http://\") || url.startsWith(\"https://\")) {\n const urlObj = new URL(url);\n pathname = urlObj.pathname;\n searchParams = urlObj.searchParams;\n } else {\n // 處理相對路徑\n const [path, queryString] = url.split(\"?\");\n if (!path) {\n return null;\n }\n pathname = path;\n searchParams = new URLSearchParams(queryString || \"\");\n }\n\n // 移除路徑首尾的斜線以便比較\n const cleanPath = pathname.replaceAll(/^\\/|\\/$/g, \"\");\n const cleanPattern = pattern.replaceAll(/^\\/|\\/$/g, \"\");\n\n // 分割路徑段\n const pathSegments = cleanPath.split(\"/\");\n const patternSegments = cleanPattern.split(\"/\");\n\n // 路徑段數量不同則不匹配\n if (pathSegments.length !== patternSegments.length) {\n return null;\n }\n\n // 提取路徑參數\n const params: Record<string, string> = {};\n for (let i = 0; i < patternSegments.length; i++) {\n const patternSegment = patternSegments[i];\n const pathSegment = pathSegments[i];\n\n if (patternSegment.startsWith(\":\")) {\n // 動態參數\n const paramName = patternSegment.slice(1);\n params[paramName] = decodeURIComponent(pathSegment);\n } else if (patternSegment !== pathSegment) {\n // 靜態段不匹配\n return null;\n }\n }\n\n // 提取查詢參數\n const query = Object.fromEntries(searchParams.entries());\n\n return { params, query };\n } catch {\n return null;\n }\n};\n\nexport const matchRoute = (route: ParsedRoute, url: string): RouteMatch => {\n const _matchRoute = (\n matches: ParsedRoute[],\n { children }: ParsedRoute\n ): RouteMatch | null => {\n if (children && children.length > 0) {\n for (const childRoute of children) {\n const matchesResult = _matchRoute([...matches, childRoute], childRoute);\n if (matchesResult) {\n return matchesResult;\n }\n }\n return null;\n }\n\n const result = matchPattern(buildPathnameFromMatches(matches), url);\n return result ? { matches, ...result } : null;\n };\n\n return (\n _matchRoute([route], route) || {\n matches: [],\n params: {},\n query: {},\n }\n );\n};\n\nexport const buildPathnameFromMatches = (matches: Route[]): string => {\n let cleanedPathnames: string[] = []; // pathnames without leading/trailing slashes\n for (const match of matches) {\n if (match.pathname === undefined) continue;\n cleanedPathnames.push(match.pathname.replaceAll(/^\\/|\\/$/g, \"\"));\n }\n return \"/\" + cleanedPathnames.join(\"/\");\n};\n\nexport const parseLocation = (location: globalThis.Location): Location => ({\n index: 0,\n state: {\n index: 0,\n },\n pathname: location.pathname,\n search: Object.fromEntries(new URLSearchParams(location.search)),\n});\n\nexport const createRouterOptions = (\n options?: Partial<RouterOptions>\n): RouterOptions => ({\n ...DefaultRouterOptions,\n ...options,\n});\n\nexport const parseRoute = (route: Route): ParsedRoute => {\n const parseRouteRecursive = (route: Route, parentId: string): ParsedRoute => {\n const id =\n route.name ??\n (route.pathname\n ? `${parentId}/${route.pathname.replaceAll(/^\\/|\\/$/g, \"\")}`\n : parentId);\n\n const parsedRoute: ParsedRoute = {\n ...route,\n id,\n children: route.children?.map((child) => parseRouteRecursive(child, id)),\n };\n\n return parsedRoute;\n };\n return parseRouteRecursive(route, \"\");\n};\n","import { useEffect, useState } from \"react\";\n\nimport { useRouter } from \"@/hooks/useRouter.js\";\nimport type { Route } from \"@/types.js\";\n\nimport { LocationProvider } from \"./location-provider.js\";\nimport { PageRenderer } from \"./page-renderer.js\";\nimport { RootRouteProvider } from \"./root-route-provider.js\";\n\nconst StackComponent = () => {\n const {\n history,\n location,\n canGoBack,\n canGoForward,\n isTransitioning,\n transitioningToLocation,\n transitionDuration,\n back,\n forward,\n } = useRouter();\n const currentLocationIndex = location?.index;\n const transitioningToLocationIndex = transitioningToLocation?.index;\n\n const [isDragging, setIsDragging] = useState(false);\n const [startX, setStartX] = useState(0);\n const [dragOffset, setDragOffset] = useState(0);\n const [isCanceling, setIsCanceling] = useState(false);\n const [isTransitionStarted, setIsTransitionStarted] = useState(false);\n\n useEffect(() => {\n if (!isTransitioning || !transitioningToLocation) return;\n setIsTransitionStarted(true);\n setTimeout(() => {\n setIsTransitionStarted(false);\n }, transitionDuration);\n }, [isTransitioning, transitioningToLocation]);\n\n if (currentLocationIndex === undefined) return;\n\n const reset = () => {\n setIsDragging(false);\n setDragOffset(0);\n setIsCanceling(false);\n };\n\n const handleTouchStart = (e: React.TouchEvent) => {\n if (isTransitioning || (!canGoForward && !canGoBack)) return;\n setIsDragging(true);\n setStartX(e.touches[0].clientX);\n };\n\n const handleTouchMove = (e: React.TouchEvent) => {\n if (!isDragging) return;\n const offset = e.touches[0].clientX - startX;\n if (\n (offset > 0 && currentLocationIndex === 0) ||\n (offset < 0 && currentLocationIndex + 1 === history.length)\n ) {\n setDragOffset(0);\n return;\n }\n setDragOffset(Math.min(innerWidth, offset));\n };\n\n const handleTouchEnd = () => {\n if (!isDragging) return;\n\n if (dragOffset > innerWidth * 0.3 && canGoBack) {\n back({\n onFinish: reset,\n });\n } else if (dragOffset < -innerWidth * 0.3 && canGoForward) {\n forward({\n onFinish: reset,\n });\n } else {\n setIsCanceling(true);\n setTimeout(reset, transitionDuration);\n }\n };\n\n return (\n <div\n style={{\n position: \"relative\",\n inset: 0,\n height: \"100%\",\n width: \"100%\",\n overflow: \"hidden\",\n }}\n >\n {currentLocationIndex >= 1 &&\n ((isDragging && dragOffset > 0) ||\n (isTransitioning &&\n transitioningToLocation &&\n transitioningToLocation.index < currentLocationIndex)) && (\n <div\n style={{\n position: \"absolute\",\n inset: 0,\n zIndex: -10,\n }}\n >\n <LocationProvider location={history.at(currentLocationIndex - 1)!}>\n <PageRenderer key={currentLocationIndex - 1} />\n </LocationProvider>\n </div>\n )}\n <div\n key={currentLocationIndex}\n style={{\n background: \"white\",\n position: \"absolute\",\n inset: 0,\n overflow: \"hidden\",\n transform:\n isTransitioning &&\n transitioningToLocation &&\n transitioningToLocation.index < currentLocationIndex\n ? `translateX(100%)`\n : isDragging && dragOffset > 0 && !isCanceling\n ? `translateX(${dragOffset}px)`\n : \"translateX(0px)\",\n transition:\n isCanceling ||\n (isTransitioning &&\n transitioningToLocation &&\n transitioningToLocation.index < currentLocationIndex)\n ? `transform ${transitionDuration}ms ease-out`\n : \"\",\n boxShadow:\n isDragging && dragOffset > 0\n ? \"-4px 0 8px rgba(0,0,0,0.1)\"\n : \"none\",\n }}\n onTouchStart={handleTouchStart}\n onTouchMove={handleTouchMove}\n onTouchEnd={handleTouchEnd}\n >\n <PageRenderer />\n </div>\n {((isDragging && dragOffset < 0) ||\n (isTransitioning &&\n transitioningToLocation &&\n currentLocationIndex <= transitioningToLocation.index)) && (\n <div\n style={{\n background: \"white\",\n position: \"absolute\",\n inset: 0,\n zIndex: 10,\n overflow: \"hidden\",\n transition: \"transform ease-in\",\n transform: isTransitionStarted\n ? `translateX(0px)`\n : isTransitioning\n ? \"translateX(100%)\"\n : `translateX(${innerWidth + dragOffset}px)`,\n transitionDuration:\n isTransitioning || isCanceling\n ? `${transitionDuration}ms`\n : \"0ms\",\n }}\n >\n <LocationProvider\n location={\n isTransitioning\n ? transitioningToLocation!\n : history.at(currentLocationIndex + 1)!\n }\n >\n <PageRenderer key={transitioningToLocationIndex} />\n </LocationProvider>\n </div>\n )}\n </div>\n );\n};\n\nexport const Stack = ({ rootRoute }: { rootRoute: Route }) => (\n <RootRouteProvider rootRoute={rootRoute}>\n <StackComponent />\n </RootRouteProvider>\n);\n","import { RouteMatchContext } from \"@/context/route-match-context.js\";\nimport { useLocation } from \"@/hooks/useLocation.js\";\nimport { useRootRoute } from \"@/hooks/useRootRoute.js\";\nimport { matchRoute } from \"@/utils.js\";\nimport { RouteComponent } from \"./route-component.js\";\nimport { RouteProvider } from \"./route-provider.js\";\n\nexport const PageRenderer = () => {\n const rootRoute = useRootRoute();\n const location = useLocation();\n const routeMatch = matchRoute(rootRoute, location.pathname);\n return (\n <RouteMatchContext.Provider value={routeMatch}>\n <RouteProvider route={rootRoute}>\n <RouteComponent />\n </RouteProvider>\n </RouteMatchContext.Provider>\n );\n};\n","import { RootRouteContext } from \"@/context/root-route-context.js\";\nimport type { Route } from \"@/types.js\";\nimport { parseRoute } from \"@/utils.js\";\nimport { useCallback, useState } from \"react\";\n\nexport const RootRouteProvider = ({\n rootRoute,\n ...props\n}: {\n rootRoute: Route;\n children: React.ReactNode;\n}) => {\n const parsedRoute = parseRoute(rootRoute);\n const [state, setState] = useState<Record<string, Record<string, any>>>({});\n\n const getRouteState = useCallback(\n (id: string, key: string) => {\n return state[id]?.[key];\n },\n [state]\n );\n\n const setRouteState = useCallback((id: string, key: string, value: any) => {\n setState((prevState) => ({\n ...prevState,\n [id]: {\n ...prevState[id],\n [key]: value,\n },\n }));\n }, []);\n\n return (\n <RootRouteContext.Provider\n value={{ ...parsedRoute, getRouteState, setRouteState }}\n {...props}\n />\n );\n};\n"],"mappings":"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","names":["index_exports","__export","DefaultTransitionDuration","Link","LocationContext","LocationProvider","Outlet","RootRouteContext","RouterContext","RouterProvider","Stack","buildPathnameFromMatches","createRouterOptions","matchPattern","matchRoute","parseLocation","parseRoute","redirect","useLocation","useRootRoute","useRoute","useRouter","__toCommonJS","import_react","import_react","RouterContext","useRouter","router","RouterContext","import_jsx_runtime","Link","to","replace","transition","duration","onFinish","props","router","useRouter","e","import_react","LocationContext","import_react","import_jsx_runtime","LocationProvider","location","props","router","useRouter","getState","key","setState","value","deleteState","LocationContext","import_react","OutletContext","import_react","useOutlet","OutletContext","import_react","RouteMatchContext","import_react","useRouteMatch","routeMatch","RouteMatchContext","import_jsx_runtime","OutletProvider","depth","props","OutletContext","import_react","useLocation","context","LocationContext","import_react","RouteContext","import_react","useRoute","route","RouteContext","import_react","import_jsx_runtime","RouteComponent","depth","router","useRouter","location","useLocation","routeMatch","useRouteMatch","route","useRoute","pendingStateKey","pending","setPending","cause","NotFoundComponent","PendingComponent","Component","Outlet","import_react","import_react","RootRouteContext","useRootRoute","route","RootRouteContext","import_react","import_jsx_runtime","RouteProvider","route","props","RouteContext","rootRoute","useRootRoute","getState","key","setState","value","import_jsx_runtime","Outlet","routeMatch","useRouteMatch","depth","useOutlet","OutletProvider","RouteProvider","RouteComponent","import_react","DefaultRouterOptions","DefaultTransitionDuration","redirect","options","matchPattern","pattern","url","pathname","searchParams","urlObj","path","queryString","cleanPath","cleanPattern","pathSegments","patternSegments","params","i","patternSegment","pathSegment","paramName","query","matchRoute","route","_matchRoute","matches","children","childRoute","matchesResult","result","buildPathnameFromMatches","cleanedPathnames","match","parseLocation","location","createRouterOptions","DefaultRouterOptions","parseRoute","parseRouteRecursive","parentId","id","child","import_jsx_runtime","RouterProvider","options","props","history","setHistory","parseLocation","currentLocationIndex","setCurrentLocationIndex","location","isTransitioning","setIsTransitioning","transitionDuration","setTransitionDuration","transitioningToLocation","setTransitioningToLocation","handlePopState","state","transitionTo","duration","callback","setLocationState","index","prevHistory","navigate","to","replace","transition","onFinish","locationOptions","pathname","currentPathSegments","seg","toPathSegments","segment","newLocation","updateHistory","back","depth","backDepth","forward","forwardDepth","RouterContext","LocationProvider","import_react","import_jsx_runtime","PageRenderer","rootRoute","useRootRoute","location","useLocation","routeMatch","matchRoute","RouteMatchContext","RouteProvider","RouteComponent","import_react","import_jsx_runtime","RootRouteProvider","rootRoute","props","parsedRoute","parseRoute","state","setState","getRouteState","id","key","setRouteState","value","prevState","RootRouteContext","import_jsx_runtime","StackComponent","history","location","canGoBack","canGoForward","isTransitioning","transitioningToLocation","transitionDuration","back","forward","useRouter","currentLocationIndex","transitioningToLocationIndex","isDragging","setIsDragging","startX","setStartX","dragOffset","setDragOffset","isCanceling","setIsCanceling","isTransitionStarted","setIsTransitionStarted","reset","handleTouchStart","e","handleTouchMove","offset","handleTouchEnd","LocationProvider","PageRenderer","Stack","rootRoute","RootRouteProvider"]}
package/dist/index.d.cts CHANGED
@@ -30,14 +30,14 @@ interface RouteMatch {
30
30
  }
31
31
 
32
32
  interface RouterOptions {
33
- defaultUseTransition?: (
33
+ defaultUseTransition: (
34
34
  fromLocation: Location | undefined,
35
35
  toLocation: Location | undefined
36
36
  ) => boolean;
37
37
  /**
38
38
  * @default 300
39
39
  */
40
- defaultTransitionDuration?: number;
40
+ defaultTransitionDuration: number;
41
41
  }
42
42
 
43
43
  interface TransitionOptions {
@@ -102,7 +102,7 @@ interface RouterContextType {
102
102
  canGoForward: boolean;
103
103
  isTransitioning: boolean;
104
104
  transitionDuration: number;
105
- transitioningToIndex?: number;
105
+ transitioningToLocation?: Location;
106
106
  navigate: (options: NavigateOptions) => void;
107
107
  back: (options?: BackOptions) => void;
108
108
  forward: (options?: ForwardOptions) => void;
@@ -140,7 +140,7 @@ declare const matchPattern: (pattern: string, url: string) => {
140
140
  declare const matchRoute: (route: ParsedRoute, url: string) => RouteMatch;
141
141
  declare const buildPathnameFromMatches: (matches: Route[]) => string;
142
142
  declare const parseLocation: (location: globalThis.Location) => Location;
143
- declare const createRouterOptions: (options?: RouterOptions) => RouterOptions;
143
+ declare const createRouterOptions: (options?: Partial<RouterOptions>) => RouterOptions;
144
144
  declare const parseRoute: (route: Route) => ParsedRoute;
145
145
 
146
146
  export { type BackOptions, DefaultTransitionDuration, type ForwardOptions, Link, type LinkProps, type Location, LocationContext, type LocationContextType, LocationProvider, type NavigateOptions, Outlet, type ParsedRoute, RootRouteContext, type RootRouteContextType, type Route, type RouteMatch, RouterContext, type RouterContextType, type RouterOptions, RouterProvider, Stack, type TransitionOptions, buildPathnameFromMatches, createRouterOptions, matchPattern, matchRoute, parseLocation, parseRoute, redirect, useLocation, useRootRoute, useRoute, useRouter };
package/dist/index.d.ts CHANGED
@@ -30,14 +30,14 @@ interface RouteMatch {
30
30
  }
31
31
 
32
32
  interface RouterOptions {
33
- defaultUseTransition?: (
33
+ defaultUseTransition: (
34
34
  fromLocation: Location | undefined,
35
35
  toLocation: Location | undefined
36
36
  ) => boolean;
37
37
  /**
38
38
  * @default 300
39
39
  */
40
- defaultTransitionDuration?: number;
40
+ defaultTransitionDuration: number;
41
41
  }
42
42
 
43
43
  interface TransitionOptions {
@@ -102,7 +102,7 @@ interface RouterContextType {
102
102
  canGoForward: boolean;
103
103
  isTransitioning: boolean;
104
104
  transitionDuration: number;
105
- transitioningToIndex?: number;
105
+ transitioningToLocation?: Location;
106
106
  navigate: (options: NavigateOptions) => void;
107
107
  back: (options?: BackOptions) => void;
108
108
  forward: (options?: ForwardOptions) => void;
@@ -140,7 +140,7 @@ declare const matchPattern: (pattern: string, url: string) => {
140
140
  declare const matchRoute: (route: ParsedRoute, url: string) => RouteMatch;
141
141
  declare const buildPathnameFromMatches: (matches: Route[]) => string;
142
142
  declare const parseLocation: (location: globalThis.Location) => Location;
143
- declare const createRouterOptions: (options?: RouterOptions) => RouterOptions;
143
+ declare const createRouterOptions: (options?: Partial<RouterOptions>) => RouterOptions;
144
144
  declare const parseRoute: (route: Route) => ParsedRoute;
145
145
 
146
146
  export { type BackOptions, DefaultTransitionDuration, type ForwardOptions, Link, type LinkProps, type Location, LocationContext, type LocationContextType, LocationProvider, type NavigateOptions, Outlet, type ParsedRoute, RootRouteContext, type RootRouteContextType, type Route, type RouteMatch, RouterContext, type RouterContextType, type RouterOptions, RouterProvider, Stack, type TransitionOptions, buildPathnameFromMatches, createRouterOptions, matchPattern, matchRoute, parseLocation, parseRoute, redirect, useLocation, useRootRoute, useRoute, useRouter };
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import{useContext as lt}from"react";import{createContext as ft}from"react";var $=ft(null);var L=()=>{let t=lt($);if(t===null)throw new Error("useRouter must be used within a Stack");return t};import{jsx as Rt}from"react/jsx-runtime";var _t=({to:t,replace:r,transition:o,duration:s,onFinish:e,...n})=>{let i=L();return Rt("a",{...n,href:t,onClick:c=>{c.preventDefault(),i.navigate({to:t,replace:r,transition:o,duration:s,onFinish:e})}})};import{createContext as ht}from"react";var B=ht(null);import{useCallback as J}from"react";import{jsx as gt}from"react/jsx-runtime";var D=({location:t,...r})=>{let o=L(),s=J(i=>t.state[i],[t]),e=J((i,c)=>{o.setLocationState(t.index,{...t.state,[i]:c})},[o,t]),n=J(i=>{delete t.state[i],o.setLocationState(t.index,t.state)},[o,t]);return gt(B.Provider,{value:{...t,canGoBack:t.index>0,canGoForward:t.index<o.history.length-1,getState:s,setState:e,deleteState:n},...r})};import{createContext as xt}from"react";var G=xt(0);import{useContext as yt}from"react";var Y=()=>yt(G);import{createContext as vt}from"react";var W=vt(null);import{useContext as wt}from"react";var X=()=>{let t=wt(W);if(t===null)throw new Error("useRouteMatch must be used within a RouteMatchProvider");return t};import{jsx as Pt}from"react/jsx-runtime";var tt=({depth:t,...r})=>Pt(G.Provider,{value:t,...r});import{useContext as Ct}from"react";var j=()=>{let t=Ct(B);if(t===null)throw new Error("useLocation must be used within a LocationProvider");return t};import{createContext as bt}from"react";var E=bt(null);import{useContext as Lt}from"react";var et=()=>{let t=Lt(E);if(t===null)throw new Error("useRoute must be used within a RouteProvider");return t};import{useEffect as St,useState as Ot}from"react";import{jsx as U}from"react/jsx-runtime";var q=({depth:t=0})=>{let r=L(),o=j(),s=X(),e=et(),n=`_Z.${e.id}.pending`,[i,c]=Ot(!!e?.beforeLoad&&e?.getState(n)!==!1);if(St(()=>{!e||t>=s.matches.length||i&&e?.beforeLoad&&(e.setState(n,!0),e.beforeLoad({location:o}).catch(({cause:m})=>{"to"in m&&r.navigate(m)}).finally(()=>{e.setState(n,!1),c(!1)}))},[]),!e)return null;if(t>=s.matches.length){let m=e.notFoundComponent;return U(m,{})}if(i){let m=e.pendingComponent;return U(m,{})}let f=e.component;return f?U(f,{}):U(ot,{})};import{useContext as kt}from"react";import{createContext as Tt}from"react";var A=Tt(null);var z=()=>{let t=kt(A);if(t===null)throw new Error("useRootRoute must be used within a RootRouteProvider");return t};import{useCallback as nt}from"react";import{jsx as rt}from"react/jsx-runtime";var _=({route:t,...r})=>{if(!t)return rt(E.Provider,{value:null,...r});let o=z(),s=nt(n=>o.getRouteState(t.id,n),[o.getRouteState]),e=nt((n,i)=>{o.setRouteState(t.id,n,i)},[o.setRouteState]);return rt(E.Provider,{value:{...t,getState:s,setState:e},...r})};import{jsx as Q}from"react/jsx-runtime";var ot=()=>{let t=X(),r=Y()+1;return Q(tt,{depth:r,children:Q(_,{route:t.matches.at(r),children:Q(q,{depth:r})})})};import{useCallback as K,useEffect as Et,useState as I}from"react";var it={defaultTransitionDuration:300};var F=300,lo=t=>new Error("",{cause:t}),Mt=(t,r)=>{try{let o,s;if(r.startsWith("http://")||r.startsWith("https://")){let p=new URL(r);o=p.pathname,s=p.searchParams}else{let[p,v]=r.split("?");if(!p)return null;o=p,s=new URLSearchParams(v||"")}let e=o.replaceAll(/^\/|\/$/g,""),n=t.replaceAll(/^\/|\/$/g,""),i=e.split("/"),c=n.split("/");if(i.length!==c.length)return null;let f={};for(let p=0;p<c.length;p++){let v=c[p],y=i[p];if(v.startsWith(":")){let k=v.slice(1);f[k]=decodeURIComponent(y)}else if(v!==y)return null}let m=Object.fromEntries(s.entries());return{params:f,query:m}}catch{return null}},st=(t,r)=>{let o=(s,{children:e})=>{if(e&&e.length>0){for(let i of e){let c=o([...s,i],i);if(c)return c}return null}let n=Mt(Dt(s),r);return n?{matches:s,...n}:null};return o([t],t)||{matches:[],params:{},query:{}}},Dt=t=>{let r=[];for(let o of t)o.pathname!==void 0&&r.push(o.pathname.replaceAll(/^\/|\/$/g,""));return"/"+r.join("/")},at=t=>({index:0,state:{},pathname:t.pathname,search:Object.fromEntries(new URLSearchParams(t.search))}),Ro=t=>({...it,...t}),ut=t=>{let r=(o,s)=>{let e=o.name??(o.pathname?`${s}/${o.pathname.replaceAll(/^\/|\/$/g,"")}`:s);return{...o,id:e,children:o.children?.map(i=>r(i,e))}};return r(t,"")};import{jsx as ct}from"react/jsx-runtime";var Po=({options:t,...r})=>{let[o,s]=I([at(window.location)]),[e,n]=I(0),i=o.at(e),[c,f]=I(!1),[m,p]=I(F),[v,y]=I();Et(()=>{window.history.replaceState({index:0},"");let d=({state:R})=>{n(R?.index??0)};return window.addEventListener("popstate",d),()=>{window.removeEventListener("popstate",d)}},[n]);let k=K((d,R)=>{s(x=>x.map(l=>l.index===d?{...l,state:R}:l)),d===e&&window.history.replaceState({index:d,...R},"",i.pathname)},[e]),w=K(({to:d,replace:R,transition:x,duration:l,updateHistory:g=!0,onFinish:T,...H})=>{if(c)return;let h=R?e:e+1,S;if(d.startsWith(".")){let b=i.pathname.split("/").filter(P=>P.length>0),dt=d.split("/").filter(P=>P.length>0);for(let P of dt)if(P.startsWith(".")){if(P===".")continue;if(P==="..")b.pop();else throw new Error(`Invalid relative path segment: ${P} in ${d}`)}else P.length>0&&b.push(P);S="/"+b.join("/")}else S=d;if(s(b=>[...h===o.length?o:b.slice(0,h),{index:h,search:{},state:{},pathname:S,...H}]),!R&&e>=0&&(x??t.defaultUseTransition?.(i,o.at(h)))){let b=l??F;f(!0),p(b),y(h),setTimeout(()=>{f(!1),y(void 0),n(h),T?.(),g&&window.history.pushState({index:h},"",d)},b)}else R?g&&window.history.replaceState({index:h},"",d):(n(h),g&&window.history.pushState({index:h},"",d))},[e,o,c,t]),M=K(({transition:d,duration:R,onFinish:x,depth:l}={})=>{if(e===0||c)return;let g=e-(l??1);if(e>0&&(d??t.defaultUseTransition?.(i,o.at(g)))){let T=R??F;f(!0),p(T),y(g),setTimeout(()=>{f(!1),y(void 0),n(g),x?.(),window.history.back()},T)}else n(g),x?.(),window.history.back()},[e,o,c,t]),O=K(({transition:d,duration:R,onFinish:x}={})=>{if(e+1>=o.length||c)return;let l=e+1;if(l<o.length&&(d??t.defaultUseTransition?.(i,o.at(l)))){let g=R??F;f(!0),p(g),y(l),setTimeout(()=>{f(!1),y(void 0),n(l),x?.(),window.history.forward()},g)}else n(l),x?.(),window.history.forward()},[e,o,c,t]);return ct($.Provider,{value:{options:t,history:o,location:i,canGoBack:e>0,canGoForward:e<o.length-1,isTransitioning:c,transitionDuration:m,transitioningToIndex:v,navigate:w,back:M,forward:O,setLocationState:k},children:ct(D,{location:i,...r})})};import{useEffect as Nt,useState as N}from"react";import{jsx as V}from"react/jsx-runtime";var Z=()=>{let t=z(),r=j(),o=st(t,r.pathname);return V(W.Provider,{value:o,children:V(_,{route:t,children:V(q,{})})})};import{useCallback as pt,useState as Ft}from"react";import{jsx as It}from"react/jsx-runtime";var mt=({rootRoute:t,...r})=>{let o=ut(t),[s,e]=Ft({}),n=pt((c,f)=>s[c]?.[f],[s]),i=pt((c,f,m)=>{e(p=>({...p,[c]:{...p[c],[f]:m}}))},[]);return It(A.Provider,{value:{...o,getRouteState:n,setRouteState:i},...r})};import{jsx as C,jsxs as Bt}from"react/jsx-runtime";var $t=()=>{let{history:t,location:r,canGoBack:o,canGoForward:s,isTransitioning:e,transitioningToIndex:n,transitionDuration:i,back:c,forward:f}=L(),m=r?.index,[p,v]=N(!1),[y,k]=N(0),[w,M]=N(0),[O,d]=N(!1),[R,x]=N(!1);if(Nt(()=>{!e||n===null||(x(!0),setTimeout(()=>{x(!1)},i))},[e,n]),m===void 0)return;let l=()=>{v(!1),M(0),d(!1)},g=h=>{e||!s&&!o||(v(!0),k(h.touches[0].clientX))},T=h=>{if(!p)return;let S=h.touches[0].clientX-y;if(S>0&&m===0||S<0&&m+1===t.length){M(0);return}M(Math.min(window.innerWidth,S))},H=()=>{p&&(w>window.innerWidth*.3&&o?c({onFinish:l}):w<-window.innerWidth*.3&&s?f({onFinish:l}):(d(!0),setTimeout(l,i)))};return Bt("div",{style:{position:"relative",inset:0,height:"100%",width:"100%",overflow:"hidden"},children:[m>=1&&(p&&w>0||e&&n!==void 0&&n<m)&&C("div",{style:{position:"absolute",inset:0,zIndex:-10},children:C(D,{location:t.at(m-1),children:C(Z,{},m-1)})}),C("div",{style:{background:"white",position:"absolute",inset:0,overflow:"hidden",transform:e&&n!==void 0&&n<m?"translateX(100%)":p&&w>0&&!O?`translateX(${w}px)`:"translateX(0px)",transition:O||e&&n!==void 0&&n<m?`transform ${i}ms ease-out`:"",boxShadow:p&&w>0?"-4px 0 8px rgba(0,0,0,0.1)":"none"},onTouchStart:g,onTouchMove:T,onTouchEnd:H,children:C(Z,{})},m),(p&&w<0||e&&n!==void 0&&m<n)&&C("div",{style:{background:"white",position:"absolute",inset:0,zIndex:10,overflow:"hidden",transition:"transform ease-in",transform:R?"translateX(0px)":p&&!O?`translateX(${window.innerWidth+w}px)`:"translateX(100%)",transitionDuration:e||O?`${i}ms`:"0ms"},children:C(D,{location:p?t.at(m+1):t.at(n),children:C(Z,{},n)})},n)]})},_o=({rootRoute:t})=>C(mt,{rootRoute:t,children:C($t,{})});export{F as DefaultTransitionDuration,_t as Link,B as LocationContext,D as LocationProvider,ot as Outlet,A as RootRouteContext,$ as RouterContext,Po as RouterProvider,_o as Stack,Dt as buildPathnameFromMatches,Ro as createRouterOptions,Mt as matchPattern,st as matchRoute,at as parseLocation,ut as parseRoute,lo as redirect,j as useLocation,z as useRootRoute,et as useRoute,L as useRouter};
1
+ import{useContext as ht}from"react";import{createContext as Rt}from"react";var G=Rt(null);var S=()=>{let t=ht(G);if(t===null)throw new Error("useRouter must be used within a Stack");return t};import{jsx as gt}from"react/jsx-runtime";var Kt=({to:t,replace:r,transition:o,duration:s,onFinish:e,...n})=>{let i=S();return gt("a",{...n,href:t,onClick:c=>{c.preventDefault(),i.navigate({to:t,replace:r,transition:o,duration:s,onFinish:e})}})};import{createContext as xt}from"react";var I=xt(null);import{useCallback as Q}from"react";import{jsx as yt}from"react/jsx-runtime";var D=({location:t,...r})=>{let o=S(),s=Q(i=>t.state[i],[t]),e=Q((i,c)=>{o.setLocationState(t.index,{...t.state,[i]:c})},[o,t]),n=Q(i=>{delete t.state[i],o.setLocationState(t.index,t.state)},[o,t]);return yt(I.Provider,{value:{...t,canGoBack:t.index>0,canGoForward:t.index<o.history.length-1,getState:s,setState:e,deleteState:n},...r})};import{createContext as vt}from"react";var X=vt(0);import{useContext as Pt}from"react";var et=()=>Pt(X);import{createContext as Ct}from"react";var W=Ct(null);import{useContext as Lt}from"react";var j=()=>{let t=Lt(W);if(t===null)throw new Error("useRouteMatch must be used within a RouteMatchProvider");return t};import{jsx as wt}from"react/jsx-runtime";var ot=({depth:t,...r})=>wt(X.Provider,{value:t,...r});import{useContext as bt}from"react";var U=()=>{let t=bt(I);if(t===null)throw new Error("useLocation must be used within a LocationProvider");return t};import{createContext as St}from"react";var F=St(null);import{useContext as Ot}from"react";var nt=()=>{let t=Ot(F);if(t===null)throw new Error("useRoute must be used within a RouteProvider");return t};import{useEffect as Tt,useState as kt}from"react";import{jsx as q}from"react/jsx-runtime";var A=({depth:t=0})=>{let r=S(),o=U(),s=j(),e=nt(),n=`_Z.${e.id}.pending`,[i,c]=kt(!!e?.beforeLoad&&e?.getState(n)!==!1);if(Tt(()=>{!e||t>=s.matches.length||i&&e?.beforeLoad&&(e.setState(n,!0),e.beforeLoad({location:o}).catch(({cause:p})=>{"to"in p&&r.navigate(p)}).finally(()=>{e.setState(n,!1),c(!1)}))},[]),!e)return null;if(t>=s.matches.length){let p=e.notFoundComponent;return q(p,{})}if(i){let p=e.pendingComponent;return q(p,{})}let f=e.component;return f?q(f,{}):q(rt,{})};import{useContext as Et}from"react";import{createContext as Mt}from"react";var H=Mt(null);var z=()=>{let t=Et(H);if(t===null)throw new Error("useRootRoute must be used within a RootRouteProvider");return t};import{useCallback as it}from"react";import{jsx as st}from"react/jsx-runtime";var _=({route:t,...r})=>{if(!t)return st(F.Provider,{value:null,...r});let o=z(),s=it(n=>o.getRouteState(t.id,n),[o.getRouteState]),e=it((n,i)=>{o.setRouteState(t.id,n,i)},[o.setRouteState]);return st(F.Provider,{value:{...t,getState:s,setState:e},...r})};import{jsx as V}from"react/jsx-runtime";var rt=()=>{let t=j(),r=et()+1;return V(ot,{depth:r,children:V(_,{route:t.matches.at(r),children:V(A,{depth:r})})})};import{useCallback as K,useEffect as Nt,useState as N}from"react";var at={defaultTransitionDuration:300};var ho=300,go=t=>new Error("",{cause:t}),Dt=(t,r)=>{try{let o,s;if(r.startsWith("http://")||r.startsWith("https://")){let d=new URL(r);o=d.pathname,s=d.searchParams}else{let[d,R]=r.split("?");if(!d)return null;o=d,s=new URLSearchParams(R||"")}let e=o.replaceAll(/^\/|\/$/g,""),n=t.replaceAll(/^\/|\/$/g,""),i=e.split("/"),c=n.split("/");if(i.length!==c.length)return null;let f={};for(let d=0;d<c.length;d++){let R=c[d],w=i[d];if(R.startsWith(":")){let O=R.slice(1);f[O]=decodeURIComponent(w)}else if(R!==w)return null}let p=Object.fromEntries(s.entries());return{params:f,query:p}}catch{return null}},ut=(t,r)=>{let o=(s,{children:e})=>{if(e&&e.length>0){for(let i of e){let c=o([...s,i],i);if(c)return c}return null}let n=Dt(Ft(s),r);return n?{matches:s,...n}:null};return o([t],t)||{matches:[],params:{},query:{}}},Ft=t=>{let r=[];for(let o of t)o.pathname!==void 0&&r.push(o.pathname.replaceAll(/^\/|\/$/g,""));return"/"+r.join("/")},ct=t=>({index:0,state:{index:0},pathname:t.pathname,search:Object.fromEntries(new URLSearchParams(t.search))}),xo=t=>({...at,...t}),pt=t=>{let r=(o,s)=>{let e=o.name??(o.pathname?`${s}/${o.pathname.replaceAll(/^\/|\/$/g,"")}`:s);return{...o,id:e,children:o.children?.map(i=>r(i,e))}};return r(t,"")};import{jsx as mt}from"react/jsx-runtime";var bo=({options:t,...r})=>{let[o,s]=N([ct(window.location)]),[e,n]=N(0),i=o.at(e),[c,f]=N(!1),[p,d]=N(0),[R,w]=N();Nt(()=>{window.history.replaceState(o[0].state,"",o[0].pathname);let m=({state:l})=>{n(l?.index??0)};return addEventListener("popstate",m),()=>{removeEventListener("popstate",m)}},[]);let O=(m,l=t.defaultTransitionDuration,x)=>{f(!0),d(l),w(m),setTimeout(()=>{f(!1),w(void 0),n(m.index),x?.()},l)},J=K((m,l)=>{s(x=>x.map(g=>g.index===m?{...g,state:l}:g)),m===e&&window.history.replaceState(l,"",i.pathname)},[e]),v=K(({to:m,replace:l,transition:x,duration:g,onFinish:C,...y})=>{if(c)return;let h=l?e:e+1,L;if(m.startsWith("/"))L=m;else{let b=i.pathname.split("/").filter(k=>k.length>0),ft=m.split("/").filter(k=>k.length>0);for(let k of ft)k!=="."&&(k===".."?b.pop():b.push(k));L="/"+b.join("/")}let T={index:h},B={index:h,search:{},state:T,pathname:L,...y},tt=()=>{l?(s(b=>[...b.slice(0,h),B,...b.slice(h+1)]),window.history.replaceState(T,"",L)):(s(b=>[...b.slice(0,h),B]),n(h),window.history.pushState(T,"",L)),C?.()};x??t.defaultUseTransition?.(i,B)?O(B,g,tt):tt()},[e,o,c,t]),M=K(({transition:m,duration:l,onFinish:x,depth:g}={})=>{if(e===0||c)return;let C=g??1,y=o.at(e-C),h=()=>{window.history.go(-C),x?.()};y&&(m??t.defaultUseTransition?.(i,y))?O(y,l,h):h()},[e,o,c,t]),E=K(({transition:m,duration:l,depth:x,onFinish:g}={})=>{if(e+1>=o.length||c)return;let C=x??1,y=o.at(e+C),h=()=>{window.history.go(C),g?.()};y&&(m??t.defaultUseTransition?.(i,y))?O(y,l,h):h()},[e,o,c,t]);return mt(G.Provider,{value:{options:t,history:o,location:i,canGoBack:e>0,canGoForward:e<o.length-1,isTransitioning:c,transitionDuration:p,transitioningToLocation:R,navigate:v,back:M,forward:E,setLocationState:J},children:mt(D,{location:i,...r})})};import{useEffect as Gt,useState as $}from"react";import{jsx as Y}from"react/jsx-runtime";var Z=()=>{let t=z(),r=U(),o=ut(t,r.pathname);return Y(W.Provider,{value:o,children:Y(_,{route:t,children:Y(A,{})})})};import{useCallback as dt,useState as $t}from"react";import{jsx as Bt}from"react/jsx-runtime";var lt=({rootRoute:t,...r})=>{let o=pt(t),[s,e]=$t({}),n=dt((c,f)=>s[c]?.[f],[s]),i=dt((c,f,p)=>{e(d=>({...d,[c]:{...d[c],[f]:p}}))},[]);return Bt(H.Provider,{value:{...o,getRouteState:n,setRouteState:i},...r})};import{jsx as P,jsxs as Xt}from"react/jsx-runtime";var It=()=>{let{history:t,location:r,canGoBack:o,canGoForward:s,isTransitioning:e,transitioningToLocation:n,transitionDuration:i,back:c,forward:f}=S(),p=r?.index,d=n?.index,[R,w]=$(!1),[O,J]=$(0),[v,M]=$(0),[E,m]=$(!1),[l,x]=$(!1);if(Gt(()=>{!e||!n||(x(!0),setTimeout(()=>{x(!1)},i))},[e,n]),p===void 0)return;let g=()=>{w(!1),M(0),m(!1)},C=L=>{e||!s&&!o||(w(!0),J(L.touches[0].clientX))},y=L=>{if(!R)return;let T=L.touches[0].clientX-O;if(T>0&&p===0||T<0&&p+1===t.length){M(0);return}M(Math.min(innerWidth,T))},h=()=>{R&&(v>innerWidth*.3&&o?c({onFinish:g}):v<-innerWidth*.3&&s?f({onFinish:g}):(m(!0),setTimeout(g,i)))};return Xt("div",{style:{position:"relative",inset:0,height:"100%",width:"100%",overflow:"hidden"},children:[p>=1&&(R&&v>0||e&&n&&n.index<p)&&P("div",{style:{position:"absolute",inset:0,zIndex:-10},children:P(D,{location:t.at(p-1),children:P(Z,{},p-1)})}),P("div",{style:{background:"white",position:"absolute",inset:0,overflow:"hidden",transform:e&&n&&n.index<p?"translateX(100%)":R&&v>0&&!E?`translateX(${v}px)`:"translateX(0px)",transition:E||e&&n&&n.index<p?`transform ${i}ms ease-out`:"",boxShadow:R&&v>0?"-4px 0 8px rgba(0,0,0,0.1)":"none"},onTouchStart:C,onTouchMove:y,onTouchEnd:h,children:P(Z,{})},p),(R&&v<0||e&&n&&p<=n.index)&&P("div",{style:{background:"white",position:"absolute",inset:0,zIndex:10,overflow:"hidden",transition:"transform ease-in",transform:l?"translateX(0px)":e?"translateX(100%)":`translateX(${innerWidth+v}px)`,transitionDuration:e||E?`${i}ms`:"0ms"},children:P(D,{location:e?n:t.at(p+1),children:P(Z,{},d)})})]})},Zo=({rootRoute:t})=>P(lt,{rootRoute:t,children:P(It,{})});export{ho as DefaultTransitionDuration,Kt as Link,I as LocationContext,D as LocationProvider,rt as Outlet,H as RootRouteContext,G as RouterContext,bo as RouterProvider,Zo as Stack,Ft as buildPathnameFromMatches,xo as createRouterOptions,Dt as matchPattern,ut as matchRoute,ct as parseLocation,pt as parseRoute,go as redirect,U as useLocation,z as useRootRoute,nt as useRoute,S as useRouter};
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/hooks/useRouter.ts","../src/context/router-context.ts","../src/components/link.tsx","../src/context/location-context.ts","../src/components/location-provider.tsx","../src/context/outlet-context.ts","../src/hooks/useOutlet.ts","../src/context/route-match-context.ts","../src/hooks/useRouteMatch.ts","../src/components/outlet-provider.tsx","../src/hooks/useLocation.ts","../src/context/route-context.ts","../src/hooks/useRoute.ts","../src/components/route-component.tsx","../src/hooks/useRootRoute.ts","../src/context/root-route-context.ts","../src/components/route-provider.tsx","../src/components/outlet.tsx","../src/components/router-provider.tsx","../src/constants.ts","../src/utils.ts","../src/components/stack.tsx","../src/components/page-renderer.tsx","../src/components/root-route-provider.tsx"],"sourcesContent":["import { useContext } from \"react\";\n\nimport { RouterContext } from \"@/context/router-context.js\";\n\nexport const useRouter = () => {\n const router = useContext(RouterContext);\n if (router === null) {\n throw new Error(\"useRouter must be used within a Stack\");\n }\n return router;\n};\n","import { createContext } from \"react\";\n\nimport type {\n BackOptions,\n ForwardOptions,\n Location,\n NavigateOptions,\n RouterOptions,\n} from \"@/types.js\";\n\nexport interface RouterContextType {\n // Router Config\n options: RouterOptions;\n\n // Navigation State\n history: Location[];\n location?: Location;\n canGoBack: boolean;\n canGoForward: boolean;\n\n // Transition state\n isTransitioning: boolean;\n transitionDuration: number;\n transitioningToIndex?: number;\n\n // Actions\n navigate: (options: NavigateOptions) => void;\n back: (options?: BackOptions) => void;\n forward: (options?: ForwardOptions) => void;\n\n // Low-level state action\n setLocationState: (index: number, state: Record<string, any>) => void;\n}\n\nexport const RouterContext = createContext<RouterContextType | null>(null);\n","import { useRouter } from \"@/hooks/useRouter.js\";\nimport type { NavigateOptions } from \"@/types.js\";\n\nexport type LinkProps = React.ComponentPropsWithoutRef<\"a\"> & NavigateOptions;\n\nexport const Link: React.FC<LinkProps> = ({\n to,\n replace,\n transition,\n duration,\n onFinish,\n ...props\n}) => {\n const router = useRouter();\n return (\n <a\n {...props}\n href={to}\n onClick={(e) => {\n e.preventDefault();\n router.navigate({ to, replace, transition, duration, onFinish });\n }}\n />\n );\n};\n","import { createContext } from \"react\";\n\nimport type { Location } from \"@/types.js\";\n\nexport interface LocationContextType extends Location {\n canGoBack: boolean;\n canGoForward: boolean;\n getState: (key: string) => any;\n setState: (key: string, value: any) => void;\n deleteState: (key: string) => void;\n}\n\nexport const LocationContext = createContext<LocationContextType | null>(null);\n","import { LocationContext } from \"@/context/location-context.js\";\nimport { useRouter } from \"@/hooks/useRouter.js\";\nimport type { Location } from \"@/types.js\";\nimport { useCallback } from \"react\";\n\nexport const LocationProvider = ({\n location,\n ...props\n}: {\n location: Location;\n children: React.ReactNode;\n}) => {\n const router = useRouter();\n const getState = useCallback(\n (key: string) => {\n return location.state[key];\n },\n [location]\n );\n const setState = useCallback(\n (key: string, value: any) => {\n router.setLocationState(location.index, {\n ...location.state,\n [key]: value,\n });\n },\n [router, location]\n );\n const deleteState = useCallback(\n (key: string) => {\n delete location.state[key];\n router.setLocationState(location.index, location.state);\n },\n [router, location]\n );\n return (\n <LocationContext.Provider\n value={{\n ...location,\n canGoBack: location.index > 0,\n canGoForward: location.index < router.history.length - 1,\n getState,\n setState,\n deleteState,\n }}\n {...props}\n />\n );\n};\n","import { createContext } from \"react\";\n\nexport const OutletContext = createContext<number>(0);\n","import { OutletContext } from \"@/context/outlet-context.js\";\nimport { useContext } from \"react\";\n\nexport const useOutlet = () => useContext(OutletContext);\n","import type { RouteMatch } from \"@/types.js\";\nimport { createContext } from \"react\";\n\nexport const RouteMatchContext = createContext<RouteMatch | null>(null);\n","import { RouteMatchContext } from \"@/context/route-match-context.js\";\nimport { useContext } from \"react\";\n\nexport const useRouteMatch = () => {\n const routeMatch = useContext(RouteMatchContext);\n if (routeMatch === null) {\n throw new Error(\"useRouteMatch must be used within a RouteMatchProvider\");\n }\n return routeMatch;\n};\n","import { OutletContext } from \"@/context/outlet-context.js\";\n\nexport const OutletProvider = ({\n depth,\n ...props\n}: {\n depth: number;\n children?: React.ReactNode;\n}) => <OutletContext.Provider value={depth} {...props} />;\n","import { useContext } from \"react\";\n\nimport { LocationContext } from \"@/context/location-context.js\";\n\nexport const useLocation = () => {\n const context = useContext(LocationContext);\n if (context === null) {\n throw new Error(\"useLocation must be used within a LocationProvider\");\n }\n return context;\n};\n","import type { ParsedRoute } from \"@/types.js\";\nimport { createContext } from \"react\";\n\nexport interface RouteContextType extends ParsedRoute {\n getState: (key: string) => any;\n setState: (key: string, value: any) => void;\n}\n\nexport const RouteContext = createContext<RouteContextType | null>(null);\n","import { RouteContext } from \"@/context/route-context.js\";\nimport { useContext } from \"react\";\n\nexport const useRoute = () => {\n const route = useContext(RouteContext);\n if (route === null) {\n throw new Error(\"useRoute must be used within a RouteProvider\");\n }\n return route;\n};\n","import { useLocation } from \"@/hooks/useLocation.js\";\nimport { useRoute } from \"@/hooks/useRoute.js\";\nimport { useRouteMatch } from \"@/hooks/useRouteMatch.js\";\nimport { useRouter } from \"@/hooks/useRouter.js\";\nimport { useEffect, useState } from \"react\";\nimport { Outlet } from \"./outlet.js\";\n\nexport const RouteComponent = ({ depth = 0 }: { depth?: number }) => {\n const router = useRouter();\n const location = useLocation();\n const routeMatch = useRouteMatch();\n const route = useRoute();\n\n const pendingStateKey = `_Z.${route.id}.pending`;\n\n const [pending, setPending] = useState(\n !!route?.beforeLoad && route?.getState(pendingStateKey) !== false\n );\n\n useEffect(() => {\n if (!route || depth >= routeMatch.matches.length) {\n return;\n }\n // TODO: push location still loading. Maybe store state in route () instead of location\n if (pending && route?.beforeLoad) {\n route.setState(pendingStateKey, true);\n route\n .beforeLoad({ location })\n .catch(({ cause }: Error) => {\n if (\"to\" in (cause as any)) {\n router.navigate(cause as any);\n }\n })\n .finally(() => {\n route.setState(pendingStateKey, false);\n setPending(false);\n });\n }\n }, []);\n\n if (!route) {\n return null;\n }\n\n if (depth >= routeMatch.matches.length) {\n const NotFoundComponent = route.notFoundComponent!;\n return <NotFoundComponent />;\n }\n\n if (pending) {\n const PendingComponent = route.pendingComponent!;\n return <PendingComponent />;\n }\n\n const Component = route.component;\n return Component ? <Component /> : <Outlet />;\n};\n","import { useContext } from \"react\";\n\nimport { RootRouteContext } from \"@/context/root-route-context.js\";\n\nexport const useRootRoute = () => {\n const route = useContext(RootRouteContext);\n if (route === null) {\n throw new Error(\"useRootRoute must be used within a RootRouteProvider\");\n }\n return route;\n};\n","import { createContext } from \"react\";\n\nimport type { ParsedRoute } from \"@/types.js\";\n\nexport interface RootRouteContextType extends ParsedRoute {\n getRouteState: (id: string, key: string) => any;\n setRouteState: (id: string, key: string, value: any) => void;\n}\n\nexport const RootRouteContext = createContext<RootRouteContextType | null>(\n null\n);\n","import { RouteContext } from \"@/context/route-context.js\";\nimport { useRootRoute } from \"@/hooks/useRootRoute.js\";\nimport type { ParsedRoute } from \"@/types.js\";\nimport { useCallback } from \"react\";\n\nexport const RouteProvider = ({\n route,\n ...props\n}: {\n route?: ParsedRoute;\n children?: React.ReactNode;\n}) => {\n if (!route) {\n return <RouteContext.Provider value={null} {...props} />;\n }\n\n const rootRoute = useRootRoute();\n\n const getState = useCallback(\n (key: string) => {\n return rootRoute.getRouteState(route.id, key);\n },\n [rootRoute.getRouteState]\n );\n\n const setState = useCallback(\n (key: string, value: any) => {\n rootRoute.setRouteState(route.id, key, value);\n },\n [rootRoute.setRouteState]\n );\n\n return (\n <RouteContext.Provider\n value={{ ...route, getState, setState }}\n {...props}\n />\n );\n};\n","import { useOutlet } from \"@/hooks/useOutlet.js\";\nimport { useRouteMatch } from \"@/hooks/useRouteMatch.js\";\nimport { OutletProvider } from \"./outlet-provider.js\";\nimport { RouteComponent } from \"./route-component.js\";\nimport { RouteProvider } from \"./route-provider.js\";\n\nexport const Outlet = () => {\n const routeMatch = useRouteMatch();\n const depth = useOutlet() + 1;\n return (\n <OutletProvider depth={depth}>\n <RouteProvider route={routeMatch.matches.at(depth)}>\n <RouteComponent depth={depth} />\n </RouteProvider>\n </OutletProvider>\n );\n};\n","import { useCallback, useEffect, useState } from \"react\";\n\nimport { RouterContext } from \"@/context/router-context.js\";\nimport type {\n BackOptions,\n ForwardOptions,\n Location,\n NavigateOptions,\n RouterOptions,\n} from \"@/types.js\";\nimport { DefaultTransitionDuration, parseLocation } from \"@/utils.js\";\nimport { LocationProvider } from \"./location-provider.js\";\n\nexport const RouterProvider = ({\n options,\n ...props\n}: {\n options: RouterOptions;\n children: React.ReactNode;\n}) => {\n const [history, setHistory] = useState<Location[]>([\n parseLocation(window.location),\n ]);\n const [currentLocationIndex, setCurrentLocationIndex] = useState<number>(0);\n const location = history.at(currentLocationIndex)!;\n const [isTransitioning, setIsTransitioning] = useState<boolean>(false);\n const [transitionDuration, setTransitionDuration] = useState<number>(\n DefaultTransitionDuration\n );\n const [transitioningToIndex, setTransitioningToIndex] = useState<number>();\n\n useEffect(() => {\n window.history.replaceState(\n {\n index: 0,\n },\n \"\"\n );\n const handlePopState = ({ state }: PopStateEvent) => {\n setCurrentLocationIndex(state?.index ?? 0);\n };\n\n window.addEventListener(\"popstate\", handlePopState);\n return () => {\n window.removeEventListener(\"popstate\", handlePopState);\n };\n }, [setCurrentLocationIndex]);\n\n // Update location state\n const setLocationState = useCallback(\n (index: number, state: Record<string, any>) => {\n setHistory((prevHistory) =>\n prevHistory.map((location) =>\n location.index === index ? { ...location, state } : location\n )\n );\n if (index === currentLocationIndex) {\n window.history.replaceState(\n {\n index,\n ...state,\n },\n \"\",\n location.pathname\n );\n }\n },\n [currentLocationIndex]\n );\n\n const navigate = useCallback(\n ({\n to,\n replace,\n transition,\n duration,\n updateHistory = true,\n onFinish,\n ...locationOptions\n }: NavigateOptions) => {\n if (isTransitioning) return;\n\n const index = replace ? currentLocationIndex : currentLocationIndex + 1;\n\n // Resolve to with absolute or relative paths like \"..\" or \".\"\n let pathname: string;\n if (to.startsWith(\".\")) {\n const currentPathSegments = location.pathname\n .split(\"/\")\n .filter((seg) => seg.length > 0);\n const toPathSegments = to.split(\"/\").filter((seg) => seg.length > 0);\n for (const segment of toPathSegments) {\n if (segment.startsWith(\".\")) {\n if (segment === \".\") {\n continue;\n } else if (segment === \"..\") {\n currentPathSegments.pop();\n } else {\n throw new Error(\n `Invalid relative path segment: ${segment} in ${to}`\n );\n }\n } else if (segment.length > 0) {\n currentPathSegments.push(segment);\n }\n }\n pathname = \"/\" + currentPathSegments.join(\"/\");\n } else {\n pathname = to;\n }\n\n setHistory((prevHistory) => [\n ...(index === history.length ? history : prevHistory.slice(0, index)),\n {\n index,\n search: {},\n state: {},\n pathname,\n ...locationOptions,\n },\n ]);\n if (\n !replace &&\n currentLocationIndex >= 0 &&\n (transition ??\n options.defaultUseTransition?.(location, history.at(index)))\n ) {\n const currentDuration = duration ?? DefaultTransitionDuration;\n setIsTransitioning(true);\n setTransitionDuration(currentDuration);\n setTransitioningToIndex(index);\n setTimeout(() => {\n setIsTransitioning(false);\n setTransitioningToIndex(undefined);\n setCurrentLocationIndex(index);\n onFinish?.();\n if (updateHistory) {\n window.history.pushState(\n {\n index,\n },\n \"\",\n to\n );\n }\n }, currentDuration);\n } else if (!replace) {\n setCurrentLocationIndex(index);\n if (updateHistory) {\n window.history.pushState(\n {\n index,\n },\n \"\",\n to\n );\n }\n } else if (updateHistory) {\n window.history.replaceState(\n {\n index,\n },\n \"\",\n to\n );\n }\n },\n [currentLocationIndex, history, isTransitioning, options]\n );\n\n const back = useCallback(\n ({ transition, duration, onFinish, depth }: BackOptions = {}) => {\n if (currentLocationIndex === 0 || isTransitioning) return;\n const newLocationIndex = currentLocationIndex - (depth ?? 1);\n if (\n currentLocationIndex > 0 &&\n (transition ??\n options.defaultUseTransition?.(\n location,\n history.at(newLocationIndex)\n ))\n ) {\n const finalDuration = duration ?? DefaultTransitionDuration;\n setIsTransitioning(true);\n setTransitionDuration(finalDuration);\n setTransitioningToIndex(newLocationIndex);\n setTimeout(() => {\n setIsTransitioning(false);\n setTransitioningToIndex(undefined);\n setCurrentLocationIndex(newLocationIndex);\n onFinish?.();\n window.history.back();\n }, finalDuration);\n } else {\n setCurrentLocationIndex(newLocationIndex);\n onFinish?.();\n window.history.back();\n }\n },\n [currentLocationIndex, history, isTransitioning, options]\n );\n\n const forward = useCallback(\n ({ transition, duration, onFinish }: ForwardOptions = {}) => {\n if (currentLocationIndex + 1 >= history.length || isTransitioning) return;\n const newLocationIndex = currentLocationIndex + 1;\n if (\n newLocationIndex < history.length &&\n (transition ??\n options.defaultUseTransition?.(\n location,\n history.at(newLocationIndex)\n ))\n ) {\n const finalDuration = duration ?? DefaultTransitionDuration;\n setIsTransitioning(true);\n setTransitionDuration(finalDuration);\n setTransitioningToIndex(newLocationIndex);\n setTimeout(() => {\n setIsTransitioning(false);\n setTransitioningToIndex(undefined);\n setCurrentLocationIndex(newLocationIndex);\n onFinish?.();\n window.history.forward();\n }, finalDuration);\n } else {\n setCurrentLocationIndex(newLocationIndex);\n onFinish?.();\n window.history.forward();\n }\n },\n [currentLocationIndex, history, isTransitioning, options]\n );\n\n return (\n <RouterContext.Provider\n value={{\n options,\n\n history,\n location,\n canGoBack: currentLocationIndex > 0,\n canGoForward: currentLocationIndex < history.length - 1,\n\n isTransitioning,\n transitionDuration,\n transitioningToIndex,\n\n navigate,\n back,\n forward,\n\n setLocationState,\n }}\n >\n <LocationProvider location={location} {...props} />\n </RouterContext.Provider>\n );\n};\n","import type { RouterOptions } from \"./types.js\";\n\nexport const DefaultRouterOptions: RouterOptions = {\n defaultTransitionDuration: 300,\n};\n","import { DefaultRouterOptions } from \"./constants.js\";\nimport type {\n Location,\n ParsedRoute,\n Route,\n RouteMatch,\n RouterOptions,\n} from \"./types.js\";\n\nexport const DefaultTransitionDuration = 300;\n\nexport const redirect = (options: { to: string; replace?: boolean }) => {\n return new Error(\"\", { cause: options });\n};\n\n/**\n * @param pattern pathname pattern like `/users/:id`. Leading and trailing slashes are optional.\n * @param url URL to match against the pattern. Can be href or pathname with query string.\n * @returns extracted params and query if matched, otherwise null\n */\nexport const matchPattern = (\n pattern: string,\n url: string\n): { params: Record<string, string>; query: Record<string, string> } | null => {\n try {\n // 解析 URL\n let pathname, searchParams;\n\n if (url.startsWith(\"http://\") || url.startsWith(\"https://\")) {\n const urlObj = new URL(url);\n pathname = urlObj.pathname;\n searchParams = urlObj.searchParams;\n } else {\n // 處理相對路徑\n const [path, queryString] = url.split(\"?\");\n if (!path) {\n return null;\n }\n pathname = path;\n searchParams = new URLSearchParams(queryString || \"\");\n }\n\n // 移除路徑首尾的斜線以便比較\n const cleanPath = pathname.replaceAll(/^\\/|\\/$/g, \"\");\n const cleanPattern = pattern.replaceAll(/^\\/|\\/$/g, \"\");\n\n // 分割路徑段\n const pathSegments = cleanPath.split(\"/\");\n const patternSegments = cleanPattern.split(\"/\");\n\n // 路徑段數量不同則不匹配\n if (pathSegments.length !== patternSegments.length) {\n return null;\n }\n\n // 提取路徑參數\n const params: Record<string, string> = {};\n for (let i = 0; i < patternSegments.length; i++) {\n const patternSegment = patternSegments[i];\n const pathSegment = pathSegments[i];\n\n if (patternSegment.startsWith(\":\")) {\n // 動態參數\n const paramName = patternSegment.slice(1);\n params[paramName] = decodeURIComponent(pathSegment);\n } else if (patternSegment !== pathSegment) {\n // 靜態段不匹配\n return null;\n }\n }\n\n // 提取查詢參數\n const query = Object.fromEntries(searchParams.entries());\n\n return { params, query };\n } catch {\n return null;\n }\n};\n\nexport const matchRoute = (route: ParsedRoute, url: string): RouteMatch => {\n const _matchRoute = (\n matches: ParsedRoute[],\n { children }: ParsedRoute\n ): RouteMatch | null => {\n if (children && children.length > 0) {\n for (const childRoute of children) {\n const matchesResult = _matchRoute([...matches, childRoute], childRoute);\n if (matchesResult) {\n return matchesResult;\n }\n }\n return null;\n }\n\n const result = matchPattern(buildPathnameFromMatches(matches), url);\n return result ? { matches, ...result } : null;\n };\n\n return (\n _matchRoute([route], route) || {\n matches: [],\n params: {},\n query: {},\n }\n );\n};\n\nexport const buildPathnameFromMatches = (matches: Route[]): string => {\n let cleanedPathnames: string[] = []; // pathnames without leading/trailing slashes\n for (const match of matches) {\n if (match.pathname === undefined) continue;\n cleanedPathnames.push(match.pathname.replaceAll(/^\\/|\\/$/g, \"\"));\n }\n return \"/\" + cleanedPathnames.join(\"/\");\n};\n\nexport const parseLocation = (location: globalThis.Location): Location => ({\n index: 0,\n state: {},\n pathname: location.pathname,\n search: Object.fromEntries(new URLSearchParams(location.search)),\n});\n\nexport const createRouterOptions = (\n options?: RouterOptions\n): RouterOptions => ({\n ...DefaultRouterOptions,\n ...options,\n});\n\nexport const parseRoute = (route: Route): ParsedRoute => {\n const parseRouteRecursive = (route: Route, parentId: string): ParsedRoute => {\n const id =\n route.name ??\n (route.pathname\n ? `${parentId}/${route.pathname.replaceAll(/^\\/|\\/$/g, \"\")}`\n : parentId);\n\n const parsedRoute: ParsedRoute = {\n ...route,\n id,\n children: route.children?.map((child) => parseRouteRecursive(child, id)),\n };\n\n return parsedRoute;\n };\n return parseRouteRecursive(route, \"\");\n};\n","import { useEffect, useState } from \"react\";\n\nimport { useRouter } from \"@/hooks/useRouter.js\";\nimport type { Route } from \"@/types.js\";\n\nimport { LocationProvider } from \"./location-provider.js\";\nimport { PageRenderer } from \"./page-renderer.js\";\nimport { RootRouteProvider } from \"./root-route-provider.js\";\n\nconst StackComponent = () => {\n const {\n history,\n location,\n canGoBack,\n canGoForward,\n isTransitioning,\n transitioningToIndex,\n transitionDuration,\n back,\n forward,\n } = useRouter();\n const currentLocationIndex = location?.index;\n\n const [isDragging, setIsDragging] = useState(false);\n const [startX, setStartX] = useState(0);\n const [dragOffset, setDragOffset] = useState(0);\n const [isCanceling, setIsCanceling] = useState(false);\n const [isTransitionStarted, setIsTransitionStarted] = useState(false);\n\n useEffect(() => {\n if (!isTransitioning || transitioningToIndex === null) return;\n setIsTransitionStarted(true);\n setTimeout(() => {\n setIsTransitionStarted(false);\n }, transitionDuration);\n }, [isTransitioning, transitioningToIndex]);\n\n if (currentLocationIndex === undefined) return;\n\n const reset = () => {\n setIsDragging(false);\n setDragOffset(0);\n setIsCanceling(false);\n };\n\n const handleTouchStart = (e: React.TouchEvent) => {\n if (isTransitioning || (!canGoForward && !canGoBack)) return;\n setIsDragging(true);\n setStartX(e.touches[0].clientX);\n };\n\n const handleTouchMove = (e: React.TouchEvent) => {\n if (!isDragging) return;\n const offset = e.touches[0].clientX - startX;\n if (\n (offset > 0 && currentLocationIndex === 0) ||\n (offset < 0 && currentLocationIndex + 1 === history.length)\n ) {\n setDragOffset(0);\n return;\n }\n setDragOffset(Math.min(window.innerWidth, offset));\n };\n\n const handleTouchEnd = () => {\n if (!isDragging) return;\n\n if (dragOffset > window.innerWidth * 0.3 && canGoBack) {\n back({\n onFinish: reset,\n });\n } else if (dragOffset < -window.innerWidth * 0.3 && canGoForward) {\n forward({\n onFinish: reset,\n });\n } else {\n setIsCanceling(true);\n setTimeout(reset, transitionDuration);\n }\n };\n\n return (\n <div\n style={{\n position: \"relative\",\n inset: 0,\n height: \"100%\",\n width: \"100%\",\n overflow: \"hidden\",\n }}\n >\n {currentLocationIndex >= 1 &&\n ((isDragging && dragOffset > 0) ||\n (isTransitioning &&\n transitioningToIndex !== undefined &&\n transitioningToIndex < currentLocationIndex)) && (\n <div\n style={{\n position: \"absolute\",\n inset: 0,\n zIndex: -10,\n }}\n >\n <LocationProvider location={history.at(currentLocationIndex - 1)!}>\n <PageRenderer key={currentLocationIndex - 1} />\n </LocationProvider>\n </div>\n )}\n <div\n key={currentLocationIndex}\n style={{\n background: \"white\",\n position: \"absolute\",\n inset: 0,\n overflow: \"hidden\",\n transform:\n isTransitioning &&\n transitioningToIndex !== undefined &&\n transitioningToIndex < currentLocationIndex\n ? `translateX(100%)`\n : isDragging && dragOffset > 0 && !isCanceling\n ? `translateX(${dragOffset}px)`\n : \"translateX(0px)\",\n transition:\n isCanceling ||\n (isTransitioning &&\n transitioningToIndex !== undefined &&\n transitioningToIndex < currentLocationIndex)\n ? `transform ${transitionDuration}ms ease-out`\n : \"\",\n boxShadow:\n isDragging && dragOffset > 0\n ? \"-4px 0 8px rgba(0,0,0,0.1)\"\n : \"none\",\n }}\n onTouchStart={handleTouchStart}\n onTouchMove={handleTouchMove}\n onTouchEnd={handleTouchEnd}\n >\n <PageRenderer />\n </div>\n {((isDragging && dragOffset < 0) ||\n (isTransitioning &&\n transitioningToIndex !== undefined &&\n currentLocationIndex < transitioningToIndex)) && (\n <div\n key={transitioningToIndex}\n style={{\n background: \"white\",\n position: \"absolute\",\n inset: 0,\n zIndex: 10,\n overflow: \"hidden\",\n transition: \"transform ease-in\",\n transform: isTransitionStarted\n ? `translateX(0px)`\n : isDragging && !isCanceling\n ? `translateX(${window.innerWidth + dragOffset}px)`\n : \"translateX(100%)\",\n transitionDuration:\n isTransitioning || isCanceling\n ? `${transitionDuration}ms`\n : \"0ms\",\n }}\n >\n <LocationProvider\n location={\n isDragging\n ? history.at(currentLocationIndex + 1)!\n : history.at(transitioningToIndex!)!\n }\n >\n <PageRenderer key={transitioningToIndex} />\n </LocationProvider>\n </div>\n )}\n </div>\n );\n};\n\nexport const Stack = ({ rootRoute }: { rootRoute: Route }) => (\n <RootRouteProvider rootRoute={rootRoute}>\n <StackComponent />\n </RootRouteProvider>\n);\n","import { RouteMatchContext } from \"@/context/route-match-context.js\";\nimport { useLocation } from \"@/hooks/useLocation.js\";\nimport { useRootRoute } from \"@/hooks/useRootRoute.js\";\nimport { matchRoute } from \"@/utils.js\";\nimport { RouteComponent } from \"./route-component.js\";\nimport { RouteProvider } from \"./route-provider.js\";\n\nexport const PageRenderer = () => {\n const rootRoute = useRootRoute();\n const location = useLocation();\n const routeMatch = matchRoute(rootRoute, location.pathname);\n return (\n <RouteMatchContext.Provider value={routeMatch}>\n <RouteProvider route={rootRoute}>\n <RouteComponent />\n </RouteProvider>\n </RouteMatchContext.Provider>\n );\n};\n","import { RootRouteContext } from \"@/context/root-route-context.js\";\nimport type { Route } from \"@/types.js\";\nimport { parseRoute } from \"@/utils.js\";\nimport { useCallback, useState } from \"react\";\n\nexport const RootRouteProvider = ({\n rootRoute,\n ...props\n}: {\n rootRoute: Route;\n children: React.ReactNode;\n}) => {\n const parsedRoute = parseRoute(rootRoute);\n const [state, setState] = useState<Record<string, Record<string, any>>>({});\n\n const getRouteState = useCallback(\n (id: string, key: string) => {\n return state[id]?.[key];\n },\n [state]\n );\n\n const setRouteState = useCallback((id: string, key: string, value: any) => {\n setState((prevState) => ({\n ...prevState,\n [id]: {\n ...prevState[id],\n [key]: value,\n },\n }));\n }, []);\n\n return (\n <RootRouteContext.Provider\n value={{ ...parsedRoute, getRouteState, setRouteState }}\n {...props}\n />\n );\n};\n"],"mappings":"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","names":["useContext","createContext","RouterContext","useRouter","router","useContext","RouterContext","jsx","Link","to","replace","transition","duration","onFinish","props","router","useRouter","e","createContext","LocationContext","useCallback","jsx","LocationProvider","location","props","router","useRouter","getState","key","setState","value","deleteState","LocationContext","createContext","OutletContext","useContext","useOutlet","OutletContext","createContext","RouteMatchContext","useContext","useRouteMatch","routeMatch","RouteMatchContext","jsx","OutletProvider","depth","props","OutletContext","useContext","useLocation","context","useContext","LocationContext","createContext","RouteContext","useContext","useRoute","route","RouteContext","useEffect","useState","jsx","RouteComponent","depth","router","useRouter","location","useLocation","routeMatch","useRouteMatch","route","useRoute","pendingStateKey","pending","setPending","useState","useEffect","cause","NotFoundComponent","PendingComponent","Component","Outlet","useContext","createContext","RootRouteContext","useRootRoute","route","useContext","RootRouteContext","useCallback","jsx","RouteProvider","route","props","RouteContext","rootRoute","useRootRoute","getState","key","setState","value","jsx","Outlet","routeMatch","useRouteMatch","depth","useOutlet","OutletProvider","RouteProvider","RouteComponent","useCallback","useEffect","useState","DefaultRouterOptions","DefaultTransitionDuration","redirect","options","matchPattern","pattern","url","pathname","searchParams","urlObj","path","queryString","cleanPath","cleanPattern","pathSegments","patternSegments","params","i","patternSegment","pathSegment","paramName","query","matchRoute","route","_matchRoute","matches","children","childRoute","matchesResult","result","buildPathnameFromMatches","cleanedPathnames","match","parseLocation","location","createRouterOptions","DefaultRouterOptions","parseRoute","parseRouteRecursive","parentId","id","child","jsx","RouterProvider","options","props","history","setHistory","useState","parseLocation","currentLocationIndex","setCurrentLocationIndex","location","isTransitioning","setIsTransitioning","transitionDuration","setTransitionDuration","DefaultTransitionDuration","transitioningToIndex","setTransitioningToIndex","useEffect","handlePopState","state","setLocationState","useCallback","index","prevHistory","navigate","to","replace","transition","duration","updateHistory","onFinish","locationOptions","pathname","currentPathSegments","seg","toPathSegments","segment","currentDuration","back","depth","newLocationIndex","finalDuration","forward","RouterContext","LocationProvider","useEffect","useState","jsx","PageRenderer","rootRoute","useRootRoute","location","useLocation","routeMatch","matchRoute","RouteMatchContext","RouteProvider","RouteComponent","useCallback","useState","jsx","RootRouteProvider","rootRoute","props","parsedRoute","parseRoute","state","setState","getRouteState","id","key","setRouteState","value","prevState","RootRouteContext","jsx","jsxs","StackComponent","history","location","canGoBack","canGoForward","isTransitioning","transitioningToIndex","transitionDuration","back","forward","useRouter","currentLocationIndex","isDragging","setIsDragging","useState","startX","setStartX","dragOffset","setDragOffset","isCanceling","setIsCanceling","isTransitionStarted","setIsTransitionStarted","useEffect","reset","handleTouchStart","e","handleTouchMove","offset","handleTouchEnd","LocationProvider","PageRenderer","Stack","rootRoute","RootRouteProvider"]}
1
+ {"version":3,"sources":["../src/hooks/useRouter.ts","../src/context/router-context.ts","../src/components/link.tsx","../src/context/location-context.ts","../src/components/location-provider.tsx","../src/context/outlet-context.ts","../src/hooks/useOutlet.ts","../src/context/route-match-context.ts","../src/hooks/useRouteMatch.ts","../src/components/outlet-provider.tsx","../src/hooks/useLocation.ts","../src/context/route-context.ts","../src/hooks/useRoute.ts","../src/components/route-component.tsx","../src/hooks/useRootRoute.ts","../src/context/root-route-context.ts","../src/components/route-provider.tsx","../src/components/outlet.tsx","../src/components/router-provider.tsx","../src/constants.ts","../src/utils.ts","../src/components/stack.tsx","../src/components/page-renderer.tsx","../src/components/root-route-provider.tsx"],"sourcesContent":["import { useContext } from \"react\";\n\nimport { RouterContext } from \"@/context/router-context.js\";\n\nexport const useRouter = () => {\n const router = useContext(RouterContext);\n if (router === null) {\n throw new Error(\"useRouter must be used within a Stack\");\n }\n return router;\n};\n","import { createContext } from \"react\";\n\nimport type {\n BackOptions,\n ForwardOptions,\n Location,\n NavigateOptions,\n RouterOptions,\n} from \"@/types.js\";\n\nexport interface RouterContextType {\n // Router Config\n options: RouterOptions;\n\n // Navigation State\n history: Location[];\n location?: Location;\n canGoBack: boolean;\n canGoForward: boolean;\n\n // Transition state\n isTransitioning: boolean;\n transitionDuration: number;\n transitioningToLocation?: Location;\n\n // Actions\n navigate: (options: NavigateOptions) => void;\n back: (options?: BackOptions) => void;\n forward: (options?: ForwardOptions) => void;\n\n // Low-level state action\n setLocationState: (index: number, state: Record<string, any>) => void;\n}\n\nexport const RouterContext = createContext<RouterContextType | null>(null);\n","import { useRouter } from \"@/hooks/useRouter.js\";\nimport type { NavigateOptions } from \"@/types.js\";\n\nexport type LinkProps = React.ComponentPropsWithoutRef<\"a\"> & NavigateOptions;\n\nexport const Link: React.FC<LinkProps> = ({\n to,\n replace,\n transition,\n duration,\n onFinish,\n ...props\n}) => {\n const router = useRouter();\n return (\n <a\n {...props}\n href={to}\n onClick={(e) => {\n e.preventDefault();\n router.navigate({ to, replace, transition, duration, onFinish });\n }}\n />\n );\n};\n","import { createContext } from \"react\";\n\nimport type { Location } from \"@/types.js\";\n\nexport interface LocationContextType extends Location {\n canGoBack: boolean;\n canGoForward: boolean;\n getState: (key: string) => any;\n setState: (key: string, value: any) => void;\n deleteState: (key: string) => void;\n}\n\nexport const LocationContext = createContext<LocationContextType | null>(null);\n","import { LocationContext } from \"@/context/location-context.js\";\nimport { useRouter } from \"@/hooks/useRouter.js\";\nimport type { Location } from \"@/types.js\";\nimport { useCallback } from \"react\";\n\nexport const LocationProvider = ({\n location,\n ...props\n}: {\n location: Location;\n children: React.ReactNode;\n}) => {\n const router = useRouter();\n const getState = useCallback(\n (key: string) => {\n return location.state[key];\n },\n [location]\n );\n const setState = useCallback(\n (key: string, value: any) => {\n router.setLocationState(location.index, {\n ...location.state,\n [key]: value,\n });\n },\n [router, location]\n );\n const deleteState = useCallback(\n (key: string) => {\n delete location.state[key];\n router.setLocationState(location.index, location.state);\n },\n [router, location]\n );\n return (\n <LocationContext.Provider\n value={{\n ...location,\n canGoBack: location.index > 0,\n canGoForward: location.index < router.history.length - 1,\n getState,\n setState,\n deleteState,\n }}\n {...props}\n />\n );\n};\n","import { createContext } from \"react\";\n\nexport const OutletContext = createContext<number>(0);\n","import { OutletContext } from \"@/context/outlet-context.js\";\nimport { useContext } from \"react\";\n\nexport const useOutlet = () => useContext(OutletContext);\n","import type { RouteMatch } from \"@/types.js\";\nimport { createContext } from \"react\";\n\nexport const RouteMatchContext = createContext<RouteMatch | null>(null);\n","import { RouteMatchContext } from \"@/context/route-match-context.js\";\nimport { useContext } from \"react\";\n\nexport const useRouteMatch = () => {\n const routeMatch = useContext(RouteMatchContext);\n if (routeMatch === null) {\n throw new Error(\"useRouteMatch must be used within a RouteMatchProvider\");\n }\n return routeMatch;\n};\n","import { OutletContext } from \"@/context/outlet-context.js\";\n\nexport const OutletProvider = ({\n depth,\n ...props\n}: {\n depth: number;\n children?: React.ReactNode;\n}) => <OutletContext.Provider value={depth} {...props} />;\n","import { useContext } from \"react\";\n\nimport { LocationContext } from \"@/context/location-context.js\";\n\nexport const useLocation = () => {\n const context = useContext(LocationContext);\n if (context === null) {\n throw new Error(\"useLocation must be used within a LocationProvider\");\n }\n return context;\n};\n","import type { ParsedRoute } from \"@/types.js\";\nimport { createContext } from \"react\";\n\nexport interface RouteContextType extends ParsedRoute {\n getState: (key: string) => any;\n setState: (key: string, value: any) => void;\n}\n\nexport const RouteContext = createContext<RouteContextType | null>(null);\n","import { RouteContext } from \"@/context/route-context.js\";\nimport { useContext } from \"react\";\n\nexport const useRoute = () => {\n const route = useContext(RouteContext);\n if (route === null) {\n throw new Error(\"useRoute must be used within a RouteProvider\");\n }\n return route;\n};\n","import { useLocation } from \"@/hooks/useLocation.js\";\nimport { useRoute } from \"@/hooks/useRoute.js\";\nimport { useRouteMatch } from \"@/hooks/useRouteMatch.js\";\nimport { useRouter } from \"@/hooks/useRouter.js\";\nimport { useEffect, useState } from \"react\";\nimport { Outlet } from \"./outlet.js\";\n\nexport const RouteComponent = ({ depth = 0 }: { depth?: number }) => {\n const router = useRouter();\n const location = useLocation();\n const routeMatch = useRouteMatch();\n const route = useRoute();\n\n const pendingStateKey = `_Z.${route.id}.pending`;\n\n const [pending, setPending] = useState(\n !!route?.beforeLoad && route?.getState(pendingStateKey) !== false\n );\n\n useEffect(() => {\n if (!route || depth >= routeMatch.matches.length) {\n return;\n }\n // TODO: push location still loading. Maybe store state in route () instead of location\n if (pending && route?.beforeLoad) {\n route.setState(pendingStateKey, true);\n route\n .beforeLoad({ location })\n .catch(({ cause }: Error) => {\n if (\"to\" in (cause as any)) {\n router.navigate(cause as any);\n }\n })\n .finally(() => {\n route.setState(pendingStateKey, false);\n setPending(false);\n });\n }\n }, []);\n\n if (!route) {\n return null;\n }\n\n if (depth >= routeMatch.matches.length) {\n const NotFoundComponent = route.notFoundComponent!;\n return <NotFoundComponent />;\n }\n\n if (pending) {\n const PendingComponent = route.pendingComponent!;\n return <PendingComponent />;\n }\n\n const Component = route.component;\n return Component ? <Component /> : <Outlet />;\n};\n","import { useContext } from \"react\";\n\nimport { RootRouteContext } from \"@/context/root-route-context.js\";\n\nexport const useRootRoute = () => {\n const route = useContext(RootRouteContext);\n if (route === null) {\n throw new Error(\"useRootRoute must be used within a RootRouteProvider\");\n }\n return route;\n};\n","import { createContext } from \"react\";\n\nimport type { ParsedRoute } from \"@/types.js\";\n\nexport interface RootRouteContextType extends ParsedRoute {\n getRouteState: (id: string, key: string) => any;\n setRouteState: (id: string, key: string, value: any) => void;\n}\n\nexport const RootRouteContext = createContext<RootRouteContextType | null>(\n null\n);\n","import { RouteContext } from \"@/context/route-context.js\";\nimport { useRootRoute } from \"@/hooks/useRootRoute.js\";\nimport type { ParsedRoute } from \"@/types.js\";\nimport { useCallback } from \"react\";\n\nexport const RouteProvider = ({\n route,\n ...props\n}: {\n route?: ParsedRoute;\n children?: React.ReactNode;\n}) => {\n if (!route) {\n return <RouteContext.Provider value={null} {...props} />;\n }\n\n const rootRoute = useRootRoute();\n\n const getState = useCallback(\n (key: string) => {\n return rootRoute.getRouteState(route.id, key);\n },\n [rootRoute.getRouteState]\n );\n\n const setState = useCallback(\n (key: string, value: any) => {\n rootRoute.setRouteState(route.id, key, value);\n },\n [rootRoute.setRouteState]\n );\n\n return (\n <RouteContext.Provider\n value={{ ...route, getState, setState }}\n {...props}\n />\n );\n};\n","import { useOutlet } from \"@/hooks/useOutlet.js\";\nimport { useRouteMatch } from \"@/hooks/useRouteMatch.js\";\nimport { OutletProvider } from \"./outlet-provider.js\";\nimport { RouteComponent } from \"./route-component.js\";\nimport { RouteProvider } from \"./route-provider.js\";\n\nexport const Outlet = () => {\n const routeMatch = useRouteMatch();\n const depth = useOutlet() + 1;\n return (\n <OutletProvider depth={depth}>\n <RouteProvider route={routeMatch.matches.at(depth)}>\n <RouteComponent depth={depth} />\n </RouteProvider>\n </OutletProvider>\n );\n};\n","import { useCallback, useEffect, useState } from \"react\";\n\nimport { RouterContext } from \"@/context/router-context.js\";\nimport type {\n BackOptions,\n ForwardOptions,\n Location,\n NavigateOptions,\n RouterOptions,\n} from \"@/types.js\";\nimport { parseLocation } from \"@/utils.js\";\nimport { LocationProvider } from \"./location-provider.js\";\n\nexport const RouterProvider = ({\n options,\n ...props\n}: {\n options: RouterOptions;\n children: React.ReactNode;\n}) => {\n const [history, setHistory] = useState<Location[]>([\n parseLocation(window.location),\n ]);\n const [currentLocationIndex, setCurrentLocationIndex] = useState<number>(0);\n const location = history.at(currentLocationIndex)!;\n const [isTransitioning, setIsTransitioning] = useState<boolean>(false);\n const [transitionDuration, setTransitionDuration] = useState<number>(0);\n const [transitioningToLocation, setTransitioningToLocation] =\n useState<Location>();\n\n useEffect(() => {\n window.history.replaceState(history[0].state, \"\", history[0].pathname);\n const handlePopState = ({ state }: PopStateEvent) => {\n setCurrentLocationIndex(state?.index ?? 0);\n };\n\n addEventListener(\"popstate\", handlePopState);\n return () => {\n removeEventListener(\"popstate\", handlePopState);\n };\n }, []);\n\n const transitionTo = (\n location: Location,\n duration: number = options.defaultTransitionDuration,\n callback?: () => void\n ) => {\n setIsTransitioning(true);\n setTransitionDuration(duration);\n setTransitioningToLocation(location);\n setTimeout(() => {\n setIsTransitioning(false);\n setTransitioningToLocation(undefined);\n // TODO: May can be deleted\n setCurrentLocationIndex(location.index);\n callback?.();\n }, duration);\n };\n\n // Update location state\n const setLocationState = useCallback(\n (index: number, state: Record<string, any>) => {\n setHistory((prevHistory) =>\n prevHistory.map((location) =>\n location.index === index ? { ...location, state } : location\n )\n );\n if (index === currentLocationIndex) {\n window.history.replaceState(state, \"\", location.pathname);\n }\n },\n [currentLocationIndex]\n );\n\n const navigate = useCallback(\n ({\n to,\n replace,\n transition,\n duration,\n onFinish,\n ...locationOptions\n }: NavigateOptions) => {\n if (isTransitioning) return;\n\n const index = replace ? currentLocationIndex : currentLocationIndex + 1;\n\n // Resolve to with absolute or relative paths like \"..\" or \".\"\n // TODO: Wrap into a utility function\n let pathname: string;\n if (to.startsWith(\"/\")) {\n pathname = to;\n } else {\n const currentPathSegments = location.pathname\n .split(\"/\")\n .filter((seg) => seg.length > 0);\n const toPathSegments = to.split(\"/\").filter((seg) => seg.length > 0);\n for (const segment of toPathSegments) {\n if (segment === \".\") {\n continue;\n } else if (segment === \"..\") {\n currentPathSegments.pop();\n } else {\n currentPathSegments.push(segment);\n }\n }\n pathname = \"/\" + currentPathSegments.join(\"/\");\n }\n const state = {\n index,\n };\n const newLocation = {\n index,\n search: {},\n state,\n pathname,\n ...locationOptions,\n };\n\n const updateHistory = () => {\n if (replace) {\n setHistory((prevHistory) => [\n ...prevHistory.slice(0, index),\n newLocation,\n ...prevHistory.slice(index + 1),\n ]);\n window.history.replaceState(state, \"\", pathname);\n } else {\n setHistory((prevHistory) => [\n ...prevHistory.slice(0, index),\n newLocation,\n ]);\n setCurrentLocationIndex(index);\n window.history.pushState(state, \"\", pathname);\n }\n onFinish?.();\n };\n\n if (transition ?? options.defaultUseTransition?.(location, newLocation)) {\n transitionTo(newLocation, duration, updateHistory);\n } else {\n updateHistory();\n }\n },\n [currentLocationIndex, history, isTransitioning, options]\n );\n\n const back = useCallback(\n ({ transition, duration, onFinish, depth }: BackOptions = {}) => {\n if (currentLocationIndex === 0 || isTransitioning) return;\n const backDepth = depth ?? 1;\n const newLocation = history.at(currentLocationIndex - backDepth);\n\n const updateHistory = () => {\n window.history.go(-backDepth);\n onFinish?.();\n };\n\n if (\n newLocation &&\n (transition ?? options.defaultUseTransition?.(location, newLocation))\n ) {\n transitionTo(newLocation, duration, updateHistory);\n } else {\n updateHistory();\n }\n },\n [currentLocationIndex, history, isTransitioning, options]\n );\n\n const forward = useCallback(\n ({ transition, duration, depth, onFinish }: ForwardOptions = {}) => {\n if (currentLocationIndex + 1 >= history.length || isTransitioning) return;\n const forwardDepth = depth ?? 1;\n const newLocation = history.at(currentLocationIndex + forwardDepth);\n\n const updateHistory = () => {\n window.history.go(forwardDepth);\n onFinish?.();\n };\n\n if (\n newLocation &&\n (transition ?? options.defaultUseTransition?.(location, newLocation))\n ) {\n transitionTo(newLocation, duration, updateHistory);\n } else {\n updateHistory();\n }\n },\n [currentLocationIndex, history, isTransitioning, options]\n );\n\n return (\n <RouterContext.Provider\n value={{\n options,\n\n history,\n location,\n canGoBack: currentLocationIndex > 0,\n canGoForward: currentLocationIndex < history.length - 1,\n\n isTransitioning,\n transitionDuration,\n transitioningToLocation,\n\n navigate,\n back,\n forward,\n\n setLocationState,\n }}\n >\n <LocationProvider location={location} {...props} />\n </RouterContext.Provider>\n );\n};\n","import type { RouterOptions } from \"./types.js\";\n\nexport const DefaultRouterOptions: RouterOptions = {\n defaultTransitionDuration: 300,\n};\n","import { DefaultRouterOptions } from \"./constants.js\";\nimport type {\n Location,\n ParsedRoute,\n Route,\n RouteMatch,\n RouterOptions,\n} from \"./types.js\";\n\nexport const DefaultTransitionDuration = 300;\n\nexport const redirect = (options: { to: string; replace?: boolean }) => {\n return new Error(\"\", { cause: options });\n};\n\n/**\n * @param pattern pathname pattern like `/users/:id`. Leading and trailing slashes are optional.\n * @param url URL to match against the pattern. Can be href or pathname with query string.\n * @returns extracted params and query if matched, otherwise null\n */\nexport const matchPattern = (\n pattern: string,\n url: string\n): { params: Record<string, string>; query: Record<string, string> } | null => {\n try {\n // 解析 URL\n let pathname, searchParams;\n\n if (url.startsWith(\"http://\") || url.startsWith(\"https://\")) {\n const urlObj = new URL(url);\n pathname = urlObj.pathname;\n searchParams = urlObj.searchParams;\n } else {\n // 處理相對路徑\n const [path, queryString] = url.split(\"?\");\n if (!path) {\n return null;\n }\n pathname = path;\n searchParams = new URLSearchParams(queryString || \"\");\n }\n\n // 移除路徑首尾的斜線以便比較\n const cleanPath = pathname.replaceAll(/^\\/|\\/$/g, \"\");\n const cleanPattern = pattern.replaceAll(/^\\/|\\/$/g, \"\");\n\n // 分割路徑段\n const pathSegments = cleanPath.split(\"/\");\n const patternSegments = cleanPattern.split(\"/\");\n\n // 路徑段數量不同則不匹配\n if (pathSegments.length !== patternSegments.length) {\n return null;\n }\n\n // 提取路徑參數\n const params: Record<string, string> = {};\n for (let i = 0; i < patternSegments.length; i++) {\n const patternSegment = patternSegments[i];\n const pathSegment = pathSegments[i];\n\n if (patternSegment.startsWith(\":\")) {\n // 動態參數\n const paramName = patternSegment.slice(1);\n params[paramName] = decodeURIComponent(pathSegment);\n } else if (patternSegment !== pathSegment) {\n // 靜態段不匹配\n return null;\n }\n }\n\n // 提取查詢參數\n const query = Object.fromEntries(searchParams.entries());\n\n return { params, query };\n } catch {\n return null;\n }\n};\n\nexport const matchRoute = (route: ParsedRoute, url: string): RouteMatch => {\n const _matchRoute = (\n matches: ParsedRoute[],\n { children }: ParsedRoute\n ): RouteMatch | null => {\n if (children && children.length > 0) {\n for (const childRoute of children) {\n const matchesResult = _matchRoute([...matches, childRoute], childRoute);\n if (matchesResult) {\n return matchesResult;\n }\n }\n return null;\n }\n\n const result = matchPattern(buildPathnameFromMatches(matches), url);\n return result ? { matches, ...result } : null;\n };\n\n return (\n _matchRoute([route], route) || {\n matches: [],\n params: {},\n query: {},\n }\n );\n};\n\nexport const buildPathnameFromMatches = (matches: Route[]): string => {\n let cleanedPathnames: string[] = []; // pathnames without leading/trailing slashes\n for (const match of matches) {\n if (match.pathname === undefined) continue;\n cleanedPathnames.push(match.pathname.replaceAll(/^\\/|\\/$/g, \"\"));\n }\n return \"/\" + cleanedPathnames.join(\"/\");\n};\n\nexport const parseLocation = (location: globalThis.Location): Location => ({\n index: 0,\n state: {\n index: 0,\n },\n pathname: location.pathname,\n search: Object.fromEntries(new URLSearchParams(location.search)),\n});\n\nexport const createRouterOptions = (\n options?: Partial<RouterOptions>\n): RouterOptions => ({\n ...DefaultRouterOptions,\n ...options,\n});\n\nexport const parseRoute = (route: Route): ParsedRoute => {\n const parseRouteRecursive = (route: Route, parentId: string): ParsedRoute => {\n const id =\n route.name ??\n (route.pathname\n ? `${parentId}/${route.pathname.replaceAll(/^\\/|\\/$/g, \"\")}`\n : parentId);\n\n const parsedRoute: ParsedRoute = {\n ...route,\n id,\n children: route.children?.map((child) => parseRouteRecursive(child, id)),\n };\n\n return parsedRoute;\n };\n return parseRouteRecursive(route, \"\");\n};\n","import { useEffect, useState } from \"react\";\n\nimport { useRouter } from \"@/hooks/useRouter.js\";\nimport type { Route } from \"@/types.js\";\n\nimport { LocationProvider } from \"./location-provider.js\";\nimport { PageRenderer } from \"./page-renderer.js\";\nimport { RootRouteProvider } from \"./root-route-provider.js\";\n\nconst StackComponent = () => {\n const {\n history,\n location,\n canGoBack,\n canGoForward,\n isTransitioning,\n transitioningToLocation,\n transitionDuration,\n back,\n forward,\n } = useRouter();\n const currentLocationIndex = location?.index;\n const transitioningToLocationIndex = transitioningToLocation?.index;\n\n const [isDragging, setIsDragging] = useState(false);\n const [startX, setStartX] = useState(0);\n const [dragOffset, setDragOffset] = useState(0);\n const [isCanceling, setIsCanceling] = useState(false);\n const [isTransitionStarted, setIsTransitionStarted] = useState(false);\n\n useEffect(() => {\n if (!isTransitioning || !transitioningToLocation) return;\n setIsTransitionStarted(true);\n setTimeout(() => {\n setIsTransitionStarted(false);\n }, transitionDuration);\n }, [isTransitioning, transitioningToLocation]);\n\n if (currentLocationIndex === undefined) return;\n\n const reset = () => {\n setIsDragging(false);\n setDragOffset(0);\n setIsCanceling(false);\n };\n\n const handleTouchStart = (e: React.TouchEvent) => {\n if (isTransitioning || (!canGoForward && !canGoBack)) return;\n setIsDragging(true);\n setStartX(e.touches[0].clientX);\n };\n\n const handleTouchMove = (e: React.TouchEvent) => {\n if (!isDragging) return;\n const offset = e.touches[0].clientX - startX;\n if (\n (offset > 0 && currentLocationIndex === 0) ||\n (offset < 0 && currentLocationIndex + 1 === history.length)\n ) {\n setDragOffset(0);\n return;\n }\n setDragOffset(Math.min(innerWidth, offset));\n };\n\n const handleTouchEnd = () => {\n if (!isDragging) return;\n\n if (dragOffset > innerWidth * 0.3 && canGoBack) {\n back({\n onFinish: reset,\n });\n } else if (dragOffset < -innerWidth * 0.3 && canGoForward) {\n forward({\n onFinish: reset,\n });\n } else {\n setIsCanceling(true);\n setTimeout(reset, transitionDuration);\n }\n };\n\n return (\n <div\n style={{\n position: \"relative\",\n inset: 0,\n height: \"100%\",\n width: \"100%\",\n overflow: \"hidden\",\n }}\n >\n {currentLocationIndex >= 1 &&\n ((isDragging && dragOffset > 0) ||\n (isTransitioning &&\n transitioningToLocation &&\n transitioningToLocation.index < currentLocationIndex)) && (\n <div\n style={{\n position: \"absolute\",\n inset: 0,\n zIndex: -10,\n }}\n >\n <LocationProvider location={history.at(currentLocationIndex - 1)!}>\n <PageRenderer key={currentLocationIndex - 1} />\n </LocationProvider>\n </div>\n )}\n <div\n key={currentLocationIndex}\n style={{\n background: \"white\",\n position: \"absolute\",\n inset: 0,\n overflow: \"hidden\",\n transform:\n isTransitioning &&\n transitioningToLocation &&\n transitioningToLocation.index < currentLocationIndex\n ? `translateX(100%)`\n : isDragging && dragOffset > 0 && !isCanceling\n ? `translateX(${dragOffset}px)`\n : \"translateX(0px)\",\n transition:\n isCanceling ||\n (isTransitioning &&\n transitioningToLocation &&\n transitioningToLocation.index < currentLocationIndex)\n ? `transform ${transitionDuration}ms ease-out`\n : \"\",\n boxShadow:\n isDragging && dragOffset > 0\n ? \"-4px 0 8px rgba(0,0,0,0.1)\"\n : \"none\",\n }}\n onTouchStart={handleTouchStart}\n onTouchMove={handleTouchMove}\n onTouchEnd={handleTouchEnd}\n >\n <PageRenderer />\n </div>\n {((isDragging && dragOffset < 0) ||\n (isTransitioning &&\n transitioningToLocation &&\n currentLocationIndex <= transitioningToLocation.index)) && (\n <div\n style={{\n background: \"white\",\n position: \"absolute\",\n inset: 0,\n zIndex: 10,\n overflow: \"hidden\",\n transition: \"transform ease-in\",\n transform: isTransitionStarted\n ? `translateX(0px)`\n : isTransitioning\n ? \"translateX(100%)\"\n : `translateX(${innerWidth + dragOffset}px)`,\n transitionDuration:\n isTransitioning || isCanceling\n ? `${transitionDuration}ms`\n : \"0ms\",\n }}\n >\n <LocationProvider\n location={\n isTransitioning\n ? transitioningToLocation!\n : history.at(currentLocationIndex + 1)!\n }\n >\n <PageRenderer key={transitioningToLocationIndex} />\n </LocationProvider>\n </div>\n )}\n </div>\n );\n};\n\nexport const Stack = ({ rootRoute }: { rootRoute: Route }) => (\n <RootRouteProvider rootRoute={rootRoute}>\n <StackComponent />\n </RootRouteProvider>\n);\n","import { RouteMatchContext } from \"@/context/route-match-context.js\";\nimport { useLocation } from \"@/hooks/useLocation.js\";\nimport { useRootRoute } from \"@/hooks/useRootRoute.js\";\nimport { matchRoute } from \"@/utils.js\";\nimport { RouteComponent } from \"./route-component.js\";\nimport { RouteProvider } from \"./route-provider.js\";\n\nexport const PageRenderer = () => {\n const rootRoute = useRootRoute();\n const location = useLocation();\n const routeMatch = matchRoute(rootRoute, location.pathname);\n return (\n <RouteMatchContext.Provider value={routeMatch}>\n <RouteProvider route={rootRoute}>\n <RouteComponent />\n </RouteProvider>\n </RouteMatchContext.Provider>\n );\n};\n","import { RootRouteContext } from \"@/context/root-route-context.js\";\nimport type { Route } from \"@/types.js\";\nimport { parseRoute } from \"@/utils.js\";\nimport { useCallback, useState } from \"react\";\n\nexport const RootRouteProvider = ({\n rootRoute,\n ...props\n}: {\n rootRoute: Route;\n children: React.ReactNode;\n}) => {\n const parsedRoute = parseRoute(rootRoute);\n const [state, setState] = useState<Record<string, Record<string, any>>>({});\n\n const getRouteState = useCallback(\n (id: string, key: string) => {\n return state[id]?.[key];\n },\n [state]\n );\n\n const setRouteState = useCallback((id: string, key: string, value: any) => {\n setState((prevState) => ({\n ...prevState,\n [id]: {\n ...prevState[id],\n [key]: value,\n },\n }));\n }, []);\n\n return (\n <RootRouteContext.Provider\n value={{ ...parsedRoute, getRouteState, setRouteState }}\n {...props}\n />\n );\n};\n"],"mappings":"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","names":["useContext","createContext","RouterContext","useRouter","router","useContext","RouterContext","jsx","Link","to","replace","transition","duration","onFinish","props","router","useRouter","e","createContext","LocationContext","useCallback","jsx","LocationProvider","location","props","router","useRouter","getState","key","setState","value","deleteState","LocationContext","createContext","OutletContext","useContext","useOutlet","OutletContext","createContext","RouteMatchContext","useContext","useRouteMatch","routeMatch","RouteMatchContext","jsx","OutletProvider","depth","props","OutletContext","useContext","useLocation","context","useContext","LocationContext","createContext","RouteContext","useContext","useRoute","route","RouteContext","useEffect","useState","jsx","RouteComponent","depth","router","useRouter","location","useLocation","routeMatch","useRouteMatch","route","useRoute","pendingStateKey","pending","setPending","useState","useEffect","cause","NotFoundComponent","PendingComponent","Component","Outlet","useContext","createContext","RootRouteContext","useRootRoute","route","useContext","RootRouteContext","useCallback","jsx","RouteProvider","route","props","RouteContext","rootRoute","useRootRoute","getState","key","setState","value","jsx","Outlet","routeMatch","useRouteMatch","depth","useOutlet","OutletProvider","RouteProvider","RouteComponent","useCallback","useEffect","useState","DefaultRouterOptions","DefaultTransitionDuration","redirect","options","matchPattern","pattern","url","pathname","searchParams","urlObj","path","queryString","cleanPath","cleanPattern","pathSegments","patternSegments","params","i","patternSegment","pathSegment","paramName","query","matchRoute","route","_matchRoute","matches","children","childRoute","matchesResult","result","buildPathnameFromMatches","cleanedPathnames","match","parseLocation","location","createRouterOptions","DefaultRouterOptions","parseRoute","parseRouteRecursive","parentId","id","child","jsx","RouterProvider","options","props","history","setHistory","useState","parseLocation","currentLocationIndex","setCurrentLocationIndex","location","isTransitioning","setIsTransitioning","transitionDuration","setTransitionDuration","transitioningToLocation","setTransitioningToLocation","useEffect","handlePopState","state","transitionTo","duration","callback","setLocationState","useCallback","index","prevHistory","navigate","to","replace","transition","onFinish","locationOptions","pathname","currentPathSegments","seg","toPathSegments","segment","newLocation","updateHistory","back","depth","backDepth","forward","forwardDepth","RouterContext","LocationProvider","useEffect","useState","jsx","PageRenderer","rootRoute","useRootRoute","location","useLocation","routeMatch","matchRoute","RouteMatchContext","RouteProvider","RouteComponent","useCallback","useState","jsx","RootRouteProvider","rootRoute","props","parsedRoute","parseRoute","state","setState","getRouteState","id","key","setRouteState","value","prevState","RootRouteContext","jsx","jsxs","StackComponent","history","location","canGoBack","canGoForward","isTransitioning","transitioningToLocation","transitionDuration","back","forward","useRouter","currentLocationIndex","transitioningToLocationIndex","isDragging","setIsDragging","useState","startX","setStartX","dragOffset","setDragOffset","isCanceling","setIsCanceling","isTransitionStarted","setIsTransitionStarted","useEffect","reset","handleTouchStart","e","handleTouchMove","offset","handleTouchEnd","LocationProvider","PageRenderer","Stack","rootRoute","RootRouteProvider"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@modastar/z-router",
3
- "version": "0.0.7",
3
+ "version": "0.0.8",
4
4
  "description": "",
5
5
  "keywords": [],
6
6
  "homepage": "https://github.com/xLanStar/z-router#readme",