waymark 0.1.0 → 0.2.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.ts CHANGED
@@ -1 +1,196 @@
1
- export declare const a = 5;
1
+ import * as react2 from "react";
2
+ import { AnchorHTMLAttributes, CSSProperties, ComponentType, ReactNode, RefAttributes } from "react";
3
+ import * as regexparam0 from "regexparam";
4
+ import * as type_fest0 from "type-fest";
5
+ import { EmptyObject } from "type-fest";
6
+ import { StandardSchemaV1 } from "@standard-schema/spec";
7
+
8
+ //#region src/utils/types.d.ts
9
+ type NormalizePath<P extends string> = RemoveTrailingSlash<DedupSlashes<`/${P}`>>;
10
+ type DedupSlashes<P extends string> = P extends `${infer Prefix}//${infer Rest}` ? `${Prefix}${DedupSlashes<`/${Rest}`>}` : P;
11
+ type RemoveTrailingSlash<P extends string> = P extends `${infer Prefix}/` ? Prefix extends "" ? "/" : Prefix : P;
12
+ type MaybeKey<K extends string, T> = T extends EmptyObject ? { [P in K]?: EmptyObject } : {} extends T ? { [P in K]?: T } : { [P in K]: T };
13
+ //#endregion
14
+ //#region src/types.d.ts
15
+ interface Register {}
16
+ type RouteList = Register extends {
17
+ routes: infer RouteList extends ReadonlyArray<Route>;
18
+ } ? RouteList : ReadonlyArray<Route>;
19
+ type Handle = Register extends {
20
+ handle: infer Handle;
21
+ } ? Handle : any;
22
+ type Pattern = RouteList[number]["pattern"];
23
+ type GetRoute<P extends Pattern> = Extract<RouteList[number], {
24
+ pattern: P;
25
+ }>;
26
+ type Params<P extends Pattern> = NonNullable<GetRoute<P>["_"]["_params"]>;
27
+ type Search<P extends Pattern> = NonNullable<GetRoute<P>["_"]["_search"]>;
28
+ type MatchOptions<P extends Pattern> = {
29
+ from: P | GetRoute<P>;
30
+ strict?: boolean;
31
+ params?: Partial<Params<P>>;
32
+ };
33
+ type Match<P extends Pattern = Pattern> = {
34
+ route: GetRoute<P>;
35
+ params: Params<P>;
36
+ };
37
+ type NavigateOptions<P extends Pattern> = {
38
+ to: P | GetRoute<P>;
39
+ replace?: boolean;
40
+ state?: any;
41
+ } & MaybeKey<"params", Params<P>> & MaybeKey<"search", Search<P>>;
42
+ interface HistoryPushOptions {
43
+ url: string;
44
+ replace?: boolean;
45
+ state?: any;
46
+ }
47
+ interface HistoryLike {
48
+ getPath: () => string;
49
+ getSearch: () => string;
50
+ getState: () => any;
51
+ go: (delta: number) => void;
52
+ push: (options: HistoryPushOptions) => void;
53
+ subscribe: (listener: () => void) => () => void;
54
+ }
55
+ type Updater<T extends object> = Partial<T> | ((prev: T) => Partial<T>);
56
+ type ComponentLoader = () => Promise<ComponentType | {
57
+ default: ComponentType;
58
+ }>;
59
+ //#endregion
60
+ //#region src/route.d.ts
61
+ 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
+ declare class Route<P extends string = string, Ps extends {} = any, S extends {} = any> {
63
+ readonly pattern: P;
64
+ readonly _: {
65
+ _params?: Ps;
66
+ _search?: S;
67
+ keys: string[];
68
+ regex: RegExp;
69
+ looseRegex: RegExp;
70
+ weights: number[];
71
+ mapSearch: (search: Record<string, unknown>) => S;
72
+ handles: Handle[];
73
+ components: ComponentType[];
74
+ preloaded: boolean;
75
+ preloaders: (() => Promise<any>)[];
76
+ };
77
+ constructor(pattern: P, mapSearch: (search: Record<string, unknown>) => S, handles: Handle[], components: ComponentType[], preloaders: (() => Promise<any>)[]);
78
+ route<P2 extends string>(subPattern: P2): Route<NormalizePath<`${P}/${P2}`>, regexparam0.RouteParams<NormalizePath<`${P}/${P2}`>> extends infer T ? { [KeyType in keyof T]: T[KeyType] } : never, S>;
79
+ search<S2 extends {}>(mapper: ((search: S & Record<string, unknown>) => S2) | StandardSchemaV1<S & 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>;
80
+ handle(handle: Handle): Route<P, Ps, S>;
81
+ preloader(preloader: () => Promise<any>): Route<P, Ps, S>;
82
+ component(component: ComponentType): Route<P, Ps, S>;
83
+ lazy(loader: ComponentLoader): Route<P, Ps, S>;
84
+ suspense(fallback: ComponentType): Route<P, Ps, S>;
85
+ error(fallback: ComponentType<{
86
+ error: unknown;
87
+ }>): Route<P, Ps, S>;
88
+ preload(): Promise<void>;
89
+ toString(): P;
90
+ }
91
+ //#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
+ //#region src/router/router.d.ts
134
+ interface RouterOptions {
135
+ basePath?: string;
136
+ routes: RouteList;
137
+ history?: HistoryLike;
138
+ defaultLinkOptions?: LinkOptions;
139
+ }
140
+ declare class Router {
141
+ readonly basePath: string;
142
+ readonly routes: RouteList;
143
+ readonly history: HistoryLike;
144
+ readonly defaultLinkOptions?: LinkOptions;
145
+ readonly _: {
146
+ routeMap: Map<string, Route>;
147
+ };
148
+ constructor(options: RouterOptions);
149
+ getRoute<P extends Pattern>(pattern: P | GetRoute<P>): GetRoute<P>;
150
+ match<P extends Pattern>(path: string, options: MatchOptions<P>): Match<P> | null;
151
+ matchAll(path: string): Match | null;
152
+ createUrl<P extends Pattern>(options: NavigateOptions<P>): string;
153
+ navigate<P extends Pattern>(options: NavigateOptions<P> | HistoryPushOptions | number): void;
154
+ }
155
+ //#endregion
156
+ //#region src/router/browser-history.d.ts
157
+ declare class BrowserHistory implements HistoryLike {
158
+ private static patchKey;
159
+ constructor();
160
+ getPath: () => string;
161
+ getSearch: () => string;
162
+ getState: () => any;
163
+ go: (delta: number) => void;
164
+ push: (options: HistoryPushOptions) => void;
165
+ subscribe: (listener: () => void) => () => void;
166
+ }
167
+ //#endregion
168
+ //#region src/router/memory-history.d.ts
169
+ interface MemoryLocation {
170
+ path: string;
171
+ search: string;
172
+ state: any;
173
+ }
174
+ declare class MemoryHistory implements HistoryLike {
175
+ private stack;
176
+ private index;
177
+ private listeners;
178
+ constructor(url?: string);
179
+ private getCurrent;
180
+ getPath: () => string;
181
+ getSearch: () => string;
182
+ getState: () => any;
183
+ go: (delta: number) => void;
184
+ push: (options: HistoryPushOptions) => void;
185
+ subscribe: (listener: () => void) => () => void;
186
+ }
187
+ //#endregion
188
+ //#region src/router/hash-history.d.ts
189
+ declare class HashHistory extends BrowserHistory {
190
+ private getHashUrl;
191
+ getPath: () => string;
192
+ getSearch: () => string;
193
+ push: (options: HistoryPushOptions) => void;
194
+ }
195
+ //#endregion
196
+ export { BrowserHistory, ComponentLoader, GetRoute, Handle, HashHistory, HistoryLike, HistoryPushOptions, Link, LinkOptions, LinkProps, Match, MatchContext, MatchOptions, MemoryHistory, MemoryLocation, Navigate, NavigateOptions, NavigateProps, Outlet, OutletContext, Params, Pattern, Register, Route, RouteList, Router, RouterContext, RouterOptions, RouterRoot, RouterRootProps, Search, Updater, route, useHandles, useLocation, useMatch, useNavigate, useOutlet, useParams, useRouter, useSearch, useSubscribe };
package/dist/index.js CHANGED
@@ -1,2 +1 @@
1
- console.log("Hello via Bun!");
2
- export const a = 5;
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,useLayoutEffect as u,useMemo as d,useRef as ee,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";function _(e){return`/${e}`.replaceAll(/\/+/g,`/`).replace(/(.+)\/$/,`$1`)}function v(e){return e.split(`/`).slice(1).map(e=>e.includes(`*`)?0:e.includes(`:`)?1:2)}function y(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 b(e){return e.startsWith(`?`)?e.slice(1):e}function x(e){return Object.entries(e).filter(([e,t])=>t!==void 0).map(([e,t])=>`${e}=${encodeURIComponent(C(t))}`).join(`&`)}function S(e){let t=new URLSearchParams(e);return Object.fromEntries([...t.entries()].map(([e,t])=>(t=decodeURIComponent(t),[e,w(t)?JSON.parse(t):t])))}function C(e){return typeof e==`string`&&!w(e)?e:JSON.stringify(e)}function w(e){try{return JSON.parse(e),!0}catch{return!1}}function T(e,t){return _(`${t}/${e}`)}function E(e,t){return(e===t||e.startsWith(`${t}/`))&&(e=e.slice(t.length)||`/`),e}function D(e,t){return[e,x(t)].filter(Boolean).join(`?`)}function O(e){let{pathname:t,search:n}=new URL(e,`http://w`);return{path:t,search:b(n)}}function k(e,t,n,r){let i=e.exec(E(n,r));if(!i)return null;let a={};return t.forEach((e,t)=>{let n=i[t+1];n&&(a[e]=n)}),a}function A(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 j=r(null),M=r(null),N=r(null);function P(){let e=c(j);if(!e)throw Error(`[Waymark] useRouter must be used within a router context`);return e}function F(){let e=c(M);return d(()=>e?.route._.handles??[],[e])}function I(){return c(N)}function L(e,t){return p(e.history.subscribe,t,t)}function R(){let e=P();return d(()=>e.navigate.bind(e),[e])}function z(){let e=P(),t=L(e,e.history.getPath),n=L(e,e.history.getSearch),r=L(e,e.history.getState);return d(()=>({path:t,search:S(n),state:r}),[t,n,r])}function B(e){let t=P(),n=L(t,t.history.getPath);return d(()=>t.match(n,e),[t,n,e])}function te(e){let t=B({from:e});if(!t)throw Error(`[Waymark] Can't read params for non-matching route: ${e}`);return t.params}function ne(e){let t=B({from:e});if(!t)throw Error(`[Waymark] Can't read search for non-matching route: ${e}`);let n=s(e=>t.route._.mapSearch(S(e)),[t.route]),r=P(),i=L(r,r.history.getSearch);return[d(()=>n(i),[n,i]),s((e,t)=>{let i=n(r.history.getSearch());e=typeof e==`function`?e(i):e;let a=D(r.history.getPath(),{...i,...e});r.navigate({url:a,replace:t})},[r,n])]}var V=class e{static patchKey=Symbol.for(`waymark_history_patch_v01`);constructor(){if(typeof history<`u`&&!Object.hasOwn(window,e.patchKey)){for(let e of[H,U]){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}}Object.assign(window,{[e.patchKey]:!0})}}getPath=()=>location.pathname;getSearch=()=>b(location.search);getState=()=>history.state;go=e=>history.go(e);push=e=>{let{url:t,replace:n,state:r}=e;history[n?U:H](r,``,t)};subscribe=e=>(W.forEach(t=>window.addEventListener(t,e)),()=>{W.forEach(t=>window.removeEventListener(t,e))})};const H=`pushState`,U=`replaceState`,W=[`popstate`,H,U,`hashchange`];var G=class{basePath;routes;history;defaultLinkOptions;_;constructor(e){let{basePath:t=`/`,routes:n,history:r,defaultLinkOptions:i}=e;this.basePath=_(t),this.routes=n,this.history=r??new V,this.defaultLinkOptions=i,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=k(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){return A(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 D(T(m(i,n),this.basePath),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})}}},K=class{stack=[];index=0;listeners=new Set;constructor(e=`/`){this.stack.push({...O(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={...O(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)})},q=class extends V{getHashUrl=()=>location.hash.slice(1)||`/`;getPath=()=>O(this.getHashUrl()).path;getSearch=()=>O(this.getHashUrl()).search;push=e=>{let{url:t,replace:n,state:r}=e;history[n?`replaceState`:`pushState`](r,``,`#${t}`)}};function J(e){let[t]=f(()=>`router`in e?e.router:new G(e)),n=L(t,t.history.getPath),r=d(()=>t.matchAll(n),[t,n]);return r||console.error(`[Waymark] No matching route found for path:`,n),d(()=>g(j.Provider,{value:t,children:g(M.Provider,{value:r,children:r?.route._.components.reduceRight((e,t)=>g(N.Provider,{value:e,children:g(t,{})}),null)})}),[t,r])}function Y(){return I()}function X(e){let t=R();return u(()=>t(e),[]),null}function Z(e){let t=P(),{to:r,replace:a,state:o,params:s,search:c,strict:u,preload:f,style:p,className:m,activeStyle:h,activeClassName:_,asChild:v,children:y,...b}={...t.defaultLinkOptions,...e},x=ee(null),S=t.createUrl(e),C=d(()=>t.getRoute(e.to),[t,e.to]),w=!!B({from:C,strict:u,params:s}),T=d(()=>({"data-active":w,style:{...p,...w&&h},className:[m,w&&_].filter(Boolean).join(` `)||void 0}),[w,p,m,h,_]);l(()=>{if(f===`render`)C.preload();else if(f===`viewport`&&x.current){let e=new IntersectionObserver(t=>{t.forEach(t=>{t.isIntersecting&&(C.preload(),e.disconnect())})});return e.observe(x.current),()=>e.disconnect()}},[f,C]);let E=e=>{b.onClick?.(e),!(e.ctrlKey||e.metaKey||e.shiftKey||e.altKey||e.button!==0||e.defaultPrevented)&&(e.preventDefault(),t.navigate({url:S,replace:a,state:o}))},D=e=>{b.onFocus?.(e),f===`intent`&&!e.defaultPrevented&&C.preload()},O=e=>{b.onPointerEnter?.(e),f===`intent`&&!e.defaultPrevented&&C.preload()},k={...b,...T,ref:re(b.ref,x),href:S,onClick:E,onFocus:D,onPointerEnter:O};return v&&i(y)?n(y,k):g(`a`,{...k,children:y})}function re(...e){let t=e.filter(e=>!!e);return t.length<=1?t[0]??null:e=>{let n=[];for(let r of t){let t=Q(r,e);n.push(t??(()=>Q(r,null)))}return()=>n.forEach(e=>e())}}function Q(e,t){if(typeof e==`function`)return e(t);e&&(e.current=t)}function ie(e){return()=>g(t,{fallback:g(e,{}),children:I()})}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?g(t,{error:this.state.error[0]}):this.props.children}}return()=>g(n,{children:I()})}function oe(e){return new $(_(e),e=>e,[],[],[])}var $=class e{pattern;_;constructor(e,t,n,r,i){let{keys:a,pattern:o}=h(e),s=h(e,!0).pattern,c=v(e);this.pattern=e,this._={keys:a,regex:o,looseRegex:s,weights:c,mapSearch:t,handles:n,components:r,preloaded:!1,preloaders:i}}route(t){let{mapSearch:n,handles:r,components:i,preloaders:a}=this._;return new e(_(`${this.pattern}/${t}`),n,r,i,a)}search(t){let{mapSearch:n,handles:r,components:i,preloaders:a}=this._;return t=y(t),new e(this.pattern,e=>{let r=n(e);return{...r,...t(r)}},r,i,a)}handle(t){let{mapSearch:n,handles:r,components:i,preloaders:a}=this._;return new e(this.pattern,n,[...r,t],i,a)}preloader(t){let{mapSearch:n,handles:r,components:i,preloaders:a}=this._;return new e(this.pattern,n,r,i,[...a,t])}component(t){let{mapSearch:n,handles:r,components:i,preloaders:a}=this._;return new e(this.pattern,n,r,[...i,o(t)],a)}lazy(e){let t=a(async()=>{let t=await e();return{default:o(`default`in t?t.default:t)}});return this.preloader(e).component(t)}suspense(e){return this.component(ie(e))}error(e){return this.component(ae(e))}async preload(){let{preloaded:e,preloaders:t}=this._;e||(this._.preloaded=!0,await Promise.all(t.map(e=>e())))}toString(){return this.pattern}};export{V as BrowserHistory,q as HashHistory,Z as Link,M as MatchContext,K as MemoryHistory,X as Navigate,Y as Outlet,N as OutletContext,$ as Route,G as Router,j as RouterContext,J as RouterRoot,oe as route,F as useHandles,z as useLocation,B as useMatch,R as useNavigate,I as useOutlet,te as useParams,P as useRouter,ne as useSearch,L as useSubscribe};
package/package.json CHANGED
@@ -1,12 +1,18 @@
1
1
  {
2
2
  "name": "waymark",
3
- "version": "0.1.0",
4
- "description": "Simplest strongly typed router for React",
3
+ "version": "0.2.0",
4
+ "license": "MIT",
5
+ "author": "strblr",
6
+ "description": "Lightweight type-safe router for React",
5
7
  "type": "module",
6
8
  "main": "dist/index.js",
7
9
  "types": "dist/index.d.ts",
8
- "license": "MIT",
9
- "author": "strblr",
10
+ "exports": {
11
+ ".": {
12
+ "default": "./dist/index.js",
13
+ "types": "./dist/index.d.ts"
14
+ }
15
+ },
10
16
  "repository": {
11
17
  "type": "git",
12
18
  "url": "https://github.com/strblr/waymark"
@@ -16,27 +22,39 @@
16
22
  "keywords": [
17
23
  "react",
18
24
  "router",
19
- "wouter",
20
25
  "typescript",
21
26
  "type",
22
27
  "typed",
28
+ "strongly-typed",
29
+ "type-safe",
23
30
  "navigate",
24
31
  "navigation",
32
+ "route",
33
+ "history",
25
34
  "search",
26
35
  "params",
27
- "strongly-typed",
28
- "react-router",
29
- "react-router-dom"
36
+ "simple",
37
+ "tiny",
38
+ "lightweight",
39
+ "minimal"
30
40
  ],
31
41
  "scripts": {
32
- "build": "tsc",
33
- "prepublishOnly": "bun run build"
42
+ "build": "tsdown --minify --platform browser",
43
+ "copy-readme": "cp ../../README.md README.md",
44
+ "prepublishOnly": "bun run build && bun run copy-readme"
34
45
  },
35
46
  "devDependencies": {
36
- "@types/bun": "latest",
47
+ "@types/bun": "^1.3.6",
48
+ "@types/react": "^19.2.9",
49
+ "tsdown": "^0.20.1",
37
50
  "typescript": "^5.9.3"
38
51
  },
39
52
  "peerDependencies": {
40
53
  "react": ">=18"
54
+ },
55
+ "dependencies": {
56
+ "@standard-schema/spec": "^1.1.0",
57
+ "regexparam": "^3.0.0",
58
+ "type-fest": "^5.4.1"
41
59
  }
42
60
  }
@@ -0,0 +1,8 @@
1
+ import { defineConfig } from "tsdown";
2
+
3
+ export default defineConfig({
4
+ entry: ["./src/index.ts"],
5
+ report: {
6
+ brotli: true
7
+ }
8
+ });
package/src/index.ts DELETED
@@ -1,2 +0,0 @@
1
- console.log("Hello via Bun!");
2
- export const a = 5;
package/tsconfig.json DELETED
@@ -1,19 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "lib": ["ESNext", "DOM"],
5
- "module": "ESNext",
6
- "moduleResolution": "Bundler",
7
- "declaration": true,
8
- "strict": true,
9
- "esModuleInterop": true,
10
- "skipLibCheck": true,
11
- "forceConsistentCasingInFileNames": true,
12
- "noUnusedLocals": true,
13
- "noUnusedParameters": true,
14
- "noFallthroughCasesInSwitch": true,
15
- "outDir": "./dist"
16
- },
17
- "include": ["src"],
18
- "exclude": ["node_modules", "dist", "**/*.test.ts"]
19
- }