waymark 0.2.3 → 0.3.0
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/README.md +463 -251
- package/dist/index.d.ts +80 -79
- package/dist/index.js +1 -1
- package/package.json +5 -5
package/dist/index.d.ts
CHANGED
|
@@ -19,12 +19,23 @@ type RouteList = Register extends {
|
|
|
19
19
|
type Handle = Register extends {
|
|
20
20
|
handle: infer Handle;
|
|
21
21
|
} ? Handle : any;
|
|
22
|
+
interface PreloadContext<R extends Route = Route> {
|
|
23
|
+
params: R["_types"]["params"];
|
|
24
|
+
search: R["_types"]["search"];
|
|
25
|
+
}
|
|
26
|
+
interface RouterOptions {
|
|
27
|
+
basePath?: string;
|
|
28
|
+
routes: RouteList;
|
|
29
|
+
history?: HistoryLike;
|
|
30
|
+
ssrContext?: SSRContext;
|
|
31
|
+
defaultLinkOptions?: LinkOptions;
|
|
32
|
+
}
|
|
22
33
|
type Pattern = RouteList[number]["pattern"];
|
|
23
34
|
type GetRoute<P extends Pattern> = Extract<RouteList[number], {
|
|
24
35
|
pattern: P;
|
|
25
36
|
}>;
|
|
26
|
-
type Params<P extends Pattern> =
|
|
27
|
-
type Search<P extends Pattern> =
|
|
37
|
+
type Params<P extends Pattern> = GetRoute<P>["_types"]["params"];
|
|
38
|
+
type Search<P extends Pattern> = GetRoute<P>["_types"]["search"];
|
|
28
39
|
type MatchOptions<P extends Pattern> = {
|
|
29
40
|
from: P | GetRoute<P>;
|
|
30
41
|
strict?: boolean;
|
|
@@ -39,6 +50,15 @@ type NavigateOptions<P extends Pattern> = {
|
|
|
39
50
|
replace?: boolean;
|
|
40
51
|
state?: any;
|
|
41
52
|
} & MaybeKey<"params", Params<P>> & MaybeKey<"search", Search<P>>;
|
|
53
|
+
interface LinkOptions {
|
|
54
|
+
strict?: boolean;
|
|
55
|
+
preload?: "intent" | "render" | "viewport" | false;
|
|
56
|
+
preloadDelay?: number;
|
|
57
|
+
style?: CSSProperties;
|
|
58
|
+
className?: string;
|
|
59
|
+
activeStyle?: CSSProperties;
|
|
60
|
+
activeClassName?: string;
|
|
61
|
+
}
|
|
42
62
|
type SSRContext = {
|
|
43
63
|
redirect?: string;
|
|
44
64
|
statusCode?: number;
|
|
@@ -65,83 +85,35 @@ type ComponentLoader = () => Promise<ComponentType | {
|
|
|
65
85
|
declare function route<P extends string>(pattern: P): Route<NormalizePath<P>, regexparam0.RouteParams<NormalizePath<P>> extends infer T ? { [KeyType in keyof T]: T[KeyType] } : never, {}>;
|
|
66
86
|
declare class Route<P extends string = string, Ps extends {} = any, S extends {} = any> {
|
|
67
87
|
readonly pattern: P;
|
|
88
|
+
readonly _types: {
|
|
89
|
+
params: Ps;
|
|
90
|
+
search: S;
|
|
91
|
+
};
|
|
68
92
|
readonly _: {
|
|
69
|
-
_params?: Ps;
|
|
70
|
-
_search?: S;
|
|
71
93
|
keys: string[];
|
|
72
94
|
regex: RegExp;
|
|
73
95
|
looseRegex: RegExp;
|
|
74
96
|
weights: number[];
|
|
75
|
-
|
|
97
|
+
validate: (search: Record<string, unknown>) => S;
|
|
76
98
|
handles: Handle[];
|
|
77
99
|
components: ComponentType[];
|
|
78
|
-
|
|
79
|
-
preloaders: (() => Promise<any>)[];
|
|
100
|
+
preloads: ((context: PreloadContext) => Promise<any>)[];
|
|
80
101
|
};
|
|
81
|
-
constructor(pattern: P,
|
|
82
|
-
route<P2 extends string>(
|
|
83
|
-
search<S2 extends {}>(
|
|
84
|
-
handle(handle: Handle)
|
|
85
|
-
|
|
86
|
-
component(component: ComponentType)
|
|
87
|
-
lazy(loader: ComponentLoader)
|
|
88
|
-
suspense(fallback: ComponentType)
|
|
89
|
-
error(fallback: ComponentType<{
|
|
102
|
+
constructor(pattern: P, _: typeof this._);
|
|
103
|
+
route: <P2 extends string>(pattern: P2) => Route<NormalizePath<`${P}/${P2}`>, regexparam0.RouteParams<NormalizePath<`${P}/${P2}`>> extends infer T ? { [KeyType in keyof T]: T[KeyType] } : never, S>;
|
|
104
|
+
search: <S2 extends {}>(validate: ((search: S & Record<string, unknown>) => S2) | StandardSchemaV1<Record<string, unknown>, S2>) => Route<P, Ps, (type_fest0.PickIndexSignature<S> extends infer T_1 ? { [Key in keyof T_1 as Key extends keyof type_fest0.PickIndexSignature<{ [K in keyof S2 as undefined extends S2[K] ? never : K]: S2[K] } & { [K_1 in keyof S2 as undefined extends S2[K_1] ? K_1 : never]?: S2[K_1] | undefined } extends infer T_2 ? { [KeyType_1 in keyof T_2]: T_2[KeyType_1] } : never> ? never : Key]: T_1[Key] } : never) & type_fest0.PickIndexSignature<{ [K in keyof S2 as undefined extends S2[K] ? never : K]: S2[K] } & { [K_1 in keyof S2 as undefined extends S2[K_1] ? K_1 : never]?: S2[K_1] | undefined } extends infer T_2 ? { [KeyType_1 in keyof T_2]: T_2[KeyType_1] } : never> & (type_fest0.OmitIndexSignature<S> extends infer T_3 ? { [Key_1 in keyof T_3 as Key_1 extends keyof type_fest0.OmitIndexSignature<{ [K in keyof S2 as undefined extends S2[K] ? never : K]: S2[K] } & { [K_1 in keyof S2 as undefined extends S2[K_1] ? K_1 : never]?: S2[K_1] | undefined } extends infer T_4 ? { [KeyType_1 in keyof T_4]: T_4[KeyType_1] } : never> ? never : Key_1]: T_3[Key_1] } : never) & type_fest0.OmitIndexSignature<{ [K in keyof S2 as undefined extends S2[K] ? never : K]: S2[K] } & { [K_1 in keyof S2 as undefined extends S2[K_1] ? K_1 : never]?: S2[K_1] | undefined } extends infer T_4 ? { [KeyType_1 in keyof T_4]: T_4[KeyType_1] } : never> extends infer T ? { [KeyType in keyof T]: T[KeyType] } : never>;
|
|
105
|
+
handle: (handle: Handle) => Route<P, Ps, S>;
|
|
106
|
+
preload: (preload: (context: PreloadContext<this>) => Promise<any>) => Route<P, Ps, S>;
|
|
107
|
+
component: (component: ComponentType) => Route<P, Ps, S>;
|
|
108
|
+
lazy: (loader: ComponentLoader) => Route<P, Ps, S>;
|
|
109
|
+
suspense: (fallback: ComponentType) => Route<P, Ps, S>;
|
|
110
|
+
error: (fallback: ComponentType<{
|
|
90
111
|
error: unknown;
|
|
91
|
-
}>)
|
|
92
|
-
|
|
93
|
-
toString(): P;
|
|
112
|
+
}>) => Route<P, Ps, S>;
|
|
113
|
+
toString: () => P;
|
|
94
114
|
}
|
|
95
115
|
//#endregion
|
|
96
|
-
//#region src/react/components.d.ts
|
|
97
|
-
type RouterRootProps = RouterOptions | {
|
|
98
|
-
router: Router;
|
|
99
|
-
};
|
|
100
|
-
declare function RouterRoot(props: RouterRootProps): ReactNode;
|
|
101
|
-
declare function Outlet(): ReactNode;
|
|
102
|
-
type NavigateProps<P extends Pattern> = NavigateOptions<P>;
|
|
103
|
-
declare function Navigate<P extends Pattern>(props: NavigateProps<P>): null;
|
|
104
|
-
type LinkProps<P extends Pattern> = NavigateOptions<P> & LinkOptions & AnchorHTMLAttributes<HTMLAnchorElement> & RefAttributes<HTMLAnchorElement> & {
|
|
105
|
-
asChild?: boolean;
|
|
106
|
-
};
|
|
107
|
-
interface LinkOptions {
|
|
108
|
-
strict?: boolean;
|
|
109
|
-
preload?: "intent" | "render" | "viewport" | false;
|
|
110
|
-
style?: CSSProperties;
|
|
111
|
-
className?: string;
|
|
112
|
-
activeStyle?: CSSProperties;
|
|
113
|
-
activeClassName?: string;
|
|
114
|
-
}
|
|
115
|
-
declare function Link<P extends Pattern>(props: LinkProps<P>): ReactNode;
|
|
116
|
-
//#endregion
|
|
117
|
-
//#region src/react/hooks.d.ts
|
|
118
|
-
declare function useRouter(): Router;
|
|
119
|
-
declare function useHandles(): Handle[];
|
|
120
|
-
declare function useOutlet(): react2.ReactNode;
|
|
121
|
-
declare function useSubscribe<T>(router: Router, getSnapshot: () => T): T;
|
|
122
|
-
declare function useNavigate(): <P extends Pattern>(options: number | HistoryPushOptions | NavigateOptions<P>) => void;
|
|
123
|
-
declare function useLocation(): {
|
|
124
|
-
path: string;
|
|
125
|
-
search: Record<string, unknown>;
|
|
126
|
-
state: any;
|
|
127
|
-
};
|
|
128
|
-
declare function useMatch<P extends Pattern>(options: MatchOptions<P>): Match<P> | null;
|
|
129
|
-
declare function useParams<P extends Pattern>(from: P | GetRoute<P>): Params<P>;
|
|
130
|
-
declare function useSearch<P extends Pattern>(from: P | GetRoute<P>): readonly [Search<P>, (update: Updater<Search<P>>, replace?: boolean) => void];
|
|
131
|
-
//#endregion
|
|
132
|
-
//#region src/react/contexts.d.ts
|
|
133
|
-
declare const RouterContext: react2.Context<Router | null>;
|
|
134
|
-
declare const MatchContext: react2.Context<Match | null>;
|
|
135
|
-
declare const OutletContext: react2.Context<ReactNode>;
|
|
136
|
-
//#endregion
|
|
137
116
|
//#region src/router/router.d.ts
|
|
138
|
-
interface RouterOptions {
|
|
139
|
-
basePath?: string;
|
|
140
|
-
routes: RouteList;
|
|
141
|
-
history?: HistoryLike;
|
|
142
|
-
ssrContext?: SSRContext;
|
|
143
|
-
defaultLinkOptions?: LinkOptions;
|
|
144
|
-
}
|
|
145
117
|
declare class Router {
|
|
146
118
|
readonly basePath: string;
|
|
147
119
|
readonly routes: RouteList;
|
|
@@ -150,16 +122,17 @@ declare class Router {
|
|
|
150
122
|
readonly defaultLinkOptions?: LinkOptions;
|
|
151
123
|
private readonly _;
|
|
152
124
|
constructor(options: RouterOptions);
|
|
153
|
-
getRoute<P extends Pattern>(pattern: P | GetRoute<P>)
|
|
154
|
-
match<P extends Pattern>(path: string, options: MatchOptions<P>)
|
|
155
|
-
matchAll(path: string)
|
|
156
|
-
createUrl<P extends Pattern>(options: NavigateOptions<P>)
|
|
157
|
-
|
|
125
|
+
getRoute: <P extends Pattern>(pattern: P | GetRoute<P>) => GetRoute<P>;
|
|
126
|
+
match: <P extends Pattern>(path: string, options: MatchOptions<P>) => Match<P> | null;
|
|
127
|
+
matchAll: (path: string) => Match | null;
|
|
128
|
+
createUrl: <P extends Pattern>(options: NavigateOptions<P>) => string;
|
|
129
|
+
preload: <P extends Pattern>(options: NavigateOptions<P>) => Promise<void>;
|
|
130
|
+
navigate: <P extends Pattern>(options: NavigateOptions<P> | HistoryPushOptions | number) => void;
|
|
158
131
|
}
|
|
159
132
|
//#endregion
|
|
160
133
|
//#region src/router/browser-history.d.ts
|
|
161
134
|
declare class BrowserHistory implements HistoryLike {
|
|
162
|
-
private static
|
|
135
|
+
private static patch;
|
|
163
136
|
private memo?;
|
|
164
137
|
constructor();
|
|
165
138
|
protected getSearchMemo: (search: string) => Record<string, unknown>;
|
|
@@ -172,11 +145,6 @@ declare class BrowserHistory implements HistoryLike {
|
|
|
172
145
|
}
|
|
173
146
|
//#endregion
|
|
174
147
|
//#region src/router/memory-history.d.ts
|
|
175
|
-
interface MemoryLocation {
|
|
176
|
-
path: string;
|
|
177
|
-
search: Record<string, unknown>;
|
|
178
|
-
state: any;
|
|
179
|
-
}
|
|
180
148
|
declare class MemoryHistory implements HistoryLike {
|
|
181
149
|
private stack;
|
|
182
150
|
private index;
|
|
@@ -199,4 +167,37 @@ declare class HashHistory extends BrowserHistory {
|
|
|
199
167
|
push: (options: HistoryPushOptions) => void;
|
|
200
168
|
}
|
|
201
169
|
//#endregion
|
|
202
|
-
|
|
170
|
+
//#region src/react/components.d.ts
|
|
171
|
+
type RouterRootProps = RouterOptions | {
|
|
172
|
+
router: Router;
|
|
173
|
+
};
|
|
174
|
+
declare function RouterRoot(props: RouterRootProps): ReactNode;
|
|
175
|
+
declare function Outlet(): ReactNode;
|
|
176
|
+
type NavigateProps<P extends Pattern> = NavigateOptions<P>;
|
|
177
|
+
declare function Navigate<P extends Pattern>(props: NavigateProps<P>): null;
|
|
178
|
+
type LinkProps<P extends Pattern> = NavigateOptions<P> & LinkOptions & AnchorHTMLAttributes<HTMLAnchorElement> & RefAttributes<HTMLAnchorElement> & {
|
|
179
|
+
asChild?: boolean;
|
|
180
|
+
};
|
|
181
|
+
declare function Link<P extends Pattern>(props: LinkProps<P>): ReactNode;
|
|
182
|
+
//#endregion
|
|
183
|
+
//#region src/react/hooks.d.ts
|
|
184
|
+
declare function useRouter(): Router;
|
|
185
|
+
declare function useNavigate(): <P extends Pattern>(options: number | HistoryPushOptions | NavigateOptions<P>) => void;
|
|
186
|
+
declare function useLocation(): {
|
|
187
|
+
path: string;
|
|
188
|
+
search: Record<string, unknown>;
|
|
189
|
+
state: any;
|
|
190
|
+
};
|
|
191
|
+
declare function useOutlet(): react2.ReactNode;
|
|
192
|
+
declare function useParams<P extends Pattern>(from: P | GetRoute<P>): Params<P>;
|
|
193
|
+
declare function useSearch<P extends Pattern>(from: P | GetRoute<P>): readonly [Search<P>, (update: Updater<Search<P>>, replace?: boolean) => void];
|
|
194
|
+
declare function useMatch<P extends Pattern>(options: MatchOptions<P>): Match<P> | null;
|
|
195
|
+
declare function useHandles(): Handle[];
|
|
196
|
+
declare function useSubscribe<T>(router: Router, getSnapshot: () => T): T;
|
|
197
|
+
//#endregion
|
|
198
|
+
//#region src/react/contexts.d.ts
|
|
199
|
+
declare const RouterContext: react2.Context<Router | null>;
|
|
200
|
+
declare const MatchContext: react2.Context<Match | null>;
|
|
201
|
+
declare const OutletContext: react2.Context<ReactNode>;
|
|
202
|
+
//#endregion
|
|
203
|
+
export { BrowserHistory, ComponentLoader, GetRoute, Handle, HashHistory, HistoryLike, HistoryPushOptions, Link, LinkOptions, LinkProps, Match, MatchContext, MatchOptions, MemoryHistory, Navigate, NavigateOptions, NavigateProps, Outlet, OutletContext, Params, Pattern, PreloadContext, Register, Route, RouteList, Router, RouterContext, RouterOptions, RouterRoot, RouterRootProps, SSRContext, Search, Updater, route, useHandles, useLocation, useMatch, useNavigate, useOutlet, useParams, useRouter, useSearch, useSubscribe };
|
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,useCallback as s,useContext as c,useEffect as
|
|
1
|
+
import{Component as e,Suspense as t,cloneElement as n,createContext as r,isValidElement as i,lazy as a,memo as o,useCallback as s,useContext as c,useEffect as l,useInsertionEffect as u,useLayoutEffect as d,useMemo as f,useRef as p,useState as m,useSyncExternalStore as h}from"react";import{inject as g,parse as _}from"regexparam";import{jsx as v}from"react/jsx-runtime";function y(e){return`/${e}`.replaceAll(/\/+/g,`/`).replace(/(.+)\/$/,`$1`)}function b(e){let{keys:t,pattern:n}=_(e);return{keys:t,regex:n,looseRegex:_(e,!0).pattern,weights:e.split(`/`).slice(1).map(e=>e.includes(`*`)?0:e.includes(`:`)?1:2)}}function x(e){return typeof e==`function`?e:t=>{let n=e[`~standard`].validate(t);if(n instanceof Promise)throw Error(`[Waymark] Validation must be synchronous`);if(n.issues)throw Error(`[Waymark] Validation failed`,{cause:n.issues});return n.value}}function S(e){return Object.entries(e).filter(([e,t])=>t!==void 0).map(([e,t])=>`${e}=${encodeURIComponent(w(t))}`).join(`&`)}function C(e){let t=new URLSearchParams(e);return Object.fromEntries([...t.entries()].map(([e,t])=>(t=decodeURIComponent(t),[e,T(t)?JSON.parse(t):t])))}function w(e){return typeof e==`string`&&!T(e)?e:JSON.stringify(e)}function T(e){try{return JSON.parse(e),!0}catch{return!1}}function E(e,t){return y(`${t}/${e}`)}function D(e,t){return(e===t||e.startsWith(`${t}/`))&&(e=e.slice(t.length)||`/`),e}function O(e,t){return[e,S(t)].filter(Boolean).join(`?`)}function k(e){let{pathname:t,search:n}=new URL(e,`http://w`);return{path:t,search:C(n)}}function A(e,t,n,r){let i=e.exec(D(n,r));if(!i)return null;let a={};return t.forEach((e,t)=>{let n=i[t+1];n&&(a[e]=n)}),a}function j(e){return[...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})}const M=r(null),N=r(null),P=r(null);function F(){let e=c(M);if(!e)throw Error(`[Waymark] useRouter must be used within a router context`);return e}function I(){return F().navigate}function L(){let e=F(),t=U(e,e.history.getPath),n=U(e,e.history.getSearch),r=U(e,e.history.getState);return f(()=>({path:t,search:n,state:r}),[t,n,r])}function R(){return c(P)}function z(e){let t=V({from:e});if(!t)throw Error(`[Waymark] Can't read params for non-matching route: ${e}`);return t.params}function B(e){let t=F(),n=t.getRoute(e),r=U(t,t.history.getSearch),i=f(()=>n._.validate(r),[n,r]);return[i,Q((e,n)=>{e=typeof e==`function`?e(i):e;let r={...i,...e},a=O(t.history.getPath(),r);t.navigate({url:a,replace:n})})]}function V(e){let t=F(),n=U(t,t.history.getPath);return f(()=>t.match(n,e),[t,n,e])}function H(){let e=c(N);return f(()=>e?.route._.handles??[],[e])}function U(e,t){return h(e.history.subscribe,t,t)}var W=class e{static patch=Symbol.for(`wmbhp01`);memo;constructor(){if(typeof history<`u`&&!(e.patch in window)){for(let e of[G,K]){let t=history[e];history[e]=function(...n){let r=t.apply(this,n),i=new Event(e);return i.arguments=n,dispatchEvent(i),r}}window[e.patch]=!0}}getSearchMemo=e=>this.memo?.search===e?this.memo.parsed:(this.memo={search:e,parsed:C(e)}).parsed;getPath=()=>location.pathname;getSearch=()=>this.getSearchMemo(location.search);getState=()=>history.state;go=e=>history.go(e);push=e=>{let{url:t,replace:n,state:r}=e;history[n?K:G](r,``,t)};subscribe=e=>(q.forEach(t=>window.addEventListener(t,e)),()=>{q.forEach(t=>window.removeEventListener(t,e))})};const G=`pushState`,K=`replaceState`,q=[`popstate`,G,K,`hashchange`];var J=class{basePath;routes;history;ssrContext;defaultLinkOptions;_;constructor(e){let{basePath:t=`/`,routes:n,history:r,ssrContext:i,defaultLinkOptions:a}=e;this.basePath=y(t),this.routes=n,this.history=r??new W,this.ssrContext=i,this.defaultLinkOptions=a,this._={routeMap:new Map(n.map(e=>[e.pattern,e]))}}getRoute=e=>{if(typeof e!=`string`)return e;let t=this._.routeMap.get(e);if(!t)throw Error(`[Waymark] Route not found for pattern: ${e}`);return t};match=(e,t)=>{let{from:n,strict:r,params:i}=t,a=this.getRoute(n),o=A(r?a._.regex:a._.looseRegex,a._.keys,e,this.basePath);return!o||i&&Object.keys(i).some(e=>i[e]!==o[e])?null:{route:a,params:o}};matchAll=e=>j(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 O(E(g(i,n),this.basePath),r)};preload=async e=>{let{to:t,params:n={},search:r={}}=e,i=this.getRoute(t);await Promise.all(i._.preloads.map(e=>e({params:n,search:r})))};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})}}},Y=class{stack=[];index=0;listeners=new Set;constructor(e=`/`){this.stack.push({...k(e),state:void 0})}getCurrent=()=>this.stack[this.index];getPath=()=>this.getCurrent().path;getSearch=()=>this.getCurrent().search;getState=()=>this.getCurrent().state;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={...k(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)})},X=class extends W{getHashUrl=()=>new URL(location.hash.slice(1),`http://w`);getPath=()=>this.getHashUrl().pathname;getSearch=()=>this.getSearchMemo(this.getHashUrl().search);push=e=>{let{url:t,replace:n,state:r}=e;history[n?`replaceState`:`pushState`](r,``,`#${t}`)}};function Z(e){let[t]=m(()=>`router`in e?e.router:new J(e)),n=U(t,t.history.getPath),r=f(()=>t.matchAll(n),[t,n]);return r||console.error(`[Waymark] No matching route found for path:`,n),f(()=>v(M.Provider,{value:t,children:v(N.Provider,{value:r,children:r?.route._.components.reduceRight((e,t)=>v(P.Provider,{value:e,children:v(t,{})}),null)})}),[t,r])}function ee(){return R()}function te(e){let t=F();return d(()=>t.navigate(e),[]),t.ssrContext&&(t.ssrContext.redirect=t.createUrl(e)),null}function ne(e){let t=F(),{to:r,replace:a,state:o,params:c,search:u,strict:d,preload:m,preloadDelay:h=50,style:g,className:_,activeStyle:y,activeClassName:b,asChild:x,children:S,...C}={...t.defaultLinkOptions,...e},w=p(null),T=p(null),E=t.createUrl(e),D=!!V({from:e.to,strict:d,params:c}),O=Q(()=>t.preload(e)),k=s(()=>{T.current!==null&&clearTimeout(T.current)},[]),A=s(()=>{k(),T.current=setTimeout(O,h)},[h,k]),j=f(()=>({"data-active":D,style:{...g,...D&&y},className:[_,D&&b].filter(Boolean).join(` `)||void 0}),[D,g,_,y,b]);l(()=>{if(m===`render`)A();else if(m===`viewport`&&w.current){let e=new IntersectionObserver(e=>e.forEach(e=>{e.isIntersecting?A():k()}));return e.observe(w.current),()=>{e.disconnect(),k()}}return k},[m,A,k]);let M=e=>{C.onClick?.(e),!(e.ctrlKey||e.metaKey||e.shiftKey||e.altKey||e.button!==0||e.defaultPrevented)&&(e.preventDefault(),t.navigate({url:E,replace:a,state:o}))},N=e=>{C.onFocus?.(e),m===`intent`&&!e.defaultPrevented&&A()},P=e=>{C.onBlur?.(e),m===`intent`&&k()},I=e=>{C.onPointerEnter?.(e),m===`intent`&&!e.defaultPrevented&&A()},L=e=>{C.onPointerLeave?.(e),m===`intent`&&k()},R={...C,...j,ref:re(w,C.ref),href:E,onClick:M,onFocus:N,onBlur:P,onPointerEnter:I,onPointerLeave:L};return x&&i(S)?n(S,R):v(`a`,{...R,children:S})}function re(e,t){return t?n=>{e.current=n;let r=typeof t==`function`?t(n):void(t.current=n);return r&&(()=>{e.current=null,r()})}:e}function Q(e){let t=p(e);return u(()=>{t.current=e},[e]),p(((...e)=>t.current(...e))).current}function ie(e){return()=>v(t,{fallback:v(e,{}),children:R()})}function ae(t){class n extends e{constructor(e){super(e),this.state={children:e.children,error:null}}static getDerivedStateFromError(e){return{error:[e]}}static getDerivedStateFromProps(e,t){return e.children===t.children?t:{children:e.children,error:null}}render(){return this.state.error?v(t,{error:this.state.error[0]}):this.props.children}}return()=>v(n,{children:R()})}function oe(e){let t=y(e);return new $(t,{...b(t),validate:e=>e,handles:[],components:[],preloads:[]})}var $=class e{pattern;_types;_;constructor(e,t){this.pattern=e,this._=t}route=t=>{let n=y(`${this.pattern}/${t}`);return new e(n,{...this._,...b(n)})};search=t=>(t=x(t),new e(this.pattern,{...this._,validate:e=>{let n=this._.validate(e);return{...n,...t({...e,...n})}}}));handle=t=>new e(this.pattern,{...this._,handles:[...this._.handles,t]});preload=t=>new e(this.pattern,{...this._,preloads:[...this._.preloads,e=>t({params:e.params,search:this._.validate(e.search)})]});component=t=>new e(this.pattern,{...this._,components:[...this._.components,o(t)]});lazy=e=>{let t=a(async()=>{let t=await e();return`default`in t?t:{default:t}});return this.preload(e).component(t)};suspense=e=>this.component(ie(e));error=e=>this.component(ae(e));toString=()=>this.pattern};export{W as BrowserHistory,X as HashHistory,ne as Link,N as MatchContext,Y as MemoryHistory,te as Navigate,ee as Outlet,P as OutletContext,$ as Route,J as Router,M as RouterContext,Z as RouterRoot,oe as route,H as useHandles,L as useLocation,V as useMatch,I as useNavigate,R as useOutlet,z as useParams,F as useRouter,B as useSearch,U as useSubscribe};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "waymark",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "strblr",
|
|
6
6
|
"description": "Lightweight type-safe router for React",
|
|
@@ -39,13 +39,13 @@
|
|
|
39
39
|
"minimal"
|
|
40
40
|
],
|
|
41
41
|
"scripts": {
|
|
42
|
-
"build": "tsc --noEmit && tsdown
|
|
42
|
+
"build": "tsc --noEmit && tsdown",
|
|
43
43
|
"prepublishOnly": "bun run build && cp ../../README.md README.md",
|
|
44
44
|
"postpublish": "rm -f README.md"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"@types/bun": "^1.3.
|
|
48
|
-
"@types/react": "^19.2.
|
|
47
|
+
"@types/bun": "^1.3.7",
|
|
48
|
+
"@types/react": "^19.2.10",
|
|
49
49
|
"tsdown": "^0.20.1",
|
|
50
50
|
"typescript": "^5.9.3"
|
|
51
51
|
},
|
|
@@ -55,6 +55,6 @@
|
|
|
55
55
|
"dependencies": {
|
|
56
56
|
"@standard-schema/spec": "^1.1.0",
|
|
57
57
|
"regexparam": "^3.0.0",
|
|
58
|
-
"type-fest": "
|
|
58
|
+
"type-fest": "5.4.1"
|
|
59
59
|
}
|
|
60
60
|
}
|