jotai-iten 0.4.2 → 0.5.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 +35 -38
- package/dist/create-router.d.cts +4 -1
- package/dist/create-router.d.ts +4 -1
- package/dist/headless-core.cjs +4 -1
- package/dist/headless-core.d.cts +5 -1
- package/dist/headless-core.d.ts +5 -1
- package/dist/headless-core.mjs +4 -1
- package/dist/types.d.cts +4 -2
- package/dist/types.d.ts +4 -2
- package/dist/url.cjs +1 -0
- package/dist/url.mjs +1 -0
- package/package.json +2 -2
- package/src/create-router.ts +7 -1
- package/src/headless-core.ts +22 -2
- package/src/types.ts +4 -0
- package/src/url.ts +1 -0
package/README.md
CHANGED
|
@@ -67,9 +67,7 @@ The current route stays mounted until the target route is ready. Loader failures
|
|
|
67
67
|
// router.ts
|
|
68
68
|
import {
|
|
69
69
|
createRouter,
|
|
70
|
-
createRoute,
|
|
71
70
|
defineRoutes,
|
|
72
|
-
type InferRoutes,
|
|
73
71
|
route,
|
|
74
72
|
} from 'jotai-iten'
|
|
75
73
|
|
|
@@ -79,12 +77,9 @@ const routes = defineRoutes({
|
|
|
79
77
|
settings: route(),
|
|
80
78
|
})
|
|
81
79
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
export const router = createRouter<Routes, unknown>({
|
|
87
|
-
initial: toRoute({ name: 'home' }),
|
|
80
|
+
export const router = createRouter({
|
|
81
|
+
routes,
|
|
82
|
+
initial: { name: 'home' },
|
|
88
83
|
})
|
|
89
84
|
|
|
90
85
|
export const {
|
|
@@ -100,7 +95,7 @@ export const {
|
|
|
100
95
|
|
|
101
96
|
```tsx
|
|
102
97
|
// App.tsx
|
|
103
|
-
import { Navigate, Route, Switch,
|
|
98
|
+
import { Navigate, Route, Switch, router } from './router'
|
|
104
99
|
|
|
105
100
|
export function App() {
|
|
106
101
|
return (
|
|
@@ -108,7 +103,7 @@ export function App() {
|
|
|
108
103
|
<Route name="home">{() => <HomeView />}</Route>
|
|
109
104
|
<Route name="detail">{({ id }) => <DetailView id={id} />}</Route>
|
|
110
105
|
<Route name="settings">{() => <SettingsView />}</Route>
|
|
111
|
-
<Navigate to={
|
|
106
|
+
<Navigate to={router.to({ name: 'home' })} />
|
|
112
107
|
</Switch>
|
|
113
108
|
)
|
|
114
109
|
}
|
|
@@ -125,9 +120,7 @@ Use `jotai-iten/headless` when you want atoms and hooks but do not need `Route`,
|
|
|
125
120
|
```ts
|
|
126
121
|
import {
|
|
127
122
|
createHeadlessRouter,
|
|
128
|
-
createRoute,
|
|
129
123
|
defineRoutes,
|
|
130
|
-
type InferRoutes,
|
|
131
124
|
route,
|
|
132
125
|
} from 'jotai-iten/headless'
|
|
133
126
|
|
|
@@ -136,12 +129,9 @@ const routes = defineRoutes({
|
|
|
136
129
|
detail: route<{ id: string }>(),
|
|
137
130
|
})
|
|
138
131
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
export const router = createHeadlessRouter<Routes, unknown>({
|
|
144
|
-
initial: toRoute({ name: 'home' }),
|
|
132
|
+
export const router = createHeadlessRouter({
|
|
133
|
+
routes,
|
|
134
|
+
initial: { name: 'home' },
|
|
145
135
|
})
|
|
146
136
|
|
|
147
137
|
export const { atoms, useNavigate, useRoute, useCurrentRoute } = router
|
|
@@ -153,11 +143,18 @@ export const { atoms, useNavigate, useRoute, useCurrentRoute } = router
|
|
|
153
143
|
|
|
154
144
|
## Creating Routes
|
|
155
145
|
|
|
156
|
-
Use `defineRoutes`
|
|
146
|
+
Use `defineRoutes` with `createRouter` or `createHeadlessRouter` for inferred route maps. The returned router exposes `router.to(...)` for typed route targets.
|
|
157
147
|
|
|
158
148
|
```ts
|
|
159
|
-
|
|
149
|
+
router.to({ name: 'home' })
|
|
150
|
+
router.to({ name: 'detail', params: { id: '42' } })
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Use `InferRoutes` plus `createRoute` when route types or factories need to live independently from a router instance.
|
|
160
154
|
|
|
155
|
+
```ts
|
|
156
|
+
type Routes = InferRoutes<typeof routes>
|
|
157
|
+
const toRoute = createRoute(routes)
|
|
161
158
|
toRoute({ name: 'home' })
|
|
162
159
|
toRoute({ name: 'detail', params: { id: '42' } })
|
|
163
160
|
```
|
|
@@ -171,8 +168,9 @@ For no-param routes, call `route()` without a type argument. Avoid `route<Record
|
|
|
171
168
|
Loaders run before the target route commits.
|
|
172
169
|
|
|
173
170
|
```ts
|
|
174
|
-
export const router = createRouter
|
|
175
|
-
|
|
171
|
+
export const router = createRouter({
|
|
172
|
+
routes,
|
|
173
|
+
initial: { name: 'home' },
|
|
176
174
|
queryClient,
|
|
177
175
|
routeConfig: {
|
|
178
176
|
detail: {
|
|
@@ -205,12 +203,13 @@ The `queryClient` only needs an `ensureQueryData` method. TanStack Query works,
|
|
|
205
203
|
```ts
|
|
206
204
|
import { authAtom } from './atoms'
|
|
207
205
|
|
|
208
|
-
const router = createRouter
|
|
209
|
-
|
|
206
|
+
const router = createRouter({
|
|
207
|
+
routes,
|
|
208
|
+
initial: { name: 'home' },
|
|
210
209
|
routeConfig: {
|
|
211
210
|
detail: {
|
|
212
|
-
beforeLoad: ({ get }) => {
|
|
213
|
-
if (!get(authAtom).userId) return
|
|
211
|
+
beforeLoad: ({ get, to }) => {
|
|
212
|
+
if (!get(authAtom).userId) return to({ name: 'home' })
|
|
214
213
|
},
|
|
215
214
|
loader: async ({ params, queryClient }) => {
|
|
216
215
|
await queryClient.ensureQueryData(detailQuery(params.id))
|
|
@@ -229,8 +228,9 @@ Redirect loops are capped by `iten-core` and become retryable errors instead of
|
|
|
229
228
|
Use `context` to compute shared values once per navigation. It can be a static object or a function that reads atoms.
|
|
230
229
|
|
|
231
230
|
```ts
|
|
232
|
-
const router = createRouter
|
|
233
|
-
|
|
231
|
+
const router = createRouter({
|
|
232
|
+
routes,
|
|
233
|
+
initial: { name: 'home' },
|
|
234
234
|
context: ({ get }) => ({ userId: get(authAtom).userId }),
|
|
235
235
|
routeConfig: {
|
|
236
236
|
detail: {
|
|
@@ -284,7 +284,7 @@ Renders the first matching child. Use `<Navigate>` as a fallback.
|
|
|
284
284
|
<Switch>
|
|
285
285
|
<Route name="home">{() => <HomeView />}</Route>
|
|
286
286
|
<Route name="detail">{({ id }) => <DetailView id={id} />}</Route>
|
|
287
|
-
<Navigate to={
|
|
287
|
+
<Navigate to={router.to({ name: 'home' })} />
|
|
288
288
|
</Switch>
|
|
289
289
|
```
|
|
290
290
|
|
|
@@ -293,7 +293,7 @@ Renders the first matching child. Use `<Navigate>` as a fallback.
|
|
|
293
293
|
Typed navigation with route-specific loading state.
|
|
294
294
|
|
|
295
295
|
```tsx
|
|
296
|
-
<Link to={
|
|
296
|
+
<Link to={router.to({ name: 'detail', params: { id: item.id } })}>
|
|
297
297
|
{({ isLoading }) => (isLoading ? 'Loading...' : 'Open')}
|
|
298
298
|
</Link>
|
|
299
299
|
```
|
|
@@ -303,7 +303,7 @@ Typed navigation with route-specific loading state.
|
|
|
303
303
|
Redirects on mount.
|
|
304
304
|
|
|
305
305
|
```tsx
|
|
306
|
-
{!isAuthenticated && <Navigate to={
|
|
306
|
+
{!isAuthenticated && <Navigate to={router.to({ name: 'home' })} />}
|
|
307
307
|
```
|
|
308
308
|
|
|
309
309
|
---
|
|
@@ -333,7 +333,7 @@ function Header() {
|
|
|
333
333
|
<button
|
|
334
334
|
type="button"
|
|
335
335
|
aria-current={isActive ? 'page' : undefined}
|
|
336
|
-
onClick={() => void navigate({ target:
|
|
336
|
+
onClick={() => void navigate({ target: router.to({ name: 'settings' }) })}
|
|
337
337
|
>
|
|
338
338
|
{isLoading ? 'Loading...' : 'Settings'}
|
|
339
339
|
</button>
|
|
@@ -428,11 +428,8 @@ const modals = defineRoutes({
|
|
|
428
428
|
imagePicker: route<{ onSelect: (uri: string) => void }>(),
|
|
429
429
|
})
|
|
430
430
|
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
export const modalRoute = createRoute(modals)
|
|
434
|
-
|
|
435
|
-
export const modalRouter = createRouter<Modals, unknown>({
|
|
431
|
+
export const modalRouter = createRouter({
|
|
432
|
+
routes: modals,
|
|
436
433
|
initial: null,
|
|
437
434
|
})
|
|
438
435
|
```
|
|
@@ -490,7 +487,7 @@ const urlSync = createUrlSync<Routes>({
|
|
|
490
487
|
router,
|
|
491
488
|
parse: ({ url }) => {
|
|
492
489
|
const id = url.searchParams.get('id')
|
|
493
|
-
return id ?
|
|
490
|
+
return id ? router.to({ name: 'detail', params: { id } }) : router.to({ name: 'home' })
|
|
494
491
|
},
|
|
495
492
|
format: ({ route, url }) => {
|
|
496
493
|
const next = new URL(url)
|
package/dist/create-router.d.cts
CHANGED
|
@@ -4,7 +4,7 @@ import { LinkComponent } from "./components/Link.cjs";
|
|
|
4
4
|
import { NavigateComponent } from "./components/Navigate.cjs";
|
|
5
5
|
import { RouteComponent } from "./components/Route.cjs";
|
|
6
6
|
import { SwitchComponent } from "./components/Switch.cjs";
|
|
7
|
-
import { RouteMapDef } from "iten-core";
|
|
7
|
+
import { InferRoutes, RouteDefinitions, RouteMapDef } from "iten-core";
|
|
8
8
|
|
|
9
9
|
//#region src/create-router.d.ts
|
|
10
10
|
type JotaiRouter<M extends RouteMapDef, _Ctx = unknown> = HeadlessJotaiRouter<M> & {
|
|
@@ -13,6 +13,9 @@ type JotaiRouter<M extends RouteMapDef, _Ctx = unknown> = HeadlessJotaiRouter<M>
|
|
|
13
13
|
Link: LinkComponent<M>;
|
|
14
14
|
Navigate: NavigateComponent<M>;
|
|
15
15
|
};
|
|
16
|
+
declare function createRouter<const Defs extends RouteDefinitions, Ctx = unknown>(config: JotaiRouterConfig<InferRoutes<Defs>, Ctx> & {
|
|
17
|
+
routes: Defs;
|
|
18
|
+
}): JotaiRouter<InferRoutes<Defs>, Ctx>;
|
|
16
19
|
declare function createRouter<M extends RouteMapDef, Ctx = unknown>(config: JotaiRouterConfig<M, Ctx>): JotaiRouter<M, Ctx>;
|
|
17
20
|
//#endregion
|
|
18
21
|
export { JotaiRouter, createRouter };
|
package/dist/create-router.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { LinkComponent } from "./components/Link.js";
|
|
|
4
4
|
import { NavigateComponent } from "./components/Navigate.js";
|
|
5
5
|
import { RouteComponent } from "./components/Route.js";
|
|
6
6
|
import { SwitchComponent } from "./components/Switch.js";
|
|
7
|
-
import { RouteMapDef } from "iten-core";
|
|
7
|
+
import { InferRoutes, RouteDefinitions, RouteMapDef } from "iten-core";
|
|
8
8
|
|
|
9
9
|
//#region src/create-router.d.ts
|
|
10
10
|
type JotaiRouter<M extends RouteMapDef, _Ctx = unknown> = HeadlessJotaiRouter<M> & {
|
|
@@ -13,6 +13,9 @@ type JotaiRouter<M extends RouteMapDef, _Ctx = unknown> = HeadlessJotaiRouter<M>
|
|
|
13
13
|
Link: LinkComponent<M>;
|
|
14
14
|
Navigate: NavigateComponent<M>;
|
|
15
15
|
};
|
|
16
|
+
declare function createRouter<const Defs extends RouteDefinitions, Ctx = unknown>(config: JotaiRouterConfig<InferRoutes<Defs>, Ctx> & {
|
|
17
|
+
routes: Defs;
|
|
18
|
+
}): JotaiRouter<InferRoutes<Defs>, Ctx>;
|
|
16
19
|
declare function createRouter<M extends RouteMapDef, Ctx = unknown>(config: JotaiRouterConfig<M, Ctx>): JotaiRouter<M, Ctx>;
|
|
17
20
|
//#endregion
|
|
18
21
|
export { JotaiRouter, createRouter };
|
package/dist/headless-core.cjs
CHANGED
|
@@ -16,7 +16,8 @@ function createHeadlessRouter(config) {
|
|
|
16
16
|
const wrapped = beforeLoad ? (input) => beforeLoad({
|
|
17
17
|
params: input.params,
|
|
18
18
|
get: _currentGet,
|
|
19
|
-
context: input.context
|
|
19
|
+
context: input.context,
|
|
20
|
+
to: input.to
|
|
20
21
|
}) : void 0;
|
|
21
22
|
return [key, {
|
|
22
23
|
...rest,
|
|
@@ -25,6 +26,7 @@ function createHeadlessRouter(config) {
|
|
|
25
26
|
})) : void 0;
|
|
26
27
|
const core = (0, iten_core.createItenCore)({
|
|
27
28
|
initial: config.initial,
|
|
29
|
+
routes: config.routes,
|
|
28
30
|
routeConfig: coreRouteConfig,
|
|
29
31
|
maxHistoryLength: config.maxHistoryLength,
|
|
30
32
|
queryClient: config.queryClient,
|
|
@@ -47,6 +49,7 @@ function createHeadlessRouter(config) {
|
|
|
47
49
|
};
|
|
48
50
|
return {
|
|
49
51
|
atoms,
|
|
52
|
+
to: core.to,
|
|
50
53
|
...require_hooks.makeHooks(atoms)
|
|
51
54
|
};
|
|
52
55
|
}
|
package/dist/headless-core.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { JotaiRouteConfig, JotaiRouterConfig, NoParams, QueryClientLike, RouteConfigMap, RouteMap as RouteMap$1, RouteMapDef as RouteMapDef$1, RouteMatcher, RouteName, RouteOf, RouteParams, RouteUnion as RouteUnion$1, RouterError as RouterError$1, RouterState as RouterState$1, UseRouteResult } from "./types.cjs";
|
|
2
2
|
import { HookBundle } from "./hooks.cjs";
|
|
3
|
-
import { NavigateInput, RouteMapDef, RouterState } from "iten-core";
|
|
3
|
+
import { InferRoutes, NavigateInput, RouteDefinitions, RouteFactory, RouteMapDef, RouterState } from "iten-core";
|
|
4
4
|
import { Atom, WritableAtom } from "jotai";
|
|
5
5
|
|
|
6
6
|
//#region src/headless-core.d.ts
|
|
@@ -11,7 +11,11 @@ type RouterAtoms<M extends RouteMapDef> = {
|
|
|
11
11
|
};
|
|
12
12
|
type HeadlessJotaiRouter<M extends RouteMapDef> = HookBundle<M> & {
|
|
13
13
|
atoms: RouterAtoms<M>;
|
|
14
|
+
to: RouteFactory<M>;
|
|
14
15
|
};
|
|
16
|
+
declare function createHeadlessRouter<const Defs extends RouteDefinitions, Ctx = unknown>(config: JotaiRouterConfig<InferRoutes<Defs>, Ctx> & {
|
|
17
|
+
routes: Defs;
|
|
18
|
+
}): HeadlessJotaiRouter<InferRoutes<Defs>>;
|
|
15
19
|
declare function createHeadlessRouter<M extends RouteMapDef, Ctx = unknown>(config: JotaiRouterConfig<M, Ctx>): HeadlessJotaiRouter<M>;
|
|
16
20
|
//#endregion
|
|
17
21
|
export { HeadlessJotaiRouter, RouterAtoms, createHeadlessRouter };
|
package/dist/headless-core.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { JotaiRouteConfig, JotaiRouterConfig, NoParams, QueryClientLike, RouteConfigMap, RouteMap as RouteMap$1, RouteMapDef as RouteMapDef$1, RouteMatcher, RouteName, RouteOf, RouteParams, RouteUnion as RouteUnion$1, RouterError as RouterError$1, RouterState as RouterState$1, UseRouteResult } from "./types.js";
|
|
2
2
|
import { HookBundle } from "./hooks.js";
|
|
3
|
-
import { NavigateInput, RouteMapDef, RouterState } from "iten-core";
|
|
3
|
+
import { InferRoutes, NavigateInput, RouteDefinitions, RouteFactory, RouteMapDef, RouterState } from "iten-core";
|
|
4
4
|
import { Atom, WritableAtom } from "jotai";
|
|
5
5
|
|
|
6
6
|
//#region src/headless-core.d.ts
|
|
@@ -11,7 +11,11 @@ type RouterAtoms<M extends RouteMapDef> = {
|
|
|
11
11
|
};
|
|
12
12
|
type HeadlessJotaiRouter<M extends RouteMapDef> = HookBundle<M> & {
|
|
13
13
|
atoms: RouterAtoms<M>;
|
|
14
|
+
to: RouteFactory<M>;
|
|
14
15
|
};
|
|
16
|
+
declare function createHeadlessRouter<const Defs extends RouteDefinitions, Ctx = unknown>(config: JotaiRouterConfig<InferRoutes<Defs>, Ctx> & {
|
|
17
|
+
routes: Defs;
|
|
18
|
+
}): HeadlessJotaiRouter<InferRoutes<Defs>>;
|
|
15
19
|
declare function createHeadlessRouter<M extends RouteMapDef, Ctx = unknown>(config: JotaiRouterConfig<M, Ctx>): HeadlessJotaiRouter<M>;
|
|
16
20
|
//#endregion
|
|
17
21
|
export { HeadlessJotaiRouter, RouterAtoms, createHeadlessRouter };
|
package/dist/headless-core.mjs
CHANGED
|
@@ -16,7 +16,8 @@ function createHeadlessRouter(config) {
|
|
|
16
16
|
const wrapped = beforeLoad ? (input) => beforeLoad({
|
|
17
17
|
params: input.params,
|
|
18
18
|
get: _currentGet,
|
|
19
|
-
context: input.context
|
|
19
|
+
context: input.context,
|
|
20
|
+
to: input.to
|
|
20
21
|
}) : void 0;
|
|
21
22
|
return [key, {
|
|
22
23
|
...rest,
|
|
@@ -25,6 +26,7 @@ function createHeadlessRouter(config) {
|
|
|
25
26
|
})) : void 0;
|
|
26
27
|
const core = createItenCore({
|
|
27
28
|
initial: config.initial,
|
|
29
|
+
routes: config.routes,
|
|
28
30
|
routeConfig: coreRouteConfig,
|
|
29
31
|
maxHistoryLength: config.maxHistoryLength,
|
|
30
32
|
queryClient: config.queryClient,
|
|
@@ -47,6 +49,7 @@ function createHeadlessRouter(config) {
|
|
|
47
49
|
};
|
|
48
50
|
return {
|
|
49
51
|
atoms,
|
|
52
|
+
to: core.to,
|
|
50
53
|
...makeHooks(atoms)
|
|
51
54
|
};
|
|
52
55
|
}
|
package/dist/types.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { InferRoutes, NoParams, QueryClientLike, RouteConfig, RouteConfigMap, RouteDefinition, RouteDefinitions, RouteMap as RouteMap$1, RouteMapDef as RouteMapDef$1, RouteMatcher, RouteName, RouteOf, RouteParams, RouteUnion as RouteUnion$1, RouterError as RouterError$1, RouterState as RouterState$1 } from "iten-core";
|
|
1
|
+
import { InferRoutes as InferRoutes$1, NoParams, QueryClientLike, RouteConfig, RouteConfigMap, RouteDefinition, RouteDefinitions as RouteDefinitions$1, RouteFactory as RouteFactory$1, RouteMap as RouteMap$1, RouteMapDef as RouteMapDef$1, RouteMatcher, RouteName, RouteOf, RouteParams, RouteUnion as RouteUnion$1, RouterError as RouterError$1, RouterState as RouterState$1 } from "iten-core";
|
|
2
2
|
import { Getter } from "jotai";
|
|
3
3
|
|
|
4
4
|
//#region src/types.d.ts
|
|
@@ -8,10 +8,12 @@ type JotaiRouteConfig<M extends RouteMapDef$1, K extends keyof M, Ctx = unknown>
|
|
|
8
8
|
params: M[K];
|
|
9
9
|
get: Getter;
|
|
10
10
|
context: Ctx;
|
|
11
|
+
to: RouteFactory$1<M>;
|
|
11
12
|
}) => RouteUnion$1<M> | undefined | Promise<RouteUnion$1<M> | undefined>;
|
|
12
13
|
}>;
|
|
13
14
|
type JotaiRouterConfig<M extends RouteMapDef$1, Ctx = unknown> = {
|
|
14
15
|
initial: RouteUnion$1<M> | null;
|
|
16
|
+
routes?: RouteDefinitions$1 | undefined;
|
|
15
17
|
routeConfig?: { [K in keyof M]?: JotaiRouteConfig<M, K, Ctx> };
|
|
16
18
|
maxHistoryLength?: number | undefined;
|
|
17
19
|
context?: Ctx | ((input: {
|
|
@@ -27,4 +29,4 @@ type UseRouteResult<M extends RouteMapDef$1, K extends keyof M> = {
|
|
|
27
29
|
params: null;
|
|
28
30
|
};
|
|
29
31
|
//#endregion
|
|
30
|
-
export { type InferRoutes, JotaiRouteConfig, JotaiRouterConfig, type NoParams, type QueryClientLike, type RouteConfigMap, type RouteDefinition, type RouteDefinitions, type RouteMap$1 as RouteMap, type RouteMapDef$1 as RouteMapDef, type RouteMatcher, type RouteName, type RouteOf, type RouteParams, type RouteUnion$1 as RouteUnion, type RouterError$1 as RouterError, type RouterState$1 as RouterState, UseRouteResult };
|
|
32
|
+
export { type InferRoutes$1 as InferRoutes, JotaiRouteConfig, JotaiRouterConfig, type NoParams, type QueryClientLike, type RouteConfigMap, type RouteDefinition, type RouteDefinitions$1 as RouteDefinitions, type RouteMap$1 as RouteMap, type RouteMapDef$1 as RouteMapDef, type RouteMatcher, type RouteName, type RouteOf, type RouteParams, type RouteUnion$1 as RouteUnion, type RouterError$1 as RouterError, type RouterState$1 as RouterState, UseRouteResult };
|
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { InferRoutes, NoParams, QueryClientLike, RouteConfig, RouteConfigMap, RouteDefinition, RouteDefinitions, RouteMap as RouteMap$1, RouteMapDef as RouteMapDef$1, RouteMatcher, RouteName, RouteOf, RouteParams, RouteUnion as RouteUnion$1, RouterError as RouterError$1, RouterState as RouterState$1 } from "iten-core";
|
|
1
|
+
import { InferRoutes as InferRoutes$1, NoParams, QueryClientLike, RouteConfig, RouteConfigMap, RouteDefinition, RouteDefinitions as RouteDefinitions$1, RouteFactory as RouteFactory$1, RouteMap as RouteMap$1, RouteMapDef as RouteMapDef$1, RouteMatcher, RouteName, RouteOf, RouteParams, RouteUnion as RouteUnion$1, RouterError as RouterError$1, RouterState as RouterState$1 } from "iten-core";
|
|
2
2
|
import { Getter } from "jotai";
|
|
3
3
|
|
|
4
4
|
//#region src/types.d.ts
|
|
@@ -8,10 +8,12 @@ type JotaiRouteConfig<M extends RouteMapDef$1, K extends keyof M, Ctx = unknown>
|
|
|
8
8
|
params: M[K];
|
|
9
9
|
get: Getter;
|
|
10
10
|
context: Ctx;
|
|
11
|
+
to: RouteFactory$1<M>;
|
|
11
12
|
}) => RouteUnion$1<M> | undefined | Promise<RouteUnion$1<M> | undefined>;
|
|
12
13
|
}>;
|
|
13
14
|
type JotaiRouterConfig<M extends RouteMapDef$1, Ctx = unknown> = {
|
|
14
15
|
initial: RouteUnion$1<M> | null;
|
|
16
|
+
routes?: RouteDefinitions$1 | undefined;
|
|
15
17
|
routeConfig?: { [K in keyof M]?: JotaiRouteConfig<M, K, Ctx> };
|
|
16
18
|
maxHistoryLength?: number | undefined;
|
|
17
19
|
context?: Ctx | ((input: {
|
|
@@ -27,4 +29,4 @@ type UseRouteResult<M extends RouteMapDef$1, K extends keyof M> = {
|
|
|
27
29
|
params: null;
|
|
28
30
|
};
|
|
29
31
|
//#endregion
|
|
30
|
-
export { type InferRoutes, JotaiRouteConfig, JotaiRouterConfig, type NoParams, type QueryClientLike, type RouteConfigMap, type RouteDefinition, type RouteDefinitions, type RouteMap$1 as RouteMap, type RouteMapDef$1 as RouteMapDef, type RouteMatcher, type RouteName, type RouteOf, type RouteParams, type RouteUnion$1 as RouteUnion, type RouterError$1 as RouterError, type RouterState$1 as RouterState, UseRouteResult };
|
|
32
|
+
export { type InferRoutes$1 as InferRoutes, JotaiRouteConfig, JotaiRouterConfig, type NoParams, type QueryClientLike, type RouteConfigMap, type RouteDefinition, type RouteDefinitions$1 as RouteDefinitions, type RouteMap$1 as RouteMap, type RouteMapDef$1 as RouteMapDef, type RouteMatcher, type RouteName, type RouteOf, type RouteParams, type RouteUnion$1 as RouteUnion, type RouterError$1 as RouterError, type RouterState$1 as RouterState, UseRouteResult };
|
package/dist/url.cjs
CHANGED
|
@@ -5,6 +5,7 @@ let iten_core_url = require("iten-core/url");
|
|
|
5
5
|
function createUrlSync({ router, store = (0, jotai.getDefaultStore)(), ...input }) {
|
|
6
6
|
const coreLike = {
|
|
7
7
|
getState: () => store.get(router.atoms.state),
|
|
8
|
+
to: router.to,
|
|
8
9
|
navigate: (navigateInput) => store.set(router.atoms.navigate, navigateInput),
|
|
9
10
|
goBack: () => {
|
|
10
11
|
store.set(router.atoms.goBack);
|
package/dist/url.mjs
CHANGED
|
@@ -4,6 +4,7 @@ import { createUrlSync as createUrlSync$1 } from "iten-core/url";
|
|
|
4
4
|
function createUrlSync({ router, store = getDefaultStore(), ...input }) {
|
|
5
5
|
const coreLike = {
|
|
6
6
|
getState: () => store.get(router.atoms.state),
|
|
7
|
+
to: router.to,
|
|
7
8
|
navigate: (navigateInput) => store.set(router.atoms.navigate, navigateInput),
|
|
8
9
|
goBack: () => {
|
|
9
10
|
store.set(router.atoms.goBack);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jotai-iten",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Jotai adapter for iten — ultralight in-memory router for embedded JS apps",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"jotai",
|
|
@@ -108,7 +108,7 @@
|
|
|
108
108
|
}
|
|
109
109
|
},
|
|
110
110
|
"dependencies": {
|
|
111
|
-
"iten-core": "^0.
|
|
111
|
+
"iten-core": "^0.5.0"
|
|
112
112
|
},
|
|
113
113
|
"publishConfig": {
|
|
114
114
|
"access": "public",
|
package/src/create-router.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { RouteMapDef } from 'iten-core'
|
|
1
|
+
import type { InferRoutes, RouteDefinitions, RouteMapDef } from 'iten-core'
|
|
2
2
|
import type { LinkComponent } from './components/Link.tsx'
|
|
3
3
|
import { makeLink } from './components/Link.tsx'
|
|
4
4
|
import type { NavigateComponent } from './components/Navigate.tsx'
|
|
@@ -18,6 +18,12 @@ export type JotaiRouter<M extends RouteMapDef, _Ctx = unknown> = HeadlessJotaiRo
|
|
|
18
18
|
Navigate: NavigateComponent<M>
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
export function createRouter<const Defs extends RouteDefinitions, Ctx = unknown>(
|
|
22
|
+
config: JotaiRouterConfig<InferRoutes<Defs>, Ctx> & { routes: Defs },
|
|
23
|
+
): JotaiRouter<InferRoutes<Defs>, Ctx>
|
|
24
|
+
export function createRouter<M extends RouteMapDef, Ctx = unknown>(
|
|
25
|
+
config: JotaiRouterConfig<M, Ctx>,
|
|
26
|
+
): JotaiRouter<M, Ctx>
|
|
21
27
|
export function createRouter<M extends RouteMapDef, Ctx = unknown>(
|
|
22
28
|
config: JotaiRouterConfig<M, Ctx>,
|
|
23
29
|
): JotaiRouter<M, Ctx> {
|
package/src/headless-core.ts
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
InferRoutes,
|
|
3
|
+
NavigateInput,
|
|
4
|
+
RouteConfigMap,
|
|
5
|
+
RouteDefinitions,
|
|
6
|
+
RouteFactory,
|
|
7
|
+
RouteMapDef,
|
|
8
|
+
RouterState,
|
|
9
|
+
RouteUnion,
|
|
10
|
+
} from 'iten-core'
|
|
2
11
|
import { createItenCore } from 'iten-core'
|
|
3
12
|
import type { Atom, Getter, WritableAtom } from 'jotai'
|
|
4
13
|
import { atom } from 'jotai'
|
|
@@ -40,8 +49,15 @@ export type RouterAtoms<M extends RouteMapDef> = {
|
|
|
40
49
|
|
|
41
50
|
export type HeadlessJotaiRouter<M extends RouteMapDef> = HookBundle<M> & {
|
|
42
51
|
atoms: RouterAtoms<M>
|
|
52
|
+
to: RouteFactory<M>
|
|
43
53
|
}
|
|
44
54
|
|
|
55
|
+
export function createHeadlessRouter<const Defs extends RouteDefinitions, Ctx = unknown>(
|
|
56
|
+
config: JotaiRouterConfig<InferRoutes<Defs>, Ctx> & { routes: Defs },
|
|
57
|
+
): HeadlessJotaiRouter<InferRoutes<Defs>>
|
|
58
|
+
export function createHeadlessRouter<M extends RouteMapDef, Ctx = unknown>(
|
|
59
|
+
config: JotaiRouterConfig<M, Ctx>,
|
|
60
|
+
): HeadlessJotaiRouter<M>
|
|
45
61
|
export function createHeadlessRouter<M extends RouteMapDef, Ctx = unknown>(
|
|
46
62
|
config: JotaiRouterConfig<M, Ctx>,
|
|
47
63
|
): HeadlessJotaiRouter<M> {
|
|
@@ -64,17 +80,19 @@ export function createHeadlessRouter<M extends RouteMapDef, Ctx = unknown>(
|
|
|
64
80
|
if (!route) return [key, route]
|
|
65
81
|
const { beforeLoad, ...rest } = route as JotaiRouteConfig<M, keyof M, Ctx>
|
|
66
82
|
const wrapped = beforeLoad
|
|
67
|
-
? (input: { params: M[keyof M]; context: Ctx }) =>
|
|
83
|
+
? (input: { params: M[keyof M]; context: Ctx; to: RouteFactory<M> }) =>
|
|
68
84
|
(
|
|
69
85
|
beforeLoad as (input: {
|
|
70
86
|
params: M[keyof M]
|
|
71
87
|
get: Getter
|
|
72
88
|
context: Ctx
|
|
89
|
+
to: RouteFactory<M>
|
|
73
90
|
}) => RouteUnion<M> | undefined | Promise<RouteUnion<M> | undefined>
|
|
74
91
|
)({
|
|
75
92
|
params: input.params,
|
|
76
93
|
get: _currentGet,
|
|
77
94
|
context: input.context,
|
|
95
|
+
to: input.to,
|
|
78
96
|
})
|
|
79
97
|
: undefined
|
|
80
98
|
return [key, { ...rest, beforeLoad: wrapped }]
|
|
@@ -84,6 +102,7 @@ export function createHeadlessRouter<M extends RouteMapDef, Ctx = unknown>(
|
|
|
84
102
|
|
|
85
103
|
const core = createItenCore<M, Ctx>({
|
|
86
104
|
initial: config.initial,
|
|
105
|
+
routes: config.routes,
|
|
87
106
|
routeConfig: coreRouteConfig,
|
|
88
107
|
maxHistoryLength: config.maxHistoryLength,
|
|
89
108
|
queryClient: config.queryClient,
|
|
@@ -121,6 +140,7 @@ export function createHeadlessRouter<M extends RouteMapDef, Ctx = unknown>(
|
|
|
121
140
|
|
|
122
141
|
return {
|
|
123
142
|
atoms,
|
|
143
|
+
to: core.to,
|
|
124
144
|
...makeHooks<M>(atoms),
|
|
125
145
|
}
|
|
126
146
|
}
|
package/src/types.ts
CHANGED
|
@@ -6,6 +6,7 @@ import type {
|
|
|
6
6
|
RouteConfigMap,
|
|
7
7
|
RouteDefinition,
|
|
8
8
|
RouteDefinitions,
|
|
9
|
+
RouteFactory,
|
|
9
10
|
RouteMap,
|
|
10
11
|
RouteMapDef,
|
|
11
12
|
RouteMatcher,
|
|
@@ -25,6 +26,7 @@ export type {
|
|
|
25
26
|
RouteConfigMap,
|
|
26
27
|
RouteDefinition,
|
|
27
28
|
RouteDefinitions,
|
|
29
|
+
RouteFactory,
|
|
28
30
|
RouteMap,
|
|
29
31
|
RouteMapDef,
|
|
30
32
|
RouteMatcher,
|
|
@@ -44,12 +46,14 @@ export type JotaiRouteConfig<M extends RouteMapDef, K extends keyof M, Ctx = unk
|
|
|
44
46
|
params: M[K]
|
|
45
47
|
get: Getter
|
|
46
48
|
context: Ctx
|
|
49
|
+
to: RouteFactory<M>
|
|
47
50
|
}) => RouteUnion<M> | undefined | Promise<RouteUnion<M> | undefined>
|
|
48
51
|
}
|
|
49
52
|
>
|
|
50
53
|
|
|
51
54
|
export type JotaiRouterConfig<M extends RouteMapDef, Ctx = unknown> = {
|
|
52
55
|
initial: RouteUnion<M> | null
|
|
56
|
+
routes?: RouteDefinitions | undefined
|
|
53
57
|
routeConfig?: { [K in keyof M]?: JotaiRouteConfig<M, K, Ctx> }
|
|
54
58
|
maxHistoryLength?: number | undefined
|
|
55
59
|
context?: Ctx | ((input: { get: Getter }) => Ctx)
|
package/src/url.ts
CHANGED
|
@@ -36,6 +36,7 @@ export function createUrlSync<M extends RouteMapDef>({
|
|
|
36
36
|
}: CreateUrlSyncInput<M>): UrlSync<M> {
|
|
37
37
|
const coreLike: ItenCore<M> = {
|
|
38
38
|
getState: () => store.get(router.atoms.state) as RouterState<M>,
|
|
39
|
+
to: router.to,
|
|
39
40
|
navigate: (navigateInput: NavigateInput<M>) => store.set(router.atoms.navigate, navigateInput),
|
|
40
41
|
goBack: () => {
|
|
41
42
|
void store.set(router.atoms.goBack)
|