neouter 0.1.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/dist/index.d.mts +67 -0
- package/dist/index.mjs +1 -0
- package/package.json +22 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { ComponentProps, ComponentType } from "react";
|
|
2
|
+
|
|
3
|
+
//#region src/types.d.ts
|
|
4
|
+
type Path$1 = string;
|
|
5
|
+
declare enum PreloadType {
|
|
6
|
+
hover = 0,
|
|
7
|
+
view = 1,
|
|
8
|
+
off = 2,
|
|
9
|
+
}
|
|
10
|
+
type RouteOptions = {
|
|
11
|
+
preload?: PreloadType;
|
|
12
|
+
};
|
|
13
|
+
type Route = {
|
|
14
|
+
component: React.ComponentType;
|
|
15
|
+
options?: RouteOptions;
|
|
16
|
+
};
|
|
17
|
+
type Routes = Record<Path$1, Route>;
|
|
18
|
+
type ExtractParams<Path$2 extends string> = Path$2 extends `${string}:${infer Param}/${infer Rest}` ? Param | ExtractParams<`/${Rest}`> : Path$2 extends `${string}:${infer Param}` ? Param : never;
|
|
19
|
+
type ParamsObject<Path$2 extends string> = { [K in ExtractParams<Path$2>]?: string };
|
|
20
|
+
type QueryParamsValueType = 'string' | 'number';
|
|
21
|
+
type WithQueryAndHash<Path$2 extends string> = Path$2 | `${Path$2}?${string}` | `${Path$2}#${string}`;
|
|
22
|
+
type ReplaceParams<Path$2 extends string> = Path$2 extends `${infer Start}:${string}/${infer Rest}` ? `${Start}${string}/${ReplaceParams<Rest>}` : Path$2 extends `${infer Start}:${string}` ? `${Start}${string}` : Path$2;
|
|
23
|
+
type AssertPathType<R extends string> = ReplaceParams<R>;
|
|
24
|
+
//#endregion
|
|
25
|
+
//#region src/components/BaseLink.d.ts
|
|
26
|
+
declare const BaseLink: ({
|
|
27
|
+
href,
|
|
28
|
+
children,
|
|
29
|
+
...props
|
|
30
|
+
}: ComponentProps<"a"> & {
|
|
31
|
+
href: Path$1;
|
|
32
|
+
}) => any;
|
|
33
|
+
//#endregion
|
|
34
|
+
//#region src/hooks/useCreateRoutes.d.ts
|
|
35
|
+
declare const useCreateRoutes: ({
|
|
36
|
+
routes,
|
|
37
|
+
notFoundComponent
|
|
38
|
+
}: {
|
|
39
|
+
routes: Routes;
|
|
40
|
+
notFoundComponent?: React.ComponentType;
|
|
41
|
+
}) => any;
|
|
42
|
+
//#endregion
|
|
43
|
+
//#region src/hooks/usePathParams.d.ts
|
|
44
|
+
declare const usePathParams: <Path extends string>() => ParamsObject<Path> | null;
|
|
45
|
+
//#endregion
|
|
46
|
+
//#region src/hooks/useQueryParams.d.ts
|
|
47
|
+
type Options = {
|
|
48
|
+
noThrowError?: boolean;
|
|
49
|
+
};
|
|
50
|
+
declare const useQueryParams: <T extends Record<string, QueryParamsValueType>>(expectedTypes: T, options?: Options) => any;
|
|
51
|
+
//#endregion
|
|
52
|
+
//#region src/hooks/useRouter.d.ts
|
|
53
|
+
declare const useRouter: () => readonly [any, any];
|
|
54
|
+
//#endregion
|
|
55
|
+
//#region src/libs/extractParams.d.ts
|
|
56
|
+
declare const extractParams: <Path extends string, Params extends string = ExtractParams<Path>>(pathPattern: Path, actualPath: string) => Record<Params, string>;
|
|
57
|
+
//#endregion
|
|
58
|
+
//#region src/libs/getMatchedPath.d.ts
|
|
59
|
+
declare const getMatchedPath: (routes: Routes, path: string) => Path$1 | null;
|
|
60
|
+
//#endregion
|
|
61
|
+
//#region src/libs/lazyImport.d.ts
|
|
62
|
+
declare function lazyImport<U extends string, T$1 extends { [P in U]: ComponentType }>(factory: () => Promise<T$1>, name: U): T$1;
|
|
63
|
+
//#endregion
|
|
64
|
+
//#region src/libs/redirect.d.ts
|
|
65
|
+
declare const redirect: <T extends Path$1>(path: T) => () => any;
|
|
66
|
+
//#endregion
|
|
67
|
+
export { type AssertPathType, BaseLink, type ExtractParams, type ParamsObject, type Path$1 as Path, type QueryParamsValueType, type Routes, type WithQueryAndHash, extractParams, getMatchedPath, lazyImport, redirect, useCreateRoutes, usePathParams, useQueryParams, useRouter };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createContext as e,lazy as t,useCallback as n,useContext as r,useEffect as i,useLayoutEffect as a,useMemo as o,useState as s}from"react";import{jsx as c}from"react/jsx-runtime";const l=e({location:``,setLocation:()=>{},routes:{}}),u=({routes:e,children:t})=>{let n=()=>window.location.pathname+window.location.search,[r,a]=s(n());return i(()=>{let e=()=>{a(n())};return window.addEventListener(`popstate`,e),()=>{window.removeEventListener(`popstate`,e)}},[r]),c(l.Provider,{value:{location:r,setLocation:a,routes:e},children:t})},d=({routes:e,notFoundComponent:t})=>{let{location:n}=r(l),i=g(e,n),a=i?e[i]?.component:null;return a?c(a,{}):t},f=({routes:e,notFoundComponent:t})=>{let n=t||(()=>c(`div`,{children:`404`}));return o(()=>({paths:Object.keys(e),RouterProvider:({children:t})=>c(u,{routes:e,children:t}),Router:()=>c(d,{routes:e,notFoundComponent:c(n,{})})}),[e,n])},p=(e,t)=>{let n=e.split(`/`),r=t.split(`/`),i={};return n.forEach((e,t)=>{if(e.startsWith(`:`)){let n=e.slice(1);i[n]=r[t]}}),i},m=new Map,h=(e,t)=>{let n=Object.keys(e),r=n.map(e=>(m.has(e)||m.set(e,RegExp(`^${e.replace(/:(\w+)/g,`(\\w+)`)}$`)),m.get(e))).findIndex(e=>e.test(t));return r===-1?null:n[r]??null},g=(e,t)=>{let n=t.split(`?`)[0];return n?(n.length>1&&n.endsWith(`/`)&&(n=n.slice(0,-1)),h(e,n)):null};function _(e,n){return Object.create({[n]:t(()=>e().then(e=>({default:e[n]})))})}const v=({path:e})=>{let[,t]=S();return a(()=>{t(e)},[e,t]),null},y=e=>()=>c(v,{path:e}),b=()=>{let{location:e,routes:t}=r(l),n=g(t,e);return n?p(n,e.split(`?`)[0]??e):null},x=(e,t)=>{let[n]=S(),r=o(()=>new URL(n,window.location.origin),[n]);return o(()=>{let n={};for(let[i,a]of r.searchParams.entries())if(i in e)if(e[i]===`number`){let e=Number(a);if(!t?.noThrowError&&Number.isNaN(e))throw Error(`Invalid number value for key ${i}`);n[i]=e}else n[i]=a;return n},[r,e,t?.noThrowError])},S=()=>{let{location:e,setLocation:t}=r(l);return[e,n(e=>{t(e),window.history.pushState({},``,e)},[t])]},C=({href:e,children:t,...n})=>{let[,r]=S(),{onClick:i,...a}=n;return c(`a`,{href:e,...a,onClick:t=>{i?.(t),!(t.ctrlKey||t.metaKey)&&(t.defaultPrevented||(t.preventDefault(),r(e)))},children:t})};export{C as BaseLink,p as extractParams,g as getMatchedPath,_ as lazyImport,y as redirect,f as useCreateRoutes,b as usePathParams,x as useQueryParams,S as useRouter};
|
package/package.json
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "neouter",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"author": "avaice <avaice@ymail.ne.jp>",
|
|
5
|
+
"license": "ISC",
|
|
6
|
+
"description": "A type-safe router for minimalists",
|
|
7
|
+
"main": "dist/index.mjs",
|
|
8
|
+
"types": "dist/index.d.mts",
|
|
9
|
+
"files": [
|
|
10
|
+
"dist"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "tsdown",
|
|
14
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
15
|
+
},
|
|
16
|
+
"peerDependencies": {
|
|
17
|
+
"react": ">=18"
|
|
18
|
+
},
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"tsdown": "^0.15.8"
|
|
21
|
+
}
|
|
22
|
+
}
|