@typeroute/router 0.11.0 → 0.11.2
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.d.ts +14 -14
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -107,8 +107,8 @@ type ComponentLoader = () => Promise<ComponentType | {
|
|
|
107
107
|
}>;
|
|
108
108
|
//#endregion
|
|
109
109
|
//#region src/route.d.ts
|
|
110
|
-
declare
|
|
111
|
-
declare
|
|
110
|
+
declare const route: <P extends string>(pattern: P) => Route<NormalizePath<P>, ParsePattern<NormalizePath<P>>, {}>;
|
|
111
|
+
declare const middleware: () => Middleware<{}>;
|
|
112
112
|
declare class Route<P extends string = string, Ps extends {} = any, S extends {} = any> implements Middleware<S> {
|
|
113
113
|
readonly _: {
|
|
114
114
|
pattern: P;
|
|
@@ -193,24 +193,24 @@ declare class HashHistory extends BrowserHistory {
|
|
|
193
193
|
type RouterRootProps = RouterOptions | {
|
|
194
194
|
router: Router;
|
|
195
195
|
};
|
|
196
|
-
declare
|
|
197
|
-
declare
|
|
196
|
+
declare const RouterRoot: (props: RouterRootProps) => ReactNode;
|
|
197
|
+
declare const Outlet: () => ReactNode;
|
|
198
198
|
type NavigateProps<P extends Pattern> = NavigateOptions<P>;
|
|
199
|
-
declare
|
|
199
|
+
declare const Navigate: <P extends Pattern>(props: NavigateProps<P>) => null;
|
|
200
200
|
type LinkProps<P extends Pattern> = NavigateOptions<P> & LinkOptions & AnchorHTMLAttributes<HTMLAnchorElement> & RefAttributes<HTMLAnchorElement> & {
|
|
201
201
|
asChild?: boolean;
|
|
202
202
|
};
|
|
203
|
-
declare
|
|
203
|
+
declare const Link: <P extends Pattern>(props: LinkProps<P>) => ReactNode;
|
|
204
204
|
//#endregion
|
|
205
205
|
//#region src/react/hooks.d.ts
|
|
206
|
-
declare
|
|
207
|
-
declare
|
|
208
|
-
declare
|
|
209
|
-
declare
|
|
210
|
-
declare
|
|
211
|
-
declare
|
|
212
|
-
declare
|
|
213
|
-
declare
|
|
206
|
+
declare const useRouter: () => Router;
|
|
207
|
+
declare const useLocation: () => HistoryLocation;
|
|
208
|
+
declare const useMatch: <P extends Pattern>(options: MatchOptions<P>) => Match<P> | null;
|
|
209
|
+
declare const useOutlet: () => ReactNode;
|
|
210
|
+
declare const useNavigate: () => <P extends Pattern>(options: number | HistoryPushOptions | NavigateOptions<P>) => void;
|
|
211
|
+
declare const useHandles: () => Handle[];
|
|
212
|
+
declare const useParams: <P extends Pattern>(from: P | GetRoute<P>) => Params<P>;
|
|
213
|
+
declare const useSearch: <P extends Pattern>(from: P | GetRoute<P>) => readonly [Search<P>, (update: Updater<Search<P>>, replace?: boolean) => void];
|
|
214
214
|
//#endregion
|
|
215
215
|
//#region src/react/contexts.d.ts
|
|
216
216
|
declare const RouterContext: react.Context<Router | null>;
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Component as e,Suspense as t,cloneElement as n,createContext as r,isValidElement as i,lazy as a,memo as o,
|
|
1
|
+
import{Component as e,Suspense as t,cloneElement as n,createContext as r,isValidElement as i,lazy as a,memo as o,useContext as s,useEffect as ee,useInsertionEffect as c,useLayoutEffect as l,useMemo as u,useRef as d,useState as f,useSyncExternalStore as p}from"react";import{inject as m,parse as h}from"regexparam";import{jsx as g}from"react/jsx-runtime";const _=e=>`/${e}`.replaceAll(/\/+/g,`/`).replace(/(.+)\/$/,`$1`),v=e=>{let{keys:t,pattern:n}=h(e);return{pattern:e,keys:t,regex:n,loose:h(e,!0).pattern,weights:e.split(`/`).slice(1).map(e=>e.includes(`*`)?0:e.includes(`:`)?1:2)}},y=e=>typeof e==`function`?e:t=>{let n=e[`~standard`].validate(t);if(n instanceof Promise)throw Error(`[TypeRoute] Validation can't be async`);if(n.issues)throw Error(`[TypeRoute] Validation failed`,{cause:n.issues});return n.value},b=e=>Object.entries(e).filter(([e,t])=>t!==void 0).map(([e,t])=>`${e}=${encodeURIComponent(S(t))}`).join(`&`),x=e=>{let t={};return new URLSearchParams(e).forEach((e,n)=>{t[n]=C(e)?JSON.parse(e):e}),t},S=e=>typeof e==`string`&&!C(e)?e:JSON.stringify(e),C=e=>{try{return JSON.parse(e),!0}catch{return!1}},w=(e,t)=>_(`${t}/${e}`),T=(e,t)=>((e===t||e.startsWith(`${t}/`))&&(e=e.slice(t.length)||`/`),e),E=(e,t)=>[e,b(t)].filter(Boolean).join(`?`),D=e=>{let{pathname:t,search:n}=new URL(e,`http://w`);return{path:t,search:x(n)}},O=({keys:e,regex:t,loose:n},r,i,a)=>{let o=(r?t:n).exec(T(i,a));if(!o)return null;let s={};return e.forEach((e,t)=>{let n=o[t+1];n&&(s[e]=n)}),s},k=e=>[...e].sort((e,t)=>{let n=e.route._.weights,r=t.route._.weights,i=Math.max(n.length,r.length);for(let e=0;e<i;e++){let t=n[e]??-1,i=r[e]??-1;if(t!==i)return i-t}return 0}),A=r(null),j=r(null),M=r(null),N=r(null),P=()=>{let e=s(A);if(e)return e;throw Error(`[TypeRoute] useRouter must be within a router context`)},F=()=>{let e=s(j);if(e)return e;throw Error(`[TypeRoute] useLocation must be within a router context`)},I=e=>{let t=P(),{path:n}=F();return u(()=>t.match(n,e),[t,n,e.from,e.strict,e.params])},L=()=>s(N),R=()=>P().navigate,z=()=>{let e=s(M);return u(()=>e?.route._.handles??[],[e])},B=e=>{let t=I({from:e});if(t)return t.params;throw Error(`[TypeRoute] Can't read params for non-matching route ${e}`)},V=e=>{let t=P(),{search:n,path:r}=F(),i=t.getRoute(e),a=u(()=>i._.validate(n),[i,n]);return[a,Z((e,n)=>{e=typeof e==`function`?e(a):e;let i=E(r,{...a,...e});t.navigate({url:i,replace:n})})]};var H=class{_loc=(e,t)=>{let{state:n}=history,[r,i]=this._??[];return i?.path===e&&r===t&&i.state===n?i:(this._=[t,{path:e,search:x(t),state:n}])[1]};constructor(){if(!window[U]){for(let e of[W,G]){let t=history[e];history[e]=function(...n){t.apply(this,n),dispatchEvent(new Event(e))}}window[U]=1}}location=()=>this._loc(location.pathname,location.search);go=e=>history.go(e);push=e=>{let{url:t,replace:n,state:r}=e;history[n?G:W](r,``,t)};subscribe=e=>(K.forEach(t=>addEventListener(t,e)),()=>{K.forEach(t=>removeEventListener(t,e))})};const U=Symbol.for(`wmp01`),W=`pushState`,G=`replaceState`,K=[`popstate`,W,G,`hashchange`];var q=class{constructor(e){let{routes:t,basePath:n=`/`,history:r,context:i,ssrContext:a,defaultLinkOptions:o}=e;this.routes=Object.values(t),this.basePath=_(n),this.history=r??new H,this.context=i,this.ssrContext=a,this.defaultLinkOptions=o,this._=new Map(this.routes.map(e=>[e._.pattern,e]))}getRoute=e=>{if(typeof e!=`string`)return e;let t=this._.get(e);if(!t)throw Error(`[TypeRoute] Route not found for ${e}`);return t};match=(e,t)=>{let{from:n,strict:r,params:i}=t,a=this.getRoute(n),o=O(a._,r,e,this.basePath);return o&&(!i||Object.keys(i).every(e=>i[e]===o[e]))?{route:a,params:o}:null};matchAll=e=>k(this.routes.map(t=>this.match(e,{from:t,strict:!0})).filter(e=>!!e))[0]??null;createUrl=e=>{let{to:t,params:n={},search:r={}}=e,{pattern:i}=this.getRoute(t)._;return E(w(m(i,n),this.basePath),r)};preload=async e=>{let{to:t,params:n={},search:r={}}=e,{preloads:i}=this.getRoute(t)._;await Promise.all(i.map(e=>e({params:n,search:r,context:this.context})))};navigate=e=>{if(typeof e==`number`)this.history.go(e);else if(`url`in e)this.history.push(e);else{let{replace:t,state:n}=e;this.history.push({url:this.createUrl(e),replace:t,state:n})}}},J=class{stack=[];index=0;listeners=new Set;constructor(e=`/`){this.stack.push({...D(e),state:void 0})}location=()=>this.stack[this.index];go=e=>{let t=this.index+e;this.stack[t]&&(this.index=t,this.listeners.forEach(e=>e()))};push=e=>{let{url:t,replace:n,state:r}=e,i={...D(t),state:r};this.stack=this.stack.slice(0,this.index+1),n?this.stack[this.index]=i:this.index=this.stack.push(i)-1,this.listeners.forEach(e=>e())};subscribe=e=>(this.listeners.add(e),()=>{this.listeners.delete(e)})},Y=class extends H{location=()=>{let{pathname:e,search:t}=new URL(location.hash.slice(1),`http://w`);return this._loc(e,t)};push=e=>{let{url:t,replace:n,state:r}=e;history[n?`replaceState`:`pushState`](r,``,`#${t}`)}};const X=e=>{let[t]=f(()=>`router`in e?e.router:new q(e)),{subscribe:n,location:r}=t.history,i=p(n,r,r),a=u(()=>t.matchAll(i.path),[t,i.path]);return a||console.error(`[TypeRoute] No matching route for path`,i.path),u(()=>g(A.Provider,{value:t,children:g(j.Provider,{value:i,children:g(M.Provider,{value:a,children:a?.route._.components.reduceRight((e,t)=>g(N.Provider,{value:e,children:g(t,{})}),null)})})}),[t,i,a])},te=()=>L(),ne=e=>{let t=P();return l(()=>t.navigate(e),[]),t.ssrContext&&(t.ssrContext.redirect=t.createUrl(e)),null},re=e=>{let t=P(),{to:r,replace:a,state:o,params:s,search:c,strict:l,preload:u,preloadDelay:f=50,style:p,className:m,activeStyle:h,activeClassName:_,asChild:v,children:y,...b}={...t.defaultLinkOptions,...e},x=d(null),S=d(null),C=t.createUrl(e),w=!!I({from:r,strict:l,params:s}),T=Z(()=>{clearTimeout(S.current)}),E=Z(()=>{T(),S.current=setTimeout(()=>t.preload(e),f)});ee(()=>{if(u===`render`)E();else if(u===`viewport`&&x.current){let e=new IntersectionObserver(e=>e.forEach(e=>{e.isIntersecting?E():T()}));return e.observe(x.current),()=>{e.disconnect(),T()}}return T},[u]);let D=e=>{b.onClick?.(e),!(e.ctrlKey||e.metaKey||e.shiftKey||e.altKey||e.button||e.defaultPrevented)&&(e.preventDefault(),t.navigate({url:C,replace:a,state:o}))},O=(e,t)=>n=>{t?.(n),u===`intent`&&!n.defaultPrevented&&e()},k={...b,ref:ie(x,b.ref),href:C,onClick:D,onFocus:O(E,b.onFocus),onBlur:O(T,b.onBlur),onPointerEnter:O(E,b.onPointerEnter),onPointerLeave:O(T,b.onPointerLeave),"data-active":w,style:{...p,...w&&h},className:[m,w&&_].filter(Boolean).join(` `)||void 0};return v&&i(y)?n(y,k):g(`a`,{...k,children:y})},ie=(e,t)=>t?n=>{e.current=n;let r=typeof t==`function`?t(n):void(t.current=n);return r&&(()=>{e.current=null,r()})}:e,Z=e=>{let t=d(e);return c(()=>{t.current=e},[e]),d(((...e)=>t.current(...e))).current},ae=e=>()=>L()??g(e,{}),oe=e=>()=>g(t,{fallback:g(e,{}),children:L()}),se=t=>{class n extends e{state={...this.props};static getDerivedStateFromError(e){return{error:[e]}}static getDerivedStateFromProps(e,t){return e.children===t.children?t:{...e,error:void 0}}render(){return this.state.error?g(t,{error:this.state.error[0]}):this.props.children}}return()=>g(n,{children:L()})},Q=e=>new $({...v(_(e)),validate:e=>e,handles:[],components:[],preloads:[]}),ce=()=>Q(``);var $=class e{constructor(e){this._=e}route=t=>new e({...this._,...v(_(`${this._.pattern}/${t}`)),p:this});use=t=>{let{_:n}=t;return new e({...this._,handles:[...this._.handles,...n.handles],components:[...this._.components,...n.components],preloads:[...this._.preloads,...n.preloads]}).search(n.validate)};search=t=>(t=y(t),new e({...this._,validate:e=>{let n=this._.validate(e);return{...n,...t({...e,...n})}}}));handle=t=>new e({...this._,handles:[...this._.handles,t]});preload=t=>new e({...this._,preloads:[...this._.preloads,e=>t({...e,search:this._.validate(e.search)})]});component=t=>new e({...this._,components:[...this._.components,o(t)]});index=e=>this.component(ae(e));lazy=e=>this.preload(e).component(a(()=>e().then(e=>`default`in e?e:{default:e})));suspense=e=>this.component(oe(e));error=e=>this.component(se(e));toString=()=>this._.pattern};export{H as BrowserHistory,Y as HashHistory,re as Link,j as LocationContext,M as MatchContext,J as MemoryHistory,ne as Navigate,te as Outlet,N as OutletContext,$ as Route,q as Router,A as RouterContext,X as RouterRoot,ce as middleware,Q as route,z as useHandles,F as useLocation,I as useMatch,R as useNavigate,L as useOutlet,B as useParams,P as useRouter,V as useSearch};
|