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.
@@ -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
+ }