@mpen/rerouter 0.1.9 → 0.3.1

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.
Files changed (89) hide show
  1. package/README.md +80 -18
  2. package/cli/bin.test.ts +221 -0
  3. package/cli/bin.ts +342 -0
  4. package/cli/fixtures/bin/kitchen-sink.tsx +15 -0
  5. package/cli/fixtures/bin/optional.tsx +3 -0
  6. package/cli/fixtures/bin/pages/Home.tsx +3 -0
  7. package/cli/fixtures/bin/pages/KitchenSink.tsx +3 -0
  8. package/cli/fixtures/bin/pages/Login.tsx +3 -0
  9. package/cli/fixtures/bin/pages/Match.tsx +3 -0
  10. package/cli/fixtures/bin/pages/NotFound.tsx +3 -0
  11. package/cli/fixtures/bin/pages/Optional.tsx +3 -0
  12. package/cli/fixtures/bin/regexp-groups.tsx +11 -0
  13. package/cli/fixtures/bin/simple.tsx +1 -0
  14. package/cli/fixtures/bin/unnamed.tsx +4 -0
  15. package/cli/tsconfig.json +9 -0
  16. package/dist/acorn-k7ED_tOl.js +4968 -0
  17. package/dist/angular--Iqdw9UJ.js +4057 -0
  18. package/dist/babel-hfWAujRY.js +9878 -0
  19. package/dist/bin.d.ts +29 -0
  20. package/dist/bin.js +233 -0
  21. package/dist/estree-C1Zjnvlw.js +7266 -0
  22. package/dist/flow-BaD9LyIP.js +52912 -0
  23. package/dist/glimmer-CvCjW_1V.js +7541 -0
  24. package/dist/graphql-BdtzBuWh.js +1945 -0
  25. package/dist/html-DkZtUVbo.js +7137 -0
  26. package/dist/index.d.ts +278 -0
  27. package/dist/index.js +247 -0
  28. package/dist/markdown-Z8Vrc69e.js +6876 -0
  29. package/dist/meriyah-DeO4stuH.js +7590 -0
  30. package/dist/postcss-BmgGJ0E5.js +6777 -0
  31. package/dist/prettier-BT_F8kIx.js +15629 -0
  32. package/dist/routes-PW-bNm8e.js +135 -0
  33. package/dist/typescript-DtIxStjy.js +22936 -0
  34. package/dist/yaml-CWOPBY0q.js +5281 -0
  35. package/examples/App.tsx +80 -0
  36. package/examples/dist/BlogPost-c10d9w2p.js +1 -0
  37. package/examples/dist/FetchLoading-534mdrgz.js +1 -0
  38. package/examples/dist/FetchLoading-sbxbdkre.js +1 -0
  39. package/examples/dist/Home-a1258p25.js +1 -0
  40. package/examples/dist/KitchenSink-821mjg0h.js +1 -0
  41. package/examples/dist/Login-wywx6bp7.js +1 -0
  42. package/examples/dist/Match-1e72jm5w.js +1 -0
  43. package/examples/dist/NotFound-smxj24jw.js +1 -0
  44. package/examples/dist/SlowLoading-59xxmbfk.js +1 -0
  45. package/examples/dist/index-0d4kj0rv.js +2 -0
  46. package/examples/dist/index-3x197sbt.js +9 -0
  47. package/examples/dist/index-a2hkfx1n.js +9 -0
  48. package/examples/dist/index-d21me1mc.js +9 -0
  49. package/examples/dist/index-ktqdknsn.js +2 -0
  50. package/examples/dist/index-p53qxxzd.js +2 -0
  51. package/examples/dist/index.html +67 -0
  52. package/examples/index.html +67 -0
  53. package/examples/pages/BlogPost.tsx +17 -0
  54. package/examples/pages/FetchLoading.tsx +53 -0
  55. package/examples/pages/FetchLoadingItem.tsx +45 -0
  56. package/examples/pages/Home.tsx +3 -0
  57. package/examples/pages/KitchenSink.tsx +23 -0
  58. package/examples/pages/Login.tsx +3 -0
  59. package/examples/pages/Match.tsx +5 -0
  60. package/examples/pages/NotFound.tsx +3 -0
  61. package/examples/pages/SlowLoading.tsx +8 -0
  62. package/examples/routes.gen.ts +105 -0
  63. package/examples/routes.ts +40 -0
  64. package/examples/server/serve-dist.ts +33 -0
  65. package/examples/server/tsconfig.json +9 -0
  66. package/package.json +41 -31
  67. package/src/components/Link.test.tsx +139 -0
  68. package/src/components/Link.tsx +89 -0
  69. package/src/components/NavLink.test.tsx +119 -0
  70. package/src/components/NavLink.tsx +71 -0
  71. package/src/components/Router.test.tsx +183 -0
  72. package/src/components/Router.tsx +207 -0
  73. package/src/hooks/index.ts +1 -0
  74. package/src/hooks/useUrl.ts +22 -0
  75. package/src/index.ts +6 -0
  76. package/src/lib/mergeSearch.test.ts +37 -0
  77. package/src/lib/mergeSearch.ts +21 -0
  78. package/src/lib/routes.test.ts +67 -0
  79. package/src/lib/routes.ts +247 -0
  80. package/src/lib/url.ts +9 -0
  81. package/tsconfig.json +10 -0
  82. package/tsdown.config.ts +21 -0
  83. package/LICENSE +0 -21
  84. package/dist/bundle.cjs +0 -422
  85. package/dist/bundle.d.ts +0 -2
  86. package/dist/bundle.mjs +0 -420
  87. package/dist/dev.d.ts +0 -1
  88. package/dist/log.d.ts +0 -1
  89. package/dist/uri-template.d.ts +0 -56
