waymark 0.2.2 → 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 +740 -408
- package/dist/index.d.ts +85 -78
- package/dist/index.js +1 -1
- package/package.json +7 -8
- package/tsdown.config.ts +0 -8
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,19 @@ 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
|
+
}
|
|
62
|
+
type SSRContext = {
|
|
63
|
+
redirect?: string;
|
|
64
|
+
statusCode?: number;
|
|
65
|
+
};
|
|
42
66
|
interface HistoryPushOptions {
|
|
43
67
|
url: string;
|
|
44
68
|
replace?: boolean;
|
|
@@ -61,99 +85,54 @@ type ComponentLoader = () => Promise<ComponentType | {
|
|
|
61
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, {}>;
|
|
62
86
|
declare class Route<P extends string = string, Ps extends {} = any, S extends {} = any> {
|
|
63
87
|
readonly pattern: P;
|
|
88
|
+
readonly _types: {
|
|
89
|
+
params: Ps;
|
|
90
|
+
search: S;
|
|
91
|
+
};
|
|
64
92
|
readonly _: {
|
|
65
|
-
_params?: Ps;
|
|
66
|
-
_search?: S;
|
|
67
93
|
keys: string[];
|
|
68
94
|
regex: RegExp;
|
|
69
95
|
looseRegex: RegExp;
|
|
70
96
|
weights: number[];
|
|
71
|
-
|
|
97
|
+
validate: (search: Record<string, unknown>) => S;
|
|
72
98
|
handles: Handle[];
|
|
73
99
|
components: ComponentType[];
|
|
74
|
-
|
|
75
|
-
preloaders: (() => Promise<any>)[];
|
|
100
|
+
preloads: ((context: PreloadContext) => Promise<any>)[];
|
|
76
101
|
};
|
|
77
|
-
constructor(pattern: P,
|
|
78
|
-
route<P2 extends string>(
|
|
79
|
-
search<S2 extends {}>(
|
|
80
|
-
handle(handle: Handle)
|
|
81
|
-
|
|
82
|
-
component(component: ComponentType)
|
|
83
|
-
lazy(loader: ComponentLoader)
|
|
84
|
-
suspense(fallback: ComponentType)
|
|
85
|
-
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<{
|
|
86
111
|
error: unknown;
|
|
87
|
-
}>)
|
|
88
|
-
|
|
89
|
-
toString(): P;
|
|
112
|
+
}>) => Route<P, Ps, S>;
|
|
113
|
+
toString: () => P;
|
|
90
114
|
}
|
|
91
115
|
//#endregion
|
|
92
|
-
//#region src/react/components.d.ts
|
|
93
|
-
type RouterRootProps = RouterOptions | {
|
|
94
|
-
router: Router;
|
|
95
|
-
};
|
|
96
|
-
declare function RouterRoot(props: RouterRootProps): ReactNode;
|
|
97
|
-
declare function Outlet(): ReactNode;
|
|
98
|
-
type NavigateProps<P extends Pattern> = NavigateOptions<P>;
|
|
99
|
-
declare function Navigate<P extends Pattern>(props: NavigateProps<P>): null;
|
|
100
|
-
type LinkProps<P extends Pattern> = NavigateOptions<P> & LinkOptions & AnchorHTMLAttributes<HTMLAnchorElement> & RefAttributes<HTMLAnchorElement> & {
|
|
101
|
-
asChild?: boolean;
|
|
102
|
-
};
|
|
103
|
-
interface LinkOptions {
|
|
104
|
-
strict?: boolean;
|
|
105
|
-
preload?: "intent" | "render" | "viewport" | false;
|
|
106
|
-
style?: CSSProperties;
|
|
107
|
-
className?: string;
|
|
108
|
-
activeStyle?: CSSProperties;
|
|
109
|
-
activeClassName?: string;
|
|
110
|
-
}
|
|
111
|
-
declare function Link<P extends Pattern>(props: LinkProps<P>): ReactNode;
|
|
112
|
-
//#endregion
|
|
113
|
-
//#region src/react/hooks.d.ts
|
|
114
|
-
declare function useRouter(): Router;
|
|
115
|
-
declare function useHandles(): Handle[];
|
|
116
|
-
declare function useOutlet(): react2.ReactNode;
|
|
117
|
-
declare function useSubscribe<T>(router: Router, getSnapshot: () => T): T;
|
|
118
|
-
declare function useNavigate(): <P extends Pattern>(options: number | HistoryPushOptions | NavigateOptions<P>) => void;
|
|
119
|
-
declare function useLocation(): {
|
|
120
|
-
path: string;
|
|
121
|
-
search: Record<string, unknown>;
|
|
122
|
-
state: any;
|
|
123
|
-
};
|
|
124
|
-
declare function useMatch<P extends Pattern>(options: MatchOptions<P>): Match<P> | null;
|
|
125
|
-
declare function useParams<P extends Pattern>(from: P | GetRoute<P>): Params<P>;
|
|
126
|
-
declare function useSearch<P extends Pattern>(from: P | GetRoute<P>): readonly [Search<P>, (update: Updater<Search<P>>, replace?: boolean) => void];
|
|
127
|
-
//#endregion
|
|
128
|
-
//#region src/react/contexts.d.ts
|
|
129
|
-
declare const RouterContext: react2.Context<Router | null>;
|
|
130
|
-
declare const MatchContext: react2.Context<Match | null>;
|
|
131
|
-
declare const OutletContext: react2.Context<ReactNode>;
|
|
132
|
-
//#endregion
|
|
133
116
|
//#region src/router/router.d.ts
|
|
134
|
-
interface RouterOptions {
|
|
135
|
-
basePath?: string;
|
|
136
|
-
routes: RouteList;
|
|
137
|
-
history?: HistoryLike;
|
|
138
|
-
defaultLinkOptions?: LinkOptions;
|
|
139
|
-
}
|
|
140
117
|
declare class Router {
|
|
141
118
|
readonly basePath: string;
|
|
142
119
|
readonly routes: RouteList;
|
|
143
120
|
readonly history: HistoryLike;
|
|
121
|
+
readonly ssrContext?: SSRContext;
|
|
144
122
|
readonly defaultLinkOptions?: LinkOptions;
|
|
145
123
|
private readonly _;
|
|
146
124
|
constructor(options: RouterOptions);
|
|
147
|
-
getRoute<P extends Pattern>(pattern: P | GetRoute<P>)
|
|
148
|
-
match<P extends Pattern>(path: string, options: MatchOptions<P>)
|
|
149
|
-
matchAll(path: string)
|
|
150
|
-
createUrl<P extends Pattern>(options: NavigateOptions<P>)
|
|
151
|
-
|
|
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;
|
|
152
131
|
}
|
|
153
132
|
//#endregion
|
|
154
133
|
//#region src/router/browser-history.d.ts
|
|
155
134
|
declare class BrowserHistory implements HistoryLike {
|
|
156
|
-
private static
|
|
135
|
+
private static patch;
|
|
157
136
|
private memo?;
|
|
158
137
|
constructor();
|
|
159
138
|
protected getSearchMemo: (search: string) => Record<string, unknown>;
|
|
@@ -166,11 +145,6 @@ declare class BrowserHistory implements HistoryLike {
|
|
|
166
145
|
}
|
|
167
146
|
//#endregion
|
|
168
147
|
//#region src/router/memory-history.d.ts
|
|
169
|
-
interface MemoryLocation {
|
|
170
|
-
path: string;
|
|
171
|
-
search: Record<string, unknown>;
|
|
172
|
-
state: any;
|
|
173
|
-
}
|
|
174
148
|
declare class MemoryHistory implements HistoryLike {
|
|
175
149
|
private stack;
|
|
176
150
|
private index;
|
|
@@ -193,4 +167,37 @@ declare class HashHistory extends BrowserHistory {
|
|
|
193
167
|
push: (options: HistoryPushOptions) => void;
|
|
194
168
|
}
|
|
195
169
|
//#endregion
|
|
196
|
-
|
|
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 l,
|
|
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",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"type": "git",
|
|
18
18
|
"url": "git+https://github.com/strblr/waymark.git"
|
|
19
19
|
},
|
|
20
|
-
"homepage": "https://strblr.
|
|
20
|
+
"homepage": "https://waymark.strblr.workers.dev",
|
|
21
21
|
"bugs": "https://github.com/strblr/waymark/issues",
|
|
22
22
|
"keywords": [
|
|
23
23
|
"react",
|
|
@@ -39,14 +39,13 @@
|
|
|
39
39
|
"minimal"
|
|
40
40
|
],
|
|
41
41
|
"scripts": {
|
|
42
|
-
"build": "tsc --noEmit && tsdown
|
|
43
|
-
"
|
|
44
|
-
"prepublishOnly": "bun run build && bun run copy-readme",
|
|
42
|
+
"build": "tsc --noEmit && tsdown",
|
|
43
|
+
"prepublishOnly": "bun run build && cp ../../README.md README.md",
|
|
45
44
|
"postpublish": "rm -f README.md"
|
|
46
45
|
},
|
|
47
46
|
"devDependencies": {
|
|
48
|
-
"@types/bun": "^1.3.
|
|
49
|
-
"@types/react": "^19.2.
|
|
47
|
+
"@types/bun": "^1.3.7",
|
|
48
|
+
"@types/react": "^19.2.10",
|
|
50
49
|
"tsdown": "^0.20.1",
|
|
51
50
|
"typescript": "^5.9.3"
|
|
52
51
|
},
|
|
@@ -56,6 +55,6 @@
|
|
|
56
55
|
"dependencies": {
|
|
57
56
|
"@standard-schema/spec": "^1.1.0",
|
|
58
57
|
"regexparam": "^3.0.0",
|
|
59
|
-
"type-fest": "
|
|
58
|
+
"type-fest": "5.4.1"
|
|
60
59
|
}
|
|
61
60
|
}
|