react-iten 0.4.1 → 0.4.2
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 +103 -2
- package/dist/components/Link.cjs +21 -0
- package/dist/components/Link.d.cts +13 -0
- package/dist/components/Link.d.ts +13 -0
- package/dist/components/Link.mjs +21 -0
- package/dist/components/Navigate.cjs +15 -0
- package/dist/components/Navigate.d.cts +10 -0
- package/dist/components/Navigate.d.ts +10 -0
- package/dist/components/Navigate.mjs +15 -0
- package/dist/components/Route.cjs +22 -0
- package/dist/components/Route.d.cts +17 -0
- package/dist/components/Route.d.ts +17 -0
- package/dist/components/Route.mjs +22 -0
- package/dist/components/Switch.cjs +21 -0
- package/dist/components/Switch.d.cts +9 -0
- package/dist/components/Switch.d.ts +9 -0
- package/dist/components/Switch.mjs +21 -0
- package/dist/create-router.cjs +18 -0
- package/dist/create-router.d.cts +18 -0
- package/dist/create-router.d.ts +18 -0
- package/dist/create-router.mjs +18 -0
- package/dist/headless.cjs +83 -0
- package/dist/headless.d.cts +21 -0
- package/dist/headless.d.ts +21 -0
- package/dist/headless.mjs +40 -0
- package/dist/hooks.cjs +52 -0
- package/dist/hooks.d.cts +21 -0
- package/dist/hooks.d.ts +21 -0
- package/dist/hooks.mjs +52 -0
- package/dist/index.cjs +48 -0
- package/dist/index.d.cts +8 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.mjs +4 -0
- package/dist/types.d.cts +19 -0
- package/dist/types.d.ts +19 -0
- package/dist/url.cjs +20 -0
- package/dist/url.d.cts +14 -0
- package/dist/url.d.ts +14 -0
- package/dist/url.mjs +19 -0
- package/dist/utils.cjs +44 -0
- package/dist/utils.d.cts +3 -0
- package/dist/utils.d.ts +3 -0
- package/dist/utils.mjs +2 -0
- package/dist/zod.cjs +77 -0
- package/dist/zod.d.cts +48 -0
- package/dist/zod.d.ts +48 -0
- package/dist/zod.mjs +73 -0
- package/package.json +99 -5
- package/src/components/Link.tsx +36 -0
- package/src/components/Navigate.tsx +26 -0
- package/src/components/Route.tsx +53 -0
- package/src/components/Switch.tsx +30 -0
- package/src/create-router.ts +33 -0
- package/src/headless.ts +91 -0
- package/src/hooks.ts +74 -0
- package/src/index.ts +35 -0
- package/src/types.ts +47 -0
- package/src/url.ts +49 -0
- package/src/utils.ts +23 -0
- package/src/zod.ts +150 -0
- package/index.js +0 -1
package/README.md
CHANGED
|
@@ -1,5 +1,106 @@
|
|
|
1
1
|
# react-iten
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
React bindings for `iten`, an ultralight typed in-memory router for embedded JavaScript apps.
|
|
4
4
|
|
|
5
|
-
Use `
|
|
5
|
+
Use this package when you want `iten` route state and React hooks/components without Jotai. Use `jotai-iten` when router context or guards should read Jotai atoms directly.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install react-iten react
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
`react-iten` depends on `iten-core`. Install `@tanstack/react-query` only when route loaders call `queryClient.ensureQueryData`, and install `zod` only when using `react-iten/zod`.
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
import {
|
|
19
|
+
createRoute,
|
|
20
|
+
createRouter,
|
|
21
|
+
defineRoutes,
|
|
22
|
+
type InferRoutes,
|
|
23
|
+
route,
|
|
24
|
+
} from 'react-iten'
|
|
25
|
+
|
|
26
|
+
const routes = defineRoutes({
|
|
27
|
+
home: route(),
|
|
28
|
+
project: route<{ id: string }>(),
|
|
29
|
+
settings: route(),
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
type Routes = InferRoutes<typeof routes>
|
|
33
|
+
|
|
34
|
+
const toRoute = createRoute(routes)
|
|
35
|
+
|
|
36
|
+
const router = createRouter<Routes>({
|
|
37
|
+
initial: toRoute({ name: 'home' }),
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
export const { Link, Navigate, Route, Switch, useNavigate, useRoute } = router
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
```tsx
|
|
44
|
+
<Switch>
|
|
45
|
+
<Route name="home">{() => <Home />}</Route>
|
|
46
|
+
<Route name="project">{({ id }) => <Project id={id} />}</Route>
|
|
47
|
+
<Route name="settings">{() => <Settings />}</Route>
|
|
48
|
+
<Navigate to={toRoute({ name: 'home' })} />
|
|
49
|
+
</Switch>
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Headless Router
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
import { createHeadlessRouter } from 'react-iten/headless'
|
|
56
|
+
|
|
57
|
+
const router = createHeadlessRouter<Routes>({
|
|
58
|
+
initial: toRoute({ name: 'home' }),
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
router.store.getState()
|
|
62
|
+
await router.store.navigate({ target: toRoute({ name: 'settings' }) })
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
The store is scoped to the router instance and uses `useSyncExternalStore` for React subscriptions.
|
|
66
|
+
|
|
67
|
+
## URL Sync
|
|
68
|
+
|
|
69
|
+
`react-iten/url` keeps URL support explicit and optional.
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
import { createUrlSync } from 'react-iten/url'
|
|
73
|
+
|
|
74
|
+
const sync = createUrlSync({
|
|
75
|
+
router,
|
|
76
|
+
parse: ({ url }) => parseRoute(url),
|
|
77
|
+
format: ({ route }) => formatRoute(route),
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
await sync.hydrate()
|
|
81
|
+
sync.start()
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Zod Runtime Validation
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
import { z } from 'zod'
|
|
88
|
+
import { createZodRoute, defineZodRoutes, zodNoParams } from 'react-iten/zod'
|
|
89
|
+
|
|
90
|
+
const schemas = defineZodRoutes({
|
|
91
|
+
home: zodNoParams(),
|
|
92
|
+
project: z.object({ id: z.string().min(1) }).strict(),
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
const toRoute = createZodRoute(schemas)
|
|
96
|
+
|
|
97
|
+
toRoute({ name: 'project', input: { id: 'alpha' } })
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Entry Points
|
|
101
|
+
|
|
102
|
+
- `react-iten`: hooks, components, route utilities, and types
|
|
103
|
+
- `react-iten/headless`: hooks and scoped store without components
|
|
104
|
+
- `react-iten/url`: optional URL sync adapter
|
|
105
|
+
- `react-iten/zod`: optional Zod route factories and parsers
|
|
106
|
+
- `react-iten/utils`: route factories, guards, matching, and type utilities
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
let react = require("react");
|
|
2
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
3
|
+
//#region src/components/Link.tsx
|
|
4
|
+
function makeLink(hooks) {
|
|
5
|
+
const { useNavigate, useRouteLoading } = hooks;
|
|
6
|
+
function Link({ to, children }) {
|
|
7
|
+
const navigate = useNavigate();
|
|
8
|
+
const isLoading = useRouteLoading({ name: to.name });
|
|
9
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
|
|
10
|
+
href: "#",
|
|
11
|
+
onClick: (0, react.useCallback)((event) => {
|
|
12
|
+
event.preventDefault();
|
|
13
|
+
navigate({ target: to });
|
|
14
|
+
}, [navigate, to]),
|
|
15
|
+
children: children({ isLoading })
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
return Link;
|
|
19
|
+
}
|
|
20
|
+
//#endregion
|
|
21
|
+
exports.makeLink = makeLink;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { RouteMapDef, RouteUnion } from "iten-core";
|
|
2
|
+
import { ReactNode } from "react";
|
|
3
|
+
|
|
4
|
+
//#region src/components/Link.d.ts
|
|
5
|
+
type LinkProps<M extends RouteMapDef> = {
|
|
6
|
+
to: RouteUnion<M>;
|
|
7
|
+
children: (state: {
|
|
8
|
+
isLoading: boolean;
|
|
9
|
+
}) => ReactNode;
|
|
10
|
+
};
|
|
11
|
+
type LinkComponent<M extends RouteMapDef> = (props: LinkProps<M>) => ReactNode;
|
|
12
|
+
//#endregion
|
|
13
|
+
export { LinkComponent, LinkProps };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { RouteMapDef, RouteUnion } from "iten-core";
|
|
2
|
+
import { ReactNode } from "react";
|
|
3
|
+
|
|
4
|
+
//#region src/components/Link.d.ts
|
|
5
|
+
type LinkProps<M extends RouteMapDef> = {
|
|
6
|
+
to: RouteUnion<M>;
|
|
7
|
+
children: (state: {
|
|
8
|
+
isLoading: boolean;
|
|
9
|
+
}) => ReactNode;
|
|
10
|
+
};
|
|
11
|
+
type LinkComponent<M extends RouteMapDef> = (props: LinkProps<M>) => ReactNode;
|
|
12
|
+
//#endregion
|
|
13
|
+
export { LinkComponent, LinkProps };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { useCallback } from "react";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
//#region src/components/Link.tsx
|
|
4
|
+
function makeLink(hooks) {
|
|
5
|
+
const { useNavigate, useRouteLoading } = hooks;
|
|
6
|
+
function Link({ to, children }) {
|
|
7
|
+
const navigate = useNavigate();
|
|
8
|
+
const isLoading = useRouteLoading({ name: to.name });
|
|
9
|
+
return /* @__PURE__ */ jsx("a", {
|
|
10
|
+
href: "#",
|
|
11
|
+
onClick: useCallback((event) => {
|
|
12
|
+
event.preventDefault();
|
|
13
|
+
navigate({ target: to });
|
|
14
|
+
}, [navigate, to]),
|
|
15
|
+
children: children({ isLoading })
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
return Link;
|
|
19
|
+
}
|
|
20
|
+
//#endregion
|
|
21
|
+
export { makeLink };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
let react = require("react");
|
|
2
|
+
//#region src/components/Navigate.tsx
|
|
3
|
+
function makeNavigate(hooks) {
|
|
4
|
+
const { useNavigate } = hooks;
|
|
5
|
+
function Navigate({ to }) {
|
|
6
|
+
const navigate = useNavigate();
|
|
7
|
+
(0, react.useEffect)(() => {
|
|
8
|
+
navigate({ target: to });
|
|
9
|
+
}, []);
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
return Navigate;
|
|
13
|
+
}
|
|
14
|
+
//#endregion
|
|
15
|
+
exports.makeNavigate = makeNavigate;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { RouteMapDef, RouteUnion } from "iten-core";
|
|
2
|
+
import { ReactNode } from "react";
|
|
3
|
+
|
|
4
|
+
//#region src/components/Navigate.d.ts
|
|
5
|
+
type NavigateProps<M extends RouteMapDef> = {
|
|
6
|
+
to: RouteUnion<M>;
|
|
7
|
+
};
|
|
8
|
+
type NavigateComponent<M extends RouteMapDef> = (props: NavigateProps<M>) => ReactNode;
|
|
9
|
+
//#endregion
|
|
10
|
+
export { NavigateComponent, NavigateProps };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { RouteMapDef, RouteUnion } from "iten-core";
|
|
2
|
+
import { ReactNode } from "react";
|
|
3
|
+
|
|
4
|
+
//#region src/components/Navigate.d.ts
|
|
5
|
+
type NavigateProps<M extends RouteMapDef> = {
|
|
6
|
+
to: RouteUnion<M>;
|
|
7
|
+
};
|
|
8
|
+
type NavigateComponent<M extends RouteMapDef> = (props: NavigateProps<M>) => ReactNode;
|
|
9
|
+
//#endregion
|
|
10
|
+
export { NavigateComponent, NavigateProps };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { useEffect } from "react";
|
|
2
|
+
//#region src/components/Navigate.tsx
|
|
3
|
+
function makeNavigate(hooks) {
|
|
4
|
+
const { useNavigate } = hooks;
|
|
5
|
+
function Navigate({ to }) {
|
|
6
|
+
const navigate = useNavigate();
|
|
7
|
+
useEffect(() => {
|
|
8
|
+
navigate({ target: to });
|
|
9
|
+
}, []);
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
return Navigate;
|
|
13
|
+
}
|
|
14
|
+
//#endregion
|
|
15
|
+
export { makeNavigate };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
2
|
+
//#region src/components/Route.tsx
|
|
3
|
+
function makeRoute(hooks) {
|
|
4
|
+
const { useRoute, useIsNavigating, useRouterError } = hooks;
|
|
5
|
+
function Route({ name, children, component: Component, pendingComponent: PendingComponent, errorComponent: ErrorComponent }) {
|
|
6
|
+
const { isActive, params } = useRoute({ name });
|
|
7
|
+
const isNavigating = useIsNavigating();
|
|
8
|
+
const error = useRouterError();
|
|
9
|
+
if (!isActive) return null;
|
|
10
|
+
if (error && ErrorComponent) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ErrorComponent, {
|
|
11
|
+
error: error.error,
|
|
12
|
+
retry: error.retry
|
|
13
|
+
});
|
|
14
|
+
if (isNavigating && PendingComponent) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PendingComponent, {});
|
|
15
|
+
if (children) return children(params);
|
|
16
|
+
if (Component) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Component, { ...params });
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
return Route;
|
|
20
|
+
}
|
|
21
|
+
//#endregion
|
|
22
|
+
exports.makeRoute = makeRoute;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { RouteMapDef } from "iten-core";
|
|
2
|
+
import { ComponentType, ReactNode } from "react";
|
|
3
|
+
|
|
4
|
+
//#region src/components/Route.d.ts
|
|
5
|
+
type RouteProps<M extends RouteMapDef, K extends keyof M> = {
|
|
6
|
+
name: K;
|
|
7
|
+
children?: ((params: M[K]) => ReactNode) | undefined;
|
|
8
|
+
component?: ComponentType<M[K]> | undefined;
|
|
9
|
+
pendingComponent?: ComponentType | undefined;
|
|
10
|
+
errorComponent?: ComponentType<{
|
|
11
|
+
error: unknown;
|
|
12
|
+
retry: () => Promise<void>;
|
|
13
|
+
}> | undefined;
|
|
14
|
+
};
|
|
15
|
+
type RouteComponent<M extends RouteMapDef> = <K extends keyof M>(props: RouteProps<M, K>) => ReactNode;
|
|
16
|
+
//#endregion
|
|
17
|
+
export { RouteComponent, RouteProps };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { RouteMapDef } from "iten-core";
|
|
2
|
+
import { ComponentType, ReactNode } from "react";
|
|
3
|
+
|
|
4
|
+
//#region src/components/Route.d.ts
|
|
5
|
+
type RouteProps<M extends RouteMapDef, K extends keyof M> = {
|
|
6
|
+
name: K;
|
|
7
|
+
children?: ((params: M[K]) => ReactNode) | undefined;
|
|
8
|
+
component?: ComponentType<M[K]> | undefined;
|
|
9
|
+
pendingComponent?: ComponentType | undefined;
|
|
10
|
+
errorComponent?: ComponentType<{
|
|
11
|
+
error: unknown;
|
|
12
|
+
retry: () => Promise<void>;
|
|
13
|
+
}> | undefined;
|
|
14
|
+
};
|
|
15
|
+
type RouteComponent<M extends RouteMapDef> = <K extends keyof M>(props: RouteProps<M, K>) => ReactNode;
|
|
16
|
+
//#endregion
|
|
17
|
+
export { RouteComponent, RouteProps };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
//#region src/components/Route.tsx
|
|
3
|
+
function makeRoute(hooks) {
|
|
4
|
+
const { useRoute, useIsNavigating, useRouterError } = hooks;
|
|
5
|
+
function Route({ name, children, component: Component, pendingComponent: PendingComponent, errorComponent: ErrorComponent }) {
|
|
6
|
+
const { isActive, params } = useRoute({ name });
|
|
7
|
+
const isNavigating = useIsNavigating();
|
|
8
|
+
const error = useRouterError();
|
|
9
|
+
if (!isActive) return null;
|
|
10
|
+
if (error && ErrorComponent) return /* @__PURE__ */ jsx(ErrorComponent, {
|
|
11
|
+
error: error.error,
|
|
12
|
+
retry: error.retry
|
|
13
|
+
});
|
|
14
|
+
if (isNavigating && PendingComponent) return /* @__PURE__ */ jsx(PendingComponent, {});
|
|
15
|
+
if (children) return children(params);
|
|
16
|
+
if (Component) return /* @__PURE__ */ jsx(Component, { ...params });
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
return Route;
|
|
20
|
+
}
|
|
21
|
+
//#endregion
|
|
22
|
+
export { makeRoute };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
let react = require("react");
|
|
2
|
+
//#region src/components/Switch.tsx
|
|
3
|
+
function makeSwitch(hooks) {
|
|
4
|
+
const { useCurrentRoute } = hooks;
|
|
5
|
+
function Switch({ children }) {
|
|
6
|
+
const route = useCurrentRoute();
|
|
7
|
+
for (const child of react.Children.toArray(children)) {
|
|
8
|
+
if (!(0, react.isValidElement)(child)) continue;
|
|
9
|
+
const props = child.props;
|
|
10
|
+
if ("name" in props) {
|
|
11
|
+
if (props.name === route?.name) return child;
|
|
12
|
+
continue;
|
|
13
|
+
}
|
|
14
|
+
return child;
|
|
15
|
+
}
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
return Switch;
|
|
19
|
+
}
|
|
20
|
+
//#endregion
|
|
21
|
+
exports.makeSwitch = makeSwitch;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Children, isValidElement } from "react";
|
|
2
|
+
//#region src/components/Switch.tsx
|
|
3
|
+
function makeSwitch(hooks) {
|
|
4
|
+
const { useCurrentRoute } = hooks;
|
|
5
|
+
function Switch({ children }) {
|
|
6
|
+
const route = useCurrentRoute();
|
|
7
|
+
for (const child of Children.toArray(children)) {
|
|
8
|
+
if (!isValidElement(child)) continue;
|
|
9
|
+
const props = child.props;
|
|
10
|
+
if ("name" in props) {
|
|
11
|
+
if (props.name === route?.name) return child;
|
|
12
|
+
continue;
|
|
13
|
+
}
|
|
14
|
+
return child;
|
|
15
|
+
}
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
return Switch;
|
|
19
|
+
}
|
|
20
|
+
//#endregion
|
|
21
|
+
export { makeSwitch };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const require_Link = require("./components/Link.cjs");
|
|
2
|
+
const require_Navigate = require("./components/Navigate.cjs");
|
|
3
|
+
const require_Route = require("./components/Route.cjs");
|
|
4
|
+
const require_Switch = require("./components/Switch.cjs");
|
|
5
|
+
const require_headless = require("./headless.cjs");
|
|
6
|
+
//#region src/create-router.ts
|
|
7
|
+
function createRouter(config) {
|
|
8
|
+
const hooks = require_headless.createHeadlessRouter(config);
|
|
9
|
+
return {
|
|
10
|
+
...hooks,
|
|
11
|
+
Route: require_Route.makeRoute(hooks),
|
|
12
|
+
Switch: require_Switch.makeSwitch(hooks),
|
|
13
|
+
Link: require_Link.makeLink(hooks),
|
|
14
|
+
Navigate: require_Navigate.makeNavigate(hooks)
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
//#endregion
|
|
18
|
+
exports.createRouter = createRouter;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ReactRouterConfig } from "./types.cjs";
|
|
2
|
+
import { HeadlessReactRouter } from "./headless.cjs";
|
|
3
|
+
import { LinkComponent } from "./components/Link.cjs";
|
|
4
|
+
import { NavigateComponent } from "./components/Navigate.cjs";
|
|
5
|
+
import { RouteComponent } from "./components/Route.cjs";
|
|
6
|
+
import { SwitchComponent } from "./components/Switch.cjs";
|
|
7
|
+
import { RouteMapDef } from "iten-core";
|
|
8
|
+
|
|
9
|
+
//#region src/create-router.d.ts
|
|
10
|
+
type ReactRouter<M extends RouteMapDef, _Ctx = unknown> = HeadlessReactRouter<M> & {
|
|
11
|
+
Route: RouteComponent<M>;
|
|
12
|
+
Switch: SwitchComponent;
|
|
13
|
+
Link: LinkComponent<M>;
|
|
14
|
+
Navigate: NavigateComponent<M>;
|
|
15
|
+
};
|
|
16
|
+
declare function createRouter<M extends RouteMapDef, Ctx = unknown>(config: ReactRouterConfig<M, Ctx>): ReactRouter<M, Ctx>;
|
|
17
|
+
//#endregion
|
|
18
|
+
export { ReactRouter, createRouter };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ReactRouterConfig } from "./types.js";
|
|
2
|
+
import { HeadlessReactRouter } from "./headless.js";
|
|
3
|
+
import { LinkComponent } from "./components/Link.js";
|
|
4
|
+
import { NavigateComponent } from "./components/Navigate.js";
|
|
5
|
+
import { RouteComponent } from "./components/Route.js";
|
|
6
|
+
import { SwitchComponent } from "./components/Switch.js";
|
|
7
|
+
import { RouteMapDef } from "iten-core";
|
|
8
|
+
|
|
9
|
+
//#region src/create-router.d.ts
|
|
10
|
+
type ReactRouter<M extends RouteMapDef, _Ctx = unknown> = HeadlessReactRouter<M> & {
|
|
11
|
+
Route: RouteComponent<M>;
|
|
12
|
+
Switch: SwitchComponent;
|
|
13
|
+
Link: LinkComponent<M>;
|
|
14
|
+
Navigate: NavigateComponent<M>;
|
|
15
|
+
};
|
|
16
|
+
declare function createRouter<M extends RouteMapDef, Ctx = unknown>(config: ReactRouterConfig<M, Ctx>): ReactRouter<M, Ctx>;
|
|
17
|
+
//#endregion
|
|
18
|
+
export { ReactRouter, createRouter };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { makeLink } from "./components/Link.mjs";
|
|
2
|
+
import { makeNavigate } from "./components/Navigate.mjs";
|
|
3
|
+
import { makeRoute } from "./components/Route.mjs";
|
|
4
|
+
import { makeSwitch } from "./components/Switch.mjs";
|
|
5
|
+
import { createHeadlessRouter } from "./headless.mjs";
|
|
6
|
+
//#region src/create-router.ts
|
|
7
|
+
function createRouter(config) {
|
|
8
|
+
const hooks = createHeadlessRouter(config);
|
|
9
|
+
return {
|
|
10
|
+
...hooks,
|
|
11
|
+
Route: makeRoute(hooks),
|
|
12
|
+
Switch: makeSwitch(hooks),
|
|
13
|
+
Link: makeLink(hooks),
|
|
14
|
+
Navigate: makeNavigate(hooks)
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
//#endregion
|
|
18
|
+
export { createRouter };
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_hooks = require("./hooks.cjs");
|
|
3
|
+
let iten_core = require("iten-core");
|
|
4
|
+
//#region src/headless.ts
|
|
5
|
+
function createHeadlessRouter(config) {
|
|
6
|
+
const getCtx = () => {
|
|
7
|
+
if (typeof config.context === "function") return config.context();
|
|
8
|
+
return config.context ?? {};
|
|
9
|
+
};
|
|
10
|
+
const core = (0, iten_core.createItenCore)({
|
|
11
|
+
initial: config.initial,
|
|
12
|
+
routeConfig: config.routeConfig,
|
|
13
|
+
maxHistoryLength: config.maxHistoryLength,
|
|
14
|
+
queryClient: config.queryClient,
|
|
15
|
+
getCtx
|
|
16
|
+
});
|
|
17
|
+
let snapshot = core.getState();
|
|
18
|
+
const store = {
|
|
19
|
+
getState: () => snapshot,
|
|
20
|
+
subscribe: ({ listener }) => core.subscribe({ listener: (nextSnapshot) => {
|
|
21
|
+
snapshot = nextSnapshot;
|
|
22
|
+
listener();
|
|
23
|
+
} }),
|
|
24
|
+
navigate: async (input) => {
|
|
25
|
+
await core.navigate(input);
|
|
26
|
+
snapshot = core.getState();
|
|
27
|
+
},
|
|
28
|
+
goBack: () => {
|
|
29
|
+
core.goBack();
|
|
30
|
+
snapshot = core.getState();
|
|
31
|
+
},
|
|
32
|
+
dispose: () => core.dispose()
|
|
33
|
+
};
|
|
34
|
+
return {
|
|
35
|
+
store,
|
|
36
|
+
core,
|
|
37
|
+
...require_hooks.makeHooks(store)
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
//#endregion
|
|
41
|
+
exports.createHeadlessRouter = createHeadlessRouter;
|
|
42
|
+
Object.defineProperty(exports, "createRoute", {
|
|
43
|
+
enumerable: true,
|
|
44
|
+
get: function() {
|
|
45
|
+
return iten_core.createRoute;
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
Object.defineProperty(exports, "defineRouteConfig", {
|
|
49
|
+
enumerable: true,
|
|
50
|
+
get: function() {
|
|
51
|
+
return iten_core.defineRouteConfig;
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
Object.defineProperty(exports, "defineRoutes", {
|
|
55
|
+
enumerable: true,
|
|
56
|
+
get: function() {
|
|
57
|
+
return iten_core.defineRoutes;
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
Object.defineProperty(exports, "isRoute", {
|
|
61
|
+
enumerable: true,
|
|
62
|
+
get: function() {
|
|
63
|
+
return iten_core.isRoute;
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
Object.defineProperty(exports, "isRouteName", {
|
|
67
|
+
enumerable: true,
|
|
68
|
+
get: function() {
|
|
69
|
+
return iten_core.isRouteName;
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
Object.defineProperty(exports, "matchRoute", {
|
|
73
|
+
enumerable: true,
|
|
74
|
+
get: function() {
|
|
75
|
+
return iten_core.matchRoute;
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
Object.defineProperty(exports, "route", {
|
|
79
|
+
enumerable: true,
|
|
80
|
+
get: function() {
|
|
81
|
+
return iten_core.route;
|
|
82
|
+
}
|
|
83
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { InferRoutes, NoParams, QueryClientLike, ReactRouterConfig, RouteConfigMap, RouteMap, RouteMapDef, RouteMatcher, RouteName, RouteOf, RouteParams, RouteUnion, RouterError, RouterState, UseRouteResult } from "./types.cjs";
|
|
2
|
+
import { HookBundle } from "./hooks.cjs";
|
|
3
|
+
import { ItenCore, NavigateInput, RouteMapDef as RouteMapDef$1, RouterState as RouterState$1, createRoute, defineRouteConfig, defineRoutes, isRoute, isRouteName, matchRoute, route } from "iten-core";
|
|
4
|
+
|
|
5
|
+
//#region src/headless.d.ts
|
|
6
|
+
type ReactRouterStore<M extends RouteMapDef$1> = {
|
|
7
|
+
getState: () => RouterState$1<M>;
|
|
8
|
+
subscribe: (input: {
|
|
9
|
+
listener: () => void;
|
|
10
|
+
}) => () => void;
|
|
11
|
+
navigate: (input: NavigateInput<M>) => Promise<void>;
|
|
12
|
+
goBack: () => void;
|
|
13
|
+
dispose: () => void;
|
|
14
|
+
};
|
|
15
|
+
type HeadlessReactRouter<M extends RouteMapDef$1> = HookBundle<M> & {
|
|
16
|
+
store: ReactRouterStore<M>;
|
|
17
|
+
core: ItenCore<M>;
|
|
18
|
+
};
|
|
19
|
+
declare function createHeadlessRouter<M extends RouteMapDef$1, Ctx = unknown>(config: ReactRouterConfig<M, Ctx>): HeadlessReactRouter<M>;
|
|
20
|
+
//#endregion
|
|
21
|
+
export { HeadlessReactRouter, type InferRoutes, type NoParams, type QueryClientLike, ReactRouterStore, type RouteConfigMap, type RouteMap, type RouteMapDef, type RouteMatcher, type RouteName, type RouteOf, type RouteParams, type RouteUnion, type RouterError, type RouterState, type UseRouteResult, createHeadlessRouter, createRoute, defineRouteConfig, defineRoutes, isRoute, isRouteName, matchRoute, route };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { InferRoutes, NoParams, QueryClientLike, ReactRouterConfig, RouteConfigMap, RouteMap, RouteMapDef, RouteMatcher, RouteName, RouteOf, RouteParams, RouteUnion, RouterError, RouterState, UseRouteResult } from "./types.js";
|
|
2
|
+
import { HookBundle } from "./hooks.js";
|
|
3
|
+
import { ItenCore, NavigateInput, RouteMapDef as RouteMapDef$1, RouterState as RouterState$1, createRoute, defineRouteConfig, defineRoutes, isRoute, isRouteName, matchRoute, route } from "iten-core";
|
|
4
|
+
|
|
5
|
+
//#region src/headless.d.ts
|
|
6
|
+
type ReactRouterStore<M extends RouteMapDef$1> = {
|
|
7
|
+
getState: () => RouterState$1<M>;
|
|
8
|
+
subscribe: (input: {
|
|
9
|
+
listener: () => void;
|
|
10
|
+
}) => () => void;
|
|
11
|
+
navigate: (input: NavigateInput<M>) => Promise<void>;
|
|
12
|
+
goBack: () => void;
|
|
13
|
+
dispose: () => void;
|
|
14
|
+
};
|
|
15
|
+
type HeadlessReactRouter<M extends RouteMapDef$1> = HookBundle<M> & {
|
|
16
|
+
store: ReactRouterStore<M>;
|
|
17
|
+
core: ItenCore<M>;
|
|
18
|
+
};
|
|
19
|
+
declare function createHeadlessRouter<M extends RouteMapDef$1, Ctx = unknown>(config: ReactRouterConfig<M, Ctx>): HeadlessReactRouter<M>;
|
|
20
|
+
//#endregion
|
|
21
|
+
export { HeadlessReactRouter, type InferRoutes, type NoParams, type QueryClientLike, ReactRouterStore, type RouteConfigMap, type RouteMap, type RouteMapDef, type RouteMatcher, type RouteName, type RouteOf, type RouteParams, type RouteUnion, type RouterError, type RouterState, type UseRouteResult, createHeadlessRouter, createRoute, defineRouteConfig, defineRoutes, isRoute, isRouteName, matchRoute, route };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { makeHooks } from "./hooks.mjs";
|
|
2
|
+
import { createItenCore, createRoute, defineRouteConfig, defineRoutes, isRoute, isRouteName, matchRoute, route } from "iten-core";
|
|
3
|
+
//#region src/headless.ts
|
|
4
|
+
function createHeadlessRouter(config) {
|
|
5
|
+
const getCtx = () => {
|
|
6
|
+
if (typeof config.context === "function") return config.context();
|
|
7
|
+
return config.context ?? {};
|
|
8
|
+
};
|
|
9
|
+
const core = createItenCore({
|
|
10
|
+
initial: config.initial,
|
|
11
|
+
routeConfig: config.routeConfig,
|
|
12
|
+
maxHistoryLength: config.maxHistoryLength,
|
|
13
|
+
queryClient: config.queryClient,
|
|
14
|
+
getCtx
|
|
15
|
+
});
|
|
16
|
+
let snapshot = core.getState();
|
|
17
|
+
const store = {
|
|
18
|
+
getState: () => snapshot,
|
|
19
|
+
subscribe: ({ listener }) => core.subscribe({ listener: (nextSnapshot) => {
|
|
20
|
+
snapshot = nextSnapshot;
|
|
21
|
+
listener();
|
|
22
|
+
} }),
|
|
23
|
+
navigate: async (input) => {
|
|
24
|
+
await core.navigate(input);
|
|
25
|
+
snapshot = core.getState();
|
|
26
|
+
},
|
|
27
|
+
goBack: () => {
|
|
28
|
+
core.goBack();
|
|
29
|
+
snapshot = core.getState();
|
|
30
|
+
},
|
|
31
|
+
dispose: () => core.dispose()
|
|
32
|
+
};
|
|
33
|
+
return {
|
|
34
|
+
store,
|
|
35
|
+
core,
|
|
36
|
+
...makeHooks(store)
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
//#endregion
|
|
40
|
+
export { createHeadlessRouter, createRoute, defineRouteConfig, defineRoutes, isRoute, isRouteName, matchRoute, route };
|