@typed/router 0.12.6 → 0.14.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/Link.d.ts +26 -11
- package/dist/Link.d.ts.map +1 -1
- package/dist/Link.js +47 -23
- package/dist/Link.js.map +1 -1
- package/dist/Match.d.ts +33 -0
- package/dist/Match.d.ts.map +1 -0
- package/dist/Match.js +16 -0
- package/dist/Match.js.map +1 -0
- package/dist/Matcher.d.ts +28 -0
- package/dist/Matcher.d.ts.map +1 -0
- package/dist/Matcher.js +24 -0
- package/dist/Matcher.js.map +1 -0
- package/dist/Navigation.d.ts +10 -0
- package/dist/Navigation.d.ts.map +1 -0
- package/dist/Navigation.js +7 -0
- package/dist/Navigation.js.map +1 -0
- package/dist/Redirect.d.ts +27 -0
- package/dist/Redirect.d.ts.map +1 -0
- package/dist/Redirect.js +17 -0
- package/dist/Redirect.js.map +1 -0
- package/dist/RouteOutlet.d.ts +3 -0
- package/dist/RouteOutlet.d.ts.map +1 -0
- package/dist/RouteOutlet.js +2 -0
- package/dist/RouteOutlet.js.map +1 -0
- package/dist/ScrollRestoration.d.ts +19 -0
- package/dist/ScrollRestoration.d.ts.map +1 -0
- package/dist/ScrollRestoration.js +64 -0
- package/dist/ScrollRestoration.js.map +1 -0
- package/dist/cjs/Link.d.ts +26 -11
- package/dist/cjs/Link.d.ts.map +1 -1
- package/dist/cjs/Link.js +47 -22
- package/dist/cjs/Link.js.map +1 -1
- package/dist/cjs/Match.d.ts +33 -0
- package/dist/cjs/Match.d.ts.map +1 -0
- package/dist/cjs/Match.js +43 -0
- package/dist/cjs/Match.js.map +1 -0
- package/dist/cjs/Matcher.d.ts +28 -0
- package/dist/cjs/Matcher.d.ts.map +1 -0
- package/dist/cjs/Matcher.js +52 -0
- package/dist/cjs/Matcher.js.map +1 -0
- package/dist/cjs/Navigation.d.ts +10 -0
- package/dist/cjs/Navigation.d.ts.map +1 -0
- package/dist/cjs/Navigation.js +34 -0
- package/dist/cjs/Navigation.js.map +1 -0
- package/dist/cjs/Redirect.d.ts +27 -0
- package/dist/cjs/Redirect.d.ts.map +1 -0
- package/dist/cjs/Redirect.js +44 -0
- package/dist/cjs/Redirect.js.map +1 -0
- package/dist/cjs/ScrollRestoration.d.ts +19 -0
- package/dist/cjs/ScrollRestoration.d.ts.map +1 -0
- package/dist/cjs/ScrollRestoration.js +91 -0
- package/dist/cjs/ScrollRestoration.js.map +1 -0
- package/dist/cjs/index.d.ts +7 -3
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +7 -3
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/matchRoutes.d.ts +8 -0
- package/dist/cjs/matchRoutes.d.ts.map +1 -0
- package/dist/cjs/matchRoutes.js +77 -0
- package/dist/cjs/matchRoutes.js.map +1 -0
- package/dist/cjs/router.d.ts +24 -63
- package/dist/cjs/router.d.ts.map +1 -1
- package/dist/cjs/router.js +22 -159
- package/dist/cjs/router.js.map +1 -1
- package/dist/index.d.ts +7 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -3
- package/dist/index.js.map +1 -1
- package/dist/matchRoutes.d.ts +8 -0
- package/dist/matchRoutes.d.ts.map +1 -0
- package/dist/matchRoutes.js +50 -0
- package/dist/matchRoutes.js.map +1 -0
- package/dist/router.d.ts +24 -63
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +19 -153
- package/dist/router.js.map +1 -1
- package/dist/tsconfig.cjs.build.tsbuildinfo +1 -1
- package/package.json +12 -10
- package/project.json +12 -10
- package/src/Link.ts +129 -39
- package/src/Match.ts +114 -0
- package/src/Matcher.ts +139 -0
- package/src/Navigation.ts +24 -0
- package/src/Redirect.ts +21 -0
- package/src/ScrollRestoration.ts +110 -0
- package/src/index.ts +7 -3
- package/src/matchRoutes.ts +112 -0
- package/src/router.ts +56 -311
- package/tsconfig.build.json +5 -1
- package/tsconfig.build.tsbuildinfo +1 -1
- package/tsconfig.cjs.build.json +6 -0
- package/tsconfig.json +6 -0
- package/vite.config.js +3 -0
- package/src/RouteMatch.ts +0 -56
- package/src/RouteMatcher.ts +0 -264
package/tsconfig.cjs.build.json
CHANGED
|
@@ -13,12 +13,18 @@
|
|
|
13
13
|
{
|
|
14
14
|
"path": "../dom/tsconfig.cjs.build.json"
|
|
15
15
|
},
|
|
16
|
+
{
|
|
17
|
+
"path": "../error/tsconfig.cjs.build.json"
|
|
18
|
+
},
|
|
16
19
|
{
|
|
17
20
|
"path": "../fx/tsconfig.cjs.build.json"
|
|
18
21
|
},
|
|
19
22
|
{
|
|
20
23
|
"path": "../html/tsconfig.cjs.build.json"
|
|
21
24
|
},
|
|
25
|
+
{
|
|
26
|
+
"path": "../navigation/tsconfig.cjs.build.json"
|
|
27
|
+
},
|
|
22
28
|
{
|
|
23
29
|
"path": "../path/tsconfig.cjs.build.json"
|
|
24
30
|
},
|
package/tsconfig.json
CHANGED
|
@@ -17,12 +17,18 @@
|
|
|
17
17
|
{
|
|
18
18
|
"path": "../dom/tsconfig.build.json"
|
|
19
19
|
},
|
|
20
|
+
{
|
|
21
|
+
"path": "../error/tsconfig.build.json"
|
|
22
|
+
},
|
|
20
23
|
{
|
|
21
24
|
"path": "../fx/tsconfig.build.json"
|
|
22
25
|
},
|
|
23
26
|
{
|
|
24
27
|
"path": "../html/tsconfig.build.json"
|
|
25
28
|
},
|
|
29
|
+
{
|
|
30
|
+
"path": "../navigation/tsconfig.build.json"
|
|
31
|
+
},
|
|
26
32
|
{
|
|
27
33
|
"path": "../path/tsconfig.build.json"
|
|
28
34
|
},
|
package/vite.config.js
ADDED
package/src/RouteMatch.ts
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/ban-types */
|
|
2
|
-
import { flow } from '@effect/data/Function'
|
|
3
|
-
import type * as Layer from '@effect/io/Layer'
|
|
4
|
-
import * as Context from '@typed/context'
|
|
5
|
-
import * as Fx from '@typed/fx'
|
|
6
|
-
import type * as html from '@typed/html'
|
|
7
|
-
import type * as Path from '@typed/path'
|
|
8
|
-
import * as Route from '@typed/route'
|
|
9
|
-
|
|
10
|
-
export interface RouteMatch<R, E, P extends string> {
|
|
11
|
-
readonly route: Route.Route<R, E, P>
|
|
12
|
-
|
|
13
|
-
readonly layout?: Fx.Fx<R, E, html.Renderable>
|
|
14
|
-
|
|
15
|
-
readonly match: (params: Fx.Fx<never, never, Path.ParamsOf<P>>) => Fx.Fx<R, E, html.Renderable>
|
|
16
|
-
|
|
17
|
-
readonly provideContext: (environment: Context.Context<R>) => RouteMatch<never, E, P>
|
|
18
|
-
|
|
19
|
-
readonly provideService: <S>(tag: Context.Tag<S>, service: S) => RouteMatch<Exclude<R, S>, E, P>
|
|
20
|
-
|
|
21
|
-
readonly provideSomeLayer: <R2, S>(
|
|
22
|
-
layer: Layer.Layer<R2, never, S>,
|
|
23
|
-
) => RouteMatch<R2 | Exclude<R, S>, E, P>
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export function RouteMatch<R, E, P extends string, R2, E2, R3, E3>(
|
|
27
|
-
route: Route.Route<R, E, P>,
|
|
28
|
-
match: (params: Fx.Fx<never, never, Path.ParamsOf<P>>) => Fx.Fx<R2, E2, html.Renderable>,
|
|
29
|
-
layout?: Fx.Fx<R3, E3, html.Renderable>,
|
|
30
|
-
): RouteMatch<R | R2 | R3, E | E2 | E3, P> {
|
|
31
|
-
const routeMatch: RouteMatch<R | R2 | R3, E | E2 | E3, P> = {
|
|
32
|
-
route,
|
|
33
|
-
match,
|
|
34
|
-
layout,
|
|
35
|
-
provideContext: (env) =>
|
|
36
|
-
RouteMatch(
|
|
37
|
-
Route.provideContext(env)(route),
|
|
38
|
-
flow(match, Fx.provideSomeContext(env)),
|
|
39
|
-
layout ? Fx.provideContext(env)(layout) : undefined,
|
|
40
|
-
),
|
|
41
|
-
provideService: (tag, service) =>
|
|
42
|
-
RouteMatch(
|
|
43
|
-
Route.provideService(tag, service)(route),
|
|
44
|
-
flow(match, Fx.provideService(tag, service)),
|
|
45
|
-
layout ? Fx.provideService(tag, service)(layout) : undefined,
|
|
46
|
-
),
|
|
47
|
-
provideSomeLayer: (layer) =>
|
|
48
|
-
RouteMatch(
|
|
49
|
-
Route.provideSomeLayer(layer)(route),
|
|
50
|
-
flow(match, Fx.provideSomeLayer(layer)),
|
|
51
|
-
layout ? Fx.provideSomeLayer(layer)(layout) : undefined,
|
|
52
|
-
),
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
return routeMatch
|
|
56
|
-
}
|
package/src/RouteMatcher.ts
DELETED
|
@@ -1,264 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/ban-types */
|
|
2
|
-
import { identity, pipe } from '@effect/data/Function'
|
|
3
|
-
import * as Option from '@effect/data/Option'
|
|
4
|
-
import * as Effect from '@effect/io/Effect'
|
|
5
|
-
import * as Fiber from '@effect/io/Fiber'
|
|
6
|
-
import type * as Layer from '@effect/io/Layer'
|
|
7
|
-
import type * as Context from '@typed/context'
|
|
8
|
-
import * as Fx from '@typed/fx'
|
|
9
|
-
import type * as html from '@typed/html'
|
|
10
|
-
import { RenderContext } from '@typed/html'
|
|
11
|
-
import type * as Path from '@typed/path'
|
|
12
|
-
import type * as Route from '@typed/route'
|
|
13
|
-
|
|
14
|
-
import { RouteMatch } from './RouteMatch.js'
|
|
15
|
-
import { Redirect, redirectTo, Router } from './router.js'
|
|
16
|
-
|
|
17
|
-
export interface RouteMatcher<R = never, E = never> {
|
|
18
|
-
// Where things are actually stored immutably
|
|
19
|
-
readonly routes: ReadonlyMap<Route.Route<any, any, any>, RouteMatch<any, any, any>>
|
|
20
|
-
|
|
21
|
-
// Add Routes
|
|
22
|
-
|
|
23
|
-
readonly match: <R2, E2, P extends string, R3, E3>(
|
|
24
|
-
route: Route.Route<R2, E2, P>,
|
|
25
|
-
f: (params: Path.ParamsOf<P>) => Fx.Fx<R3, E3, html.Renderable>,
|
|
26
|
-
) => RouteMatcher<R | R2 | R3, E | E2 | E3>
|
|
27
|
-
|
|
28
|
-
readonly matchFx: <R2, E2, P extends string, R3, E3>(
|
|
29
|
-
route: Route.Route<R2, E2, P>,
|
|
30
|
-
f: (params: Fx.Fx<never, never, Path.ParamsOf<P>>) => Fx.Fx<R3, E3, html.Renderable>,
|
|
31
|
-
) => RouteMatcher<R | R2 | R3, E | E2 | E3>
|
|
32
|
-
|
|
33
|
-
readonly matchEffect: <R2, E2, P extends string, R3, E3>(
|
|
34
|
-
route: Route.Route<R2, E2, P>,
|
|
35
|
-
f: (params: Path.ParamsOf<P>) => Effect.Effect<R3, E3, html.Renderable>,
|
|
36
|
-
) => RouteMatcher<R | R2 | R3, E | E2 | E3>
|
|
37
|
-
|
|
38
|
-
// Add Layout
|
|
39
|
-
|
|
40
|
-
readonly withLayout: <R2, E2>(fx: Fx.Fx<R2, E2, html.Renderable>) => RouteMatcher<R | R2, E | E2>
|
|
41
|
-
|
|
42
|
-
// Provide resources
|
|
43
|
-
|
|
44
|
-
readonly provideContext: <R2>(environment: Context.Context<R2>) => RouteMatcher<Exclude<R, R2>, E>
|
|
45
|
-
|
|
46
|
-
readonly provideService: <R2>(
|
|
47
|
-
tag: Context.Tag<R2>,
|
|
48
|
-
service: R2,
|
|
49
|
-
) => RouteMatcher<Exclude<R, R2>, E>
|
|
50
|
-
|
|
51
|
-
readonly provideSomeLayer: <R2, S>(
|
|
52
|
-
layer: Layer.Layer<R2, never, S>,
|
|
53
|
-
) => RouteMatcher<Exclude<R, S> | R2, E>
|
|
54
|
-
|
|
55
|
-
// Runners that turn a RouterMatcher back into an Fx.
|
|
56
|
-
// Error handling should be handled after converting to an Fx for maximum flexibility.
|
|
57
|
-
|
|
58
|
-
readonly notFound: <R2, E2, R3 = never, E3 = never>(
|
|
59
|
-
f: (path: string) => Fx.Fx<R2, E2, html.Renderable>,
|
|
60
|
-
options?: FallbackOptions<R3, E3>,
|
|
61
|
-
) => Fx.Fx<Router | R | R2 | R3, E | E2 | E3, html.Renderable>
|
|
62
|
-
|
|
63
|
-
readonly notFoundEffect: <R2, E2, R3 = never, E3 = never>(
|
|
64
|
-
f: (path: string) => Effect.Effect<R2, E2, html.Renderable>,
|
|
65
|
-
options?: FallbackOptions<R3, E3>,
|
|
66
|
-
) => Fx.Fx<Router | R | R2 | R3, E | E2 | E3, html.Renderable>
|
|
67
|
-
|
|
68
|
-
readonly redirectTo: <R2, E2, P extends string>(
|
|
69
|
-
route: Route.Route<R2, E2, P>,
|
|
70
|
-
...params: [keyof Path.ParamsOf<P>] extends [never]
|
|
71
|
-
? // eslint-disable-next-line @typescript-eslint/ban-types
|
|
72
|
-
[{}?]
|
|
73
|
-
: [(path: string) => Path.ParamsOf<P>]
|
|
74
|
-
) => Fx.Fx<Router | R | R2, E | Redirect, html.Renderable>
|
|
75
|
-
|
|
76
|
-
readonly run: Fx.Fx<Router | R, E | Redirect, html.Renderable | null>
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export interface FallbackOptions<R, E> {
|
|
80
|
-
readonly layout?: Fx.Fx<R, E, html.Renderable>
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
export function RouteMatcher<R, E>(routes: RouteMatcher<R, E>['routes']): RouteMatcher<R, E> {
|
|
84
|
-
const matcher: RouteMatcher<R, E> = {
|
|
85
|
-
routes,
|
|
86
|
-
matchFx: (route, f) => RouteMatcher(new Map(routes).set(route, RouteMatch(route, f))),
|
|
87
|
-
match: (route, f) =>
|
|
88
|
-
RouteMatcher(new Map(routes).set(route, RouteMatch(route, Fx.switchMap(f)))),
|
|
89
|
-
matchEffect: (route, f) =>
|
|
90
|
-
RouteMatcher(new Map(routes).set(route, RouteMatch(route, Fx.switchMapEffect(f)))),
|
|
91
|
-
withLayout: (layout) =>
|
|
92
|
-
RouteMatcher(
|
|
93
|
-
new Map(
|
|
94
|
-
Array.from(routes).map(([k, match]) => [
|
|
95
|
-
k,
|
|
96
|
-
RouteMatch(match.route, match.match, match.layout ?? layout),
|
|
97
|
-
]),
|
|
98
|
-
),
|
|
99
|
-
),
|
|
100
|
-
provideContext: (environment) =>
|
|
101
|
-
RouteMatcher(new Map(Array.from(routes).map(([k, v]) => [k, v.provideContext(environment)]))),
|
|
102
|
-
provideService: (tag, service) =>
|
|
103
|
-
RouteMatcher(
|
|
104
|
-
new Map(Array.from(routes).map(([k, v]) => [k, v.provideService(tag, service)])),
|
|
105
|
-
),
|
|
106
|
-
provideSomeLayer: (layer) =>
|
|
107
|
-
RouteMatcher(new Map(Array.from(routes).map(([k, v]) => [k, v.provideSomeLayer(layer)]))),
|
|
108
|
-
notFound: <R2, E2, R3, E3>(
|
|
109
|
-
f: (path: string) => Fx.Fx<R2, E2, html.Renderable>,
|
|
110
|
-
options: FallbackOptions<R3, E3> = {},
|
|
111
|
-
) =>
|
|
112
|
-
Router.withFx((router) =>
|
|
113
|
-
Fx.gen(function* ($) {
|
|
114
|
-
const { outlet } = yield* $(Router)
|
|
115
|
-
const { environment } = yield* $(RenderContext)
|
|
116
|
-
// Create stable references to the route matchers
|
|
117
|
-
const matchers = Array.from(routes.values()).map(
|
|
118
|
-
(v) => [v, runRouteMatch(router, v)] as const,
|
|
119
|
-
)
|
|
120
|
-
|
|
121
|
-
const renderFallback = Fx.switchMap(f)(router.currentPath)
|
|
122
|
-
|
|
123
|
-
let previousFiber: Fiber.RuntimeFiber<any, any> | undefined
|
|
124
|
-
let previousLayout: Fx.Fx<any, any, html.Renderable> | undefined
|
|
125
|
-
let previousRender: Fx.Fx<any, any, html.Renderable> | undefined
|
|
126
|
-
|
|
127
|
-
const samplePreviousValues = () => ({
|
|
128
|
-
fiber: previousFiber,
|
|
129
|
-
layout: previousLayout,
|
|
130
|
-
render: previousRender,
|
|
131
|
-
})
|
|
132
|
-
|
|
133
|
-
// This function helps us to ensure shared layouts are only rendered once
|
|
134
|
-
// and the outlet content is changed
|
|
135
|
-
const verifyShouldRerender = (
|
|
136
|
-
render: Fx.Fx<any, any, html.Renderable>,
|
|
137
|
-
layout?: Fx.Fx<any, any, html.Renderable>,
|
|
138
|
-
): Effect.Effect<any, any, Option.Option<Fx.Fx<any, any, html.Renderable>>> =>
|
|
139
|
-
Effect.gen(function* ($) {
|
|
140
|
-
const previous = samplePreviousValues()
|
|
141
|
-
|
|
142
|
-
// Update the previous values
|
|
143
|
-
previousRender = render
|
|
144
|
-
previousLayout = layout
|
|
145
|
-
|
|
146
|
-
// Skip rerendering if the render function is the same
|
|
147
|
-
if (previous.render === render && previous.layout === layout) {
|
|
148
|
-
return Option.none()
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
// Interrupt the previous fiber if it exists
|
|
152
|
-
if (previous.render !== render && previous.fiber) {
|
|
153
|
-
yield* $(Fiber.interrupt(previous.fiber))
|
|
154
|
-
previousFiber = undefined
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
// If we have a layout, we need to render it and use the route outlet.
|
|
158
|
-
if (layout) {
|
|
159
|
-
// Render into the route outlet
|
|
160
|
-
if (previous.render !== render) {
|
|
161
|
-
previousFiber = yield* $(
|
|
162
|
-
pipe(
|
|
163
|
-
render,
|
|
164
|
-
Fx.observe(outlet.set),
|
|
165
|
-
Effect.catchAll((e: Redirect) =>
|
|
166
|
-
Redirect.is(e) ? router.currentPath.set(e.path) : Effect.fail(e),
|
|
167
|
-
),
|
|
168
|
-
Effect.onError(outlet.error),
|
|
169
|
-
Effect.forkDaemon,
|
|
170
|
-
),
|
|
171
|
-
)
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
return Option.some(layout)
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
// If we don't have a layout, but we did, we need to clear the outlet
|
|
178
|
-
if (previous.layout) {
|
|
179
|
-
yield* $(outlet.set(null))
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
// Otherwise use the render function directly
|
|
183
|
-
return Option.some(render)
|
|
184
|
-
})
|
|
185
|
-
|
|
186
|
-
return pipe(
|
|
187
|
-
router.currentPath,
|
|
188
|
-
environment === 'browser' ? identity : Fx.take(1),
|
|
189
|
-
Fx.switchMapEffect((path) =>
|
|
190
|
-
Effect.gen(function* ($) {
|
|
191
|
-
const currentParams = yield* $(router.route.match(path))
|
|
192
|
-
|
|
193
|
-
if (Option.isNone(currentParams)) {
|
|
194
|
-
return Option.none()
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
const matchedPath: string = router.route.make(currentParams.value)
|
|
198
|
-
const currentPath =
|
|
199
|
-
matchedPath === '/' ? path : path.replace(matchedPath, '') || '/'
|
|
200
|
-
|
|
201
|
-
yield* $(Effect.logInfo(`[@typed/router] Matching path: ${currentPath}`))
|
|
202
|
-
|
|
203
|
-
// Attempt to find the best match
|
|
204
|
-
for (const [match, render] of matchers) {
|
|
205
|
-
yield* $(Effect.logInfo(`[@typed/router] Matching against: ${match.route.path}`))
|
|
206
|
-
|
|
207
|
-
const result = yield* $(match.route.match(currentPath))
|
|
208
|
-
|
|
209
|
-
if (Option.isSome(result)) {
|
|
210
|
-
yield* $(Effect.logInfo(`[@typed/router] Matched against: ${match.route.path}`))
|
|
211
|
-
|
|
212
|
-
return yield* $(verifyShouldRerender(render, match.layout))
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
yield* $(Effect.logInfo(`[@typed/router] Rendering fallback`))
|
|
217
|
-
|
|
218
|
-
// If we didn't find a match, render the not found page
|
|
219
|
-
return yield* $(verifyShouldRerender(renderFallback, options.layout))
|
|
220
|
-
}),
|
|
221
|
-
),
|
|
222
|
-
Fx.compact,
|
|
223
|
-
Fx.skipRepeats, // Stable render references are used to avoid mounting the same component twice
|
|
224
|
-
Fx.switchLatest,
|
|
225
|
-
)
|
|
226
|
-
}),
|
|
227
|
-
),
|
|
228
|
-
notFoundEffect: (f) => matcher.notFound((path) => Fx.fromEffect(f(path))),
|
|
229
|
-
redirectTo: ((route, ...params) =>
|
|
230
|
-
matcher.notFound(() => redirectTo.fx(route, ...params))) as RouteMatcher<R, E>['redirectTo'],
|
|
231
|
-
run: Fx.suspend(() => matcher.notFound(() => Fx.succeed(null))),
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
return matcher
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
export namespace RouteMatcher {
|
|
238
|
-
export const empty = RouteMatcher<never, never>(new Map())
|
|
239
|
-
|
|
240
|
-
export const concat = <R, E, R2, E2>(
|
|
241
|
-
matcher: RouteMatcher<R, E>,
|
|
242
|
-
matcher2: RouteMatcher<R2, E2>,
|
|
243
|
-
): RouteMatcher<R | R2, E | E2> => RouteMatcher(new Map([...matcher.routes, ...matcher2.routes]))
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
export const { matchFx, match, matchEffect } = RouteMatcher<never, never>(new Map())
|
|
247
|
-
|
|
248
|
-
function runRouteMatch<R, E, P extends string>(
|
|
249
|
-
router: Router,
|
|
250
|
-
{ route, match }: RouteMatch<R, E, P>,
|
|
251
|
-
): Fx.Fx<R, E, html.Renderable> {
|
|
252
|
-
return Fx.gen(function* ($) {
|
|
253
|
-
const env = yield* $(Effect.context<R>())
|
|
254
|
-
const nestedRouter = router.define(route)
|
|
255
|
-
const params = pipe(nestedRouter.params, Fx.provideContext(env))
|
|
256
|
-
const render = pipe(
|
|
257
|
-
match(params as unknown as Fx.Fx<never, never, Path.ParamsOf<P>>),
|
|
258
|
-
Router.provideFx(nestedRouter as Router),
|
|
259
|
-
Fx.provideContext(env),
|
|
260
|
-
)
|
|
261
|
-
|
|
262
|
-
return render
|
|
263
|
-
})
|
|
264
|
-
}
|