@@ -0,0 +1,67 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>@mpen/rerouter examples</title>
7
+ <style>
8
+ body {
9
+ margin: 0;
10
+ font-family:
11
+ ui-sans-serif,
12
+ system-ui,
13
+ -apple-system,
14
+ Segoe UI,
15
+ Roboto,
16
+ Helvetica,
17
+ Arial,
18
+ 'Apple Color Emoji',
19
+ 'Segoe UI Emoji';
20
+ background: #0b1020;
21
+ color: #e8eefc;
22
+ }
23
+ a {
24
+ color: inherit;
25
+ }
26
+ .app {
27
+ max-width: 900px;
28
+ margin: 0 auto;
29
+ padding: 24px;
30
+ }
31
+ .card {
32
+ background: rgba(255, 255, 255, 0.06);
33
+ border: 1px solid rgba(255, 255, 255, 0.12);
34
+ border-radius: 12px;
35
+ padding: 16px;
36
+ margin-bottom: 16px;
37
+ }
38
+ .nav {
39
+ display: flex;
40
+ flex-wrap: wrap;
41
+ gap: 10px;
42
+ margin-top: 8px;
43
+ }
44
+ .pill {
45
+ padding: 6px 10px;
46
+ border-radius: 999px;
47
+ border: 1px solid rgba(255, 255, 255, 0.16);
48
+ background: rgba(255, 255, 255, 0.06);
49
+ text-decoration: none;
50
+ }
51
+ .pill.active {
52
+ border-color: rgba(90, 200, 250, 0.7);
53
+ background: rgba(90, 200, 250, 0.18);
54
+ }
55
+ code {
56
+ font-family:
57
+ ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono',
58
+ 'Courier New', monospace;
59
+ font-size: 0.95em;
60
+ }
61
+ </style>
62
+ <script type="module" crossorigin src="./index-d21me1mc.js"></script></head>
63
+ <body>
64
+ <div id="root"></div>
65
+
66
+ </body>
67
+ </html>
@@ -0,0 +1,67 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>@mpen/rerouter examples</title>
7
+ <style>
8
+ body {
9
+ margin: 0;
10
+ font-family:
11
+ ui-sans-serif,
12
+ system-ui,
13
+ -apple-system,
14
+ Segoe UI,
15
+ Roboto,
16
+ Helvetica,
17
+ Arial,
18
+ 'Apple Color Emoji',
19
+ 'Segoe UI Emoji';
20
+ background: #0b1020;
21
+ color: #e8eefc;
22
+ }
23
+ a {
24
+ color: inherit;
25
+ }
26
+ .app {
27
+ max-width: 900px;
28
+ margin: 0 auto;
29
+ padding: 24px;
30
+ }
31
+ .card {
32
+ background: rgba(255, 255, 255, 0.06);
33
+ border: 1px solid rgba(255, 255, 255, 0.12);
34
+ border-radius: 12px;
35
+ padding: 16px;
36
+ margin-bottom: 16px;
37
+ }
38
+ .nav {
39
+ display: flex;
40
+ flex-wrap: wrap;
41
+ gap: 10px;
42
+ margin-top: 8px;
43
+ }
44
+ .pill {
45
+ padding: 6px 10px;
46
+ border-radius: 999px;
47
+ border: 1px solid rgba(255, 255, 255, 0.16);
48
+ background: rgba(255, 255, 255, 0.06);
49
+ text-decoration: none;
50
+ }
51
+ .pill.active {
52
+ border-color: rgba(90, 200, 250, 0.7);
53
+ background: rgba(90, 200, 250, 0.18);
54
+ }
55
+ code {
56
+ font-family:
57
+ ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono',
58
+ 'Courier New', monospace;
59
+ font-size: 0.95em;
60
+ }
61
+ </style>
62
+ </head>
63
+ <body>
64
+ <div id="root"></div>
65
+ <script type="module" src="./App.tsx"></script>
66
+ </body>
67
+ </html>
@@ -0,0 +1,17 @@
1
+ import type { RouteComponent } from '../../src'
2
+
3
+ type BlogPostParams = {
4
+ id: string
5
+ title?: string
6
+ }
7
+
8
+ const BlogPost: RouteComponent<BlogPostParams> = ({ id, title }) => {
9
+ return (
10
+ <div>
11
+ <div>Blog post: {id}</div>
12
+ <div>Title: {title}</div>
13
+ </div>
14
+ )
15
+ }
16
+
17
+ export default BlogPost
@@ -0,0 +1,53 @@
1
+ import { use } from 'react'
2
+ import { NavLink, Router, type RouteObject } from '../../src'
3
+ import FetchLoadingItem from './FetchLoadingItem'
4
+ import * as routesGen from '../routes.gen'
5
+
6
+ const itemRoutes: readonly RouteObject[] = [
7
+ {
8
+ pattern: '/fetch-loading/:id',
9
+ component: async () => ({ default: FetchLoadingItem }),
10
+ },
11
+ ]
12
+
13
+ type FetchResult = {
14
+ message: string
15
+ loadedAt: string
16
+ }
17
+
18
+ const fetchResult = new Promise<FetchResult>((resolve) => {
19
+ setTimeout(() => {
20
+ resolve({
21
+ message: 'The route component loaded immediately, then Suspense waited for data.',
22
+ loadedAt: new Date().toLocaleTimeString(),
23
+ })
24
+ }, 2000)
25
+ })
26
+
27
+ export default function FetchLoading() {
28
+ const result = use(fetchResult)
29
+ const itemIds = ['abc-123', 'invoice-456', 'with/slash']
30
+
31
+ return (
32
+ <div>
33
+ <h2 style={{ marginTop: 0 }}>Fetch loading page</h2>
34
+ <div>{result.message}</div>
35
+ <div style={{ marginTop: 8, opacity: 0.8 }}>Loaded at {result.loadedAt}</div>
36
+ <div className="nav" style={{ marginTop: 16 }}>
37
+ {itemIds.map((id) => (
38
+ <NavLink
39
+ activeClass="active"
40
+ className="pill"
41
+ key={id}
42
+ to={routesGen.fetchLoadingItem({ id })}
43
+ >
44
+ Fetch {id}
45
+ </NavLink>
46
+ ))}
47
+ </div>
48
+ <div style={{ marginTop: 16 }}>
49
+ <Router routes={itemRoutes} loading={<div>Loading item...</div>} />
50
+ </div>
51
+ </div>
52
+ )
53
+ }
@@ -0,0 +1,45 @@
1
+ import { use } from 'react'
2
+
3
+ type FetchLoadingItemProps = {
4
+ id: string
5
+ }
6
+
7
+ type FetchResult = {
8
+ id: string
9
+ message: string
10
+ loadedAt: string
11
+ }
12
+
13
+ const fetchResults = new Map<string, Promise<FetchResult>>()
14
+
15
+ function fetchItem(id: string): Promise<FetchResult> {
16
+ let result = fetchResults.get(id)
17
+ if (!result) {
18
+ result = new Promise<FetchResult>((resolve) => {
19
+ setTimeout(() => {
20
+ resolve({
21
+ id,
22
+ message: `Fetched fake data for item ${id}.`,
23
+ loadedAt: new Date().toLocaleTimeString(),
24
+ })
25
+ }, 2000)
26
+ })
27
+ fetchResults.set(id, result)
28
+ }
29
+ return result
30
+ }
31
+
32
+ export default function FetchLoadingItem({ id }: FetchLoadingItemProps) {
33
+ const result = use(fetchItem(id))
34
+
35
+ return (
36
+ <div>
37
+ <h2 style={{ marginTop: 0 }}>Fetch loading item</h2>
38
+ <div>
39
+ URL param: <code>{result.id}</code>
40
+ </div>
41
+ <div style={{ marginTop: 8 }}>{result.message}</div>
42
+ <div style={{ marginTop: 8, opacity: 0.8 }}>Loaded at {result.loadedAt}</div>
43
+ </div>
44
+ )
45
+ }
@@ -0,0 +1,3 @@
1
+ export default function Home() {
2
+ return <div>Home</div>
3
+ }
@@ -0,0 +1,23 @@
1
+ import type { RouteComponent } from '../../src'
2
+
3
+ type KitchenSinkParams = {
4
+ foo: string
5
+ baz: string
6
+ splat: string
7
+ optional?: string
8
+ two?: string
9
+ }
10
+
11
+ const KitchenSink: RouteComponent<KitchenSinkParams> = ({ foo, baz, splat, optional, two }) => {
12
+ return (
13
+ <div>
14
+ <div>foo: {foo}</div>
15
+ <div>baz: {baz}</div>
16
+ <div>splat: {splat}</div>
17
+ <div>optional: {optional}</div>
18
+ <div>two: {two}</div>
19
+ </div>
20
+ )
21
+ }
22
+
23
+ export default KitchenSink
@@ -0,0 +1,3 @@
1
+ export default function Login() {
2
+ return <div>Login</div>
3
+ }
@@ -0,0 +1,5 @@
1
+ import type { RouteParams } from '../../src'
2
+
3
+ export default function Match({ id }: RouteParams) {
4
+ return <div>Match: {id}</div>
5
+ }
@@ -0,0 +1,3 @@
1
+ export default function NotFound() {
2
+ return <div>Not found</div>
3
+ }
@@ -0,0 +1,8 @@
1
+ export default function SlowLoading() {
2
+ return (
3
+ <div>
4
+ <h2 style={{ marginTop: 0 }}>Slow loading page</h2>
5
+ <div>This page waits 2 seconds before its route component finishes loading.</div>
6
+ </div>
7
+ )
8
+ }
@@ -0,0 +1,105 @@
1
+ // Do not modify this file. It was auto-generated with the following command:
2
+ // $ rerouter ./examples/routes.ts -w -p
3
+
4
+ type AllOrNone<T> = Required<T> | { [K in keyof T]?: never }
5
+
6
+ type ParamType = string | number | boolean
7
+ type WildcardType = Iterable<ParamType>
8
+
9
+ export function home(): string {
10
+ let sb = ''
11
+
12
+ sb += '/'
13
+
14
+ return sb
15
+ }
16
+
17
+ export function kitchenSink(
18
+ params: { foo: ParamType; baz: ParamType; splat: WildcardType } & AllOrNone<{
19
+ optional: ParamType
20
+ two: ParamType
21
+ }>,
22
+ ): string {
23
+ let sb = ''
24
+
25
+ if (params['foo'] == null) throw new Error('Missing param: foo')
26
+ if (params['baz'] == null) throw new Error('Missing param: baz')
27
+ if (params['splat'] == null) throw new Error('Missing param: splat')
28
+ sb += '/hello/'
29
+ sb += encodeURIComponent(String(params['foo']))
30
+ sb += '/bar/'
31
+ sb += encodeURIComponent(String(params['baz']))
32
+ sb += '/'
33
+ sb += Array.from(params['splat'], (v) => encodeURIComponent(String(v))).join('/')
34
+ sb += '/xxx'
35
+ if (params['optional'] != null && params['two'] != null) {
36
+ sb += '/'
37
+ sb += encodeURIComponent(String(params['optional']))
38
+ sb += '/lol/'
39
+ sb += encodeURIComponent(String(params['two']))
40
+ } else if (!(params['optional'] == null && params['two'] == null)) {
41
+ throw new Error('Group requires all-or-none: "optional", "two"')
42
+ }
43
+
44
+ return sb
45
+ }
46
+
47
+ export function blogPost(params: { id: ParamType } & AllOrNone<{ title: ParamType }>): string {
48
+ let sb = ''
49
+
50
+ if (params['id'] == null) throw new Error('Missing param: id')
51
+ sb += '/blog/'
52
+ sb += encodeURIComponent(String(params['id']))
53
+ if (params['title'] != null) {
54
+ sb += '-'
55
+ sb += encodeURIComponent(String(params['title']))
56
+ } else if (!(params['title'] == null)) {
57
+ throw new Error('Group requires all-or-none: "title"')
58
+ }
59
+
60
+ return sb
61
+ }
62
+
63
+ export function slowLoading(): string {
64
+ let sb = ''
65
+
66
+ sb += '/slow-loading'
67
+
68
+ return sb
69
+ }
70
+
71
+ export function fetchLoading(): string {
72
+ let sb = ''
73
+
74
+ sb += '/fetch-loading'
75
+
76
+ return sb
77
+ }
78
+
79
+ export function fetchLoadingItem(params: { id: ParamType }): string {
80
+ let sb = ''
81
+
82
+ if (params['id'] == null) throw new Error('Missing param: id')
83
+ sb += '/fetch-loading/'
84
+ sb += encodeURIComponent(String(params['id']))
85
+
86
+ return sb
87
+ }
88
+
89
+ export function login(): string {
90
+ let sb = ''
91
+
92
+ sb += '/login'
93
+
94
+ return sb
95
+ }
96
+
97
+ export function match(params: { id: ParamType }): string {
98
+ let sb = ''
99
+
100
+ if (params['id'] == null) throw new Error('Missing param: id')
101
+ sb += '/matches/'
102
+ sb += encodeURIComponent(String(params['id']))
103
+
104
+ return sb
105
+ }
@@ -0,0 +1,40 @@
1
+ import type { Routes } from '@mpen/rerouter'
2
+
3
+ const loadFetchLoading = () => import('./pages/FetchLoading')
4
+
5
+ const ROUTES: Routes = [
6
+ { name: 'home', pattern: '/', component: () => import('./pages/Home') },
7
+ {
8
+ name: 'kitchenSink',
9
+ pattern: '/hello/:foo/bar/:baz/*splat/xxx{/:optional/lol/:two}',
10
+ component: () => import('./pages/KitchenSink'),
11
+ },
12
+ {
13
+ name: 'blogPost',
14
+ pattern: '/blog/:id(\\d+){-:title}?',
15
+ component: () => import('./pages/BlogPost'),
16
+ },
17
+ {
18
+ name: 'slowLoading',
19
+ pattern: '/slow-loading',
20
+ component: () =>
21
+ new Promise((resolve) => {
22
+ setTimeout(resolve, 2000)
23
+ }).then(() => import('./pages/SlowLoading')),
24
+ },
25
+ {
26
+ name: 'fetchLoading',
27
+ pattern: '/fetch-loading',
28
+ component: loadFetchLoading,
29
+ },
30
+ {
31
+ name: 'fetchLoadingItem',
32
+ pattern: '/fetch-loading/:id',
33
+ component: loadFetchLoading,
34
+ },
35
+ { name: 'login', pattern: '/login', component: () => import('./pages/Login') },
36
+ { name: 'match', pattern: '/matches/:id', component: () => import('./pages/Match') },
37
+ { name: 'notFound', pattern: '*', component: () => import('./pages/NotFound') },
38
+ ]
39
+
40
+ export default ROUTES
@@ -0,0 +1,33 @@
1
+ import { fileURLToPath } from 'node:url'
2
+ import { join } from 'node:path'
3
+
4
+ const distPath = fileURLToPath(new URL('../dist/', import.meta.url))
5
+ const index = Bun.file(join(distPath, 'index.html'))
6
+
7
+ async function fileForPath(pathname: string) {
8
+ const requestedPath = pathname === '/' ? 'index.html' : pathname.slice(1)
9
+ const file = Bun.file(join(distPath, requestedPath))
10
+
11
+ if (await file.exists()) return file
12
+ if (pathname.startsWith('/_bun/') || requestedPath.split('/').at(-1)?.includes('.'))
13
+ return undefined
14
+
15
+ return index
16
+ }
17
+
18
+ const server = Bun.serve({
19
+ async fetch(request) {
20
+ const url = new URL(request.url)
21
+ const file = await fileForPath(url.pathname)
22
+
23
+ if (!file) return new Response('Not found', { status: 404 })
24
+
25
+ return new Response(file, {
26
+ headers: {
27
+ 'Cache-Control': 'no-store',
28
+ },
29
+ })
30
+ },
31
+ })
32
+
33
+ console.log(`Serving production build at ${server.url}`)
@@ -0,0 +1,9 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "lib": ["ESNext"],
5
+ "types": ["bun"]
6
+ },
7
+ "include": ["serve-dist.ts"],
8
+ "exclude": ["**/*.test.*"]
9
+ }
package/package.json CHANGED
@@ -1,39 +1,49 @@
1
1
  {
2
2
  "name": "@mpen/rerouter",
3
- "version": "0.1.9",
4
- "packageManager": "bun",
5
- "exports": "./dist/bundle.cjs",
6
- "module": "./dist/bundle.mjs",
7
- "types": "./dist/bundle.d.ts",
8
- "files": [
9
- "./dist"
10
- ],
3
+ "description": "Lightweight type-safe router for React with URL helper generation.",
4
+ "version": "0.3.1",
5
+ "exports": {
6
+ ".": "./dist/index.js",
7
+ "./bin": "./dist/bin.js",
8
+ "./package.json": "./package.json"
9
+ },
10
+ "bin": {
11
+ "rerouter": "./dist/bin.js"
12
+ },
11
13
  "type": "module",
12
- "devDependencies": {
13
- "@rollup/plugin-commonjs": "^25.0.4",
14
- "@rollup/plugin-node-resolve": "^15.2.1",
15
- "@rollup/plugin-replace": "^5.0.2",
16
- "@rollup/plugin-terser": "^0.4.3",
17
- "@rollup/plugin-typescript": "^11.1.3",
18
- "bun-types": "^1.0.2",
19
- "chalk": "^5.3.0",
20
- "npm-run-all": "^4.1.5",
21
- "rimraf": "^5.0.1",
22
- "rollup": "^3.29.2",
23
- "tslib": "^2.6.2",
24
- "typescript": "^5.2.2"
14
+ "dependencies": {
15
+ "@mpen/classcat": "0.1.3",
16
+ "@mpen/ts-types": "0.1.2",
17
+ "path-to-regexp": "^8.3.0"
25
18
  },
26
- "engines": {
27
- "node": ">=10"
19
+ "peerDependencies": {
20
+ "react": "^19",
21
+ "typescript": "^5"
22
+ },
23
+ "devDependencies": {
24
+ "@testing-library/react": "^16.3.2",
25
+ "@types/node": "^22",
26
+ "@types/react": "^19",
27
+ "@types/react-dom": "^19.2.3",
28
+ "happy-dom": "^20.9.0",
29
+ "react-dom": "^19.2.3",
30
+ "tsdown": "^0.21"
28
31
  },
29
- "license": "MIT",
30
32
  "scripts": {
31
- "test": "bun test --watch src",
32
- "dev": "bun run --hot src/dev.ts",
33
- "bundle:clean": "rimraf -g \"dist/*\"",
34
- "bundle:build": "rollup -c",
35
- "bundle": "run-s bundle:clean bundle:build",
36
- "patch": "npm version patch && VER=$(jq -r '.version' package.json) && hg ci -m \"Publish v$VER\" && hg tag \"v$VER\"",
37
- "release": "run-s bundle patch && npm publish && hg push"
33
+ "build": "tsdown",
34
+ "gen": "bun cli/bin.ts ./examples/routes.ts -w -p",
35
+ "serve": "bun --hot examples/index.html",
36
+ "dev": "bun run --sequential gen serve",
37
+ "prod": "bun run gen && bun build --production --splitting examples/index.html --outdir examples/dist && bun examples/server/serve-dist.ts"
38
+ },
39
+ "types": "./dist/index.d.ts",
40
+ "publishConfig": {
41
+ "access": "public"
42
+ },
43
+ "main": "./dist/index.js",
44
+ "module": "./dist/index.js",
45
+ "inlinedDependencies": {
46
+ "prettier": "3.8.3",
47
+ "process": "0.11.10"
38
48
  }
39
49
  }