@typed/router 0.17.7 → 0.18.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.
Files changed (46) hide show
  1. package/dist/Http/Router.d.ts +2 -0
  2. package/dist/Http/Router.d.ts.map +1 -0
  3. package/dist/Http/Router.js +2 -0
  4. package/dist/Http/Router.js.map +1 -0
  5. package/dist/Link.d.ts +12 -11
  6. package/dist/Link.d.ts.map +1 -1
  7. package/dist/Link.js +9 -7
  8. package/dist/Link.js.map +1 -1
  9. package/dist/Match.d.ts +3 -3
  10. package/dist/Match.d.ts.map +1 -1
  11. package/dist/Matcher.d.ts +30 -4
  12. package/dist/Matcher.d.ts.map +1 -1
  13. package/dist/Matcher.js +27 -4
  14. package/dist/Matcher.js.map +1 -1
  15. package/dist/Redirect.d.ts +1 -1
  16. package/dist/cjs/Link.d.ts +12 -11
  17. package/dist/cjs/Link.d.ts.map +1 -1
  18. package/dist/cjs/Link.js +8 -6
  19. package/dist/cjs/Link.js.map +1 -1
  20. package/dist/cjs/Match.d.ts +3 -3
  21. package/dist/cjs/Match.d.ts.map +1 -1
  22. package/dist/cjs/Matcher.d.ts +30 -4
  23. package/dist/cjs/Matcher.d.ts.map +1 -1
  24. package/dist/cjs/Matcher.js +28 -5
  25. package/dist/cjs/Matcher.js.map +1 -1
  26. package/dist/cjs/Redirect.d.ts +1 -1
  27. package/dist/cjs/matchRoutes.js +1 -1
  28. package/dist/cjs/matchRoutes.js.map +1 -1
  29. package/dist/cjs/router.d.ts +14 -4
  30. package/dist/cjs/router.d.ts.map +1 -1
  31. package/dist/cjs/router.js +18 -2
  32. package/dist/cjs/router.js.map +1 -1
  33. package/dist/matchRoutes.js +1 -1
  34. package/dist/matchRoutes.js.map +1 -1
  35. package/dist/router.d.ts +14 -4
  36. package/dist/router.d.ts.map +1 -1
  37. package/dist/router.js +14 -1
  38. package/dist/router.js.map +1 -1
  39. package/dist/tsconfig.cjs.build.tsbuildinfo +1 -1
  40. package/package.json +10 -9
  41. package/src/Link.ts +36 -31
  42. package/src/Match.ts +3 -3
  43. package/src/Matcher.ts +95 -11
  44. package/src/matchRoutes.ts +1 -1
  45. package/src/router.ts +59 -6
  46. package/tsconfig.build.tsbuildinfo +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@typed/router",
3
- "version": "0.17.7",
3
+ "version": "0.18.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
@@ -21,16 +21,17 @@
21
21
  "dependencies": {
22
22
  "@effect/data": "^0.17.1",
23
23
  "@effect/io": "^0.38.0",
24
- "@typed/context": "0.17.1",
25
- "@typed/dom": "8.17.2",
26
- "@typed/error": "0.16.1",
27
- "@typed/fx": "1.16.1",
28
- "@typed/html": "3.17.6",
29
- "@typed/navigation": "0.4.2",
24
+ "@effect/platform": "^0.12.1",
25
+ "@typed/context": "0.18.0",
26
+ "@typed/dom": "8.18.0",
27
+ "@typed/error": "0.17.0",
28
+ "@typed/fx": "1.17.0",
29
+ "@typed/html": "3.18.0",
30
+ "@typed/navigation": "0.5.0",
30
31
  "@typed/path": "0.6.2",
31
- "@typed/route": "0.13.2"
32
+ "@typed/route": "0.14.0"
32
33
  },
33
- "gitHead": "9083c6af485d129f95e5f7b07d1bfb285668b7dd",
34
+ "gitHead": "61b4f0a42ab8f8b5e6e02c0433215121955df43c",
34
35
  "publishConfig": {
35
36
  "access": "public"
36
37
  },
package/src/Link.ts CHANGED
@@ -1,39 +1,42 @@
1
+ import { not } from '@effect/data/Predicate'
1
2
  import * as Effect from '@effect/io/Effect'
2
3
  import * as Scope from '@effect/io/Scope'
4
+ import { getIsUsingKeyModifier } from '@typed/dom'
3
5
  import * as Fx from '@typed/fx'
4
- import { Placeholder } from '@typed/html'
6
+ import { EventHandler, Placeholder } from '@typed/html'
5
7
  import * as Navigation from '@typed/navigation'
6
8
  import { pathJoin } from '@typed/path'
7
9
 
8
10
  import { Router, getCurrentPathFromUrl } from './router.js'
9
11
 
10
12
  export interface UseLinkParams<
11
- R = never,
12
- E = never,
13
- R2 = never,
14
- E2 = never,
15
- R3 = never,
16
- E3 = never,
17
- R4 = never,
18
- E4 = never,
19
- R5 = never,
20
- E5 = never,
13
+ To extends Placeholder.AnyOf<string>,
14
+ Replace extends Placeholder.AnyOf<boolean>,
15
+ State,
16
+ Relative extends Placeholder.AnyOf<boolean>,
17
+ Key extends Placeholder.AnyOf<string>,
21
18
  > {
22
- readonly to: Placeholder<R, E, string>
23
- readonly replace?: Placeholder<R2, E2, boolean>
24
- readonly state?: Placeholder<R3, E3, unknown> | unknown
25
- readonly relative?: Placeholder<R4, E4, boolean>
26
- readonly key?: Placeholder<R5, E5, string>
19
+ readonly to: To
20
+ readonly replace?: Replace
21
+ readonly state?: State
22
+ readonly relative?: Relative
23
+ readonly key?: Key
27
24
  }
28
25
 
29
26
  export namespace UseLinkParams {
30
- export type Any = UseLinkParams<any, any, any, any, any, any, any, any, any, any>
27
+ export type Any = UseLinkParams<
28
+ Placeholder.AnyOf<string>,
29
+ Placeholder.AnyOf<boolean>,
30
+ unknown,
31
+ Placeholder.AnyOf<boolean>,
32
+ Placeholder.AnyOf<string>
33
+ >
31
34
 
32
- export type Context<T extends Any> = Placeholder.ResourcesOf<
35
+ export type Context<T extends Any> = Placeholder.Context<
33
36
  T['to'] | T['replace'] | T['state'] | T['relative'] | T['key']
34
37
  >
35
38
 
36
- export type Error<T extends Any> = Placeholder.ErrorsOf<
39
+ export type Error<T extends Any> = Placeholder.Error<
37
40
  T['to'] | T['replace'] | T['state'] | T['relative'] | T['key']
38
41
  >
39
42
  }
@@ -42,7 +45,8 @@ export interface UseLink<E> {
42
45
  readonly url: Fx.Computed<Router, E, string>
43
46
  readonly options: Fx.Computed<never, E, Navigation.NavigateOptions>
44
47
  readonly navigate: Effect.Effect<Router, E, Navigation.Destination>
45
- readonly active: Fx.Computed<Router, E, boolean>
48
+ readonly active: Fx.Fx<Router, E, boolean>
49
+ readonly onClick: EventHandler<KeyboardEvent | MouseEvent, Router, E>
46
50
  }
47
51
 
48
52
  export namespace UseLink {
@@ -63,15 +67,16 @@ export function useLink<Params extends UseLinkParams.Any>(
63
67
  Placeholder.asRef(params.state ?? null),
64
68
  Placeholder.asRef(params.key),
65
69
  Placeholder.asRef(params.relative ?? true),
70
+ Router,
66
71
  ] as const),
67
- ([to, replace, state, key, relative]) => {
72
+ ([to, replace, state, key, relative, router]) => {
68
73
  const url = Fx.RefSubject.tuple(to, relative).mapEffect(([to, relative]) =>
69
74
  Effect.gen(function* ($) {
70
75
  let url = to
71
76
 
72
77
  // Check if we should make the URL relative to the current route
73
78
  if (relative) {
74
- const { route, params } = yield* $(Router)
79
+ const { route, params } = router
75
80
  const matched = yield* $(params)
76
81
  const basePath = route.make(matched)
77
82
 
@@ -89,15 +94,8 @@ export function useLink<Params extends UseLinkParams.Any>(
89
94
  }),
90
95
  )
91
96
 
92
- const active: Fx.Computed<Router, UseLinkParams.Error<Params>, boolean> = url.mapEffect(
93
- (url) =>
94
- Effect.gen(function* ($) {
95
- const {
96
- navigation: { currentEntry },
97
- } = yield* $(Router)
98
-
99
- return isActive(url, (yield* $(currentEntry)).url)
100
- }),
97
+ const active = Fx.map(Fx.combine(url, router.navigation.currentEntry), ([url, destination]) =>
98
+ isActive(url, destination.url),
101
99
  )
102
100
 
103
101
  const navigate: Effect.Effect<
@@ -108,11 +106,18 @@ export function useLink<Params extends UseLinkParams.Any>(
108
106
  Router.withEffect((r) => r.navigation.navigate(url, options)),
109
107
  )
110
108
 
109
+ const onClick = EventHandler.preventDefault.if<
110
+ KeyboardEvent | MouseEvent,
111
+ Router,
112
+ UseLinkParams.Error<Params>
113
+ >(not(getIsUsingKeyModifier), () => navigate)
114
+
111
115
  return {
112
116
  url,
113
117
  options,
114
118
  navigate,
115
119
  active,
120
+ onClick,
116
121
  } satisfies UseLink.FromParams<Params>
117
122
  },
118
123
  )
package/src/Match.ts CHANGED
@@ -54,16 +54,16 @@ export namespace Match {
54
54
  : never
55
55
 
56
56
  export type Context<M extends Any> =
57
- | Fx.Fx.ResourcesOf<Rendered<M>>
57
+ | Fx.Fx.Context<Rendered<M>>
58
58
  | ([Guard<M>] extends [never] ? never : Effect.Effect.Context<Guard<M>>)
59
59
  | ([Matched<M>] extends [never] ? never : Effect.Effect.Context<Matched<M>>)
60
60
 
61
61
  export type Error<M extends Any> =
62
- | Fx.Fx.ErrorsOf<Rendered<M>>
62
+ | Fx.Fx.Error<Rendered<M>>
63
63
  | ([Guard<M>] extends [never] ? never : Exclude<Effect.Effect.Error<Guard<M>>, NavigationError>)
64
64
  | ([Matched<M>] extends [never] ? never : Effect.Effect.Error<Matched<M>>)
65
65
 
66
- export type Success<M extends Any> = Fx.Fx.OutputOf<Rendered<M>>
66
+ export type Success<M extends Any> = Fx.Fx.Success<Rendered<M>>
67
67
  }
68
68
 
69
69
  export function Match<P extends string, Rendered extends Fx.Fx<any, any, any>>(
package/src/Matcher.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  import * as Chunk from '@effect/data/Chunk'
2
2
  import * as Debug from '@effect/data/Function'
3
+ import * as Pipeable from '@effect/data/Pipeable'
4
+ import * as Cause from '@effect/io/Cause'
3
5
  import * as Effect from '@effect/io/Effect'
4
6
  import * as Fx from '@typed/fx'
5
7
  import { RenderContext } from '@typed/html'
@@ -11,16 +13,31 @@ import { Redirect } from './Redirect.js'
11
13
  import { matchRoutes } from './matchRoutes.js'
12
14
  import { Router } from './router.js'
13
15
 
14
- export interface Matcher<Matches extends ReadonlyArray<Match.Any>> {
16
+ export interface Matcher<Matches extends ReadonlyArray<Match.Any>> extends Pipeable.Pipeable {
15
17
  /** @internal */
16
18
  readonly matches: Chunk.Chunk<Match.Any>
17
19
 
20
+ /**
21
+ * Matches a route to an Fx
22
+ */
18
23
  readonly match: <P extends string, R, E, A, Opts extends MatchOptions.Any<P> = MatchOptions<P>>(
19
24
  route: Route<P>,
20
25
  render: (params: Fx.Filtered<never, never, ParamsOf<P>>) => Fx.Fx<R, E, A>,
21
26
  options?: Opts,
22
27
  ) => Matcher<readonly [...Matches, Match<P, Fx.Fx<R, E, A>, Opts>]>
23
28
 
29
+ /**
30
+ * Matches a route to a value
31
+ */
32
+ readonly matchTo: <P extends string, A, Opts extends MatchOptions.Any<P> = MatchOptions<P>>(
33
+ route: Route<P>,
34
+ to: (params: ParamsOf<P>) => A,
35
+ options?: Opts,
36
+ ) => Matcher<readonly [...Matches, Match<P, Fx.Fx<never, never, A>, Opts>]>
37
+
38
+ /**
39
+ * Matches a route to a lazy Fx
40
+ */
24
41
  readonly matchLazy: <
25
42
  P extends string,
26
43
  R,
@@ -33,6 +50,10 @@ export interface Matcher<Matches extends ReadonlyArray<Match.Any>> {
33
50
  options?: Opts,
34
51
  ) => Matcher<readonly [...Matches, Match<P, Fx.Fx<R, E, A>, Opts>]>
35
52
 
53
+ /**
54
+ * The default way to turn a Matcher into an Fx is by providing an Fx to run when
55
+ * no routes match.
56
+ */
36
57
  readonly notFound: <R, E, A>(
37
58
  render: (params: Fx.Filtered<never, never, Readonly<Record<string, string>>>) => Fx.Fx<R, E, A>,
38
59
  ) => Fx.Fx<
@@ -41,6 +62,32 @@ export interface Matcher<Matches extends ReadonlyArray<Match.Any>> {
41
62
  A | Match.Success<Matches[number]>
42
63
  >
43
64
 
65
+ /**
66
+ * Redirect to a route when no routes match. This variant will only utilize
67
+ * the route provided to it.
68
+ */
69
+ readonly redirect: <P extends string>(
70
+ route: Route<P>,
71
+ ...params: [keyof ParamsOf<P>] extends [never] ? [] : [ParamsOf<P>]
72
+ ) => Fx.Fx<
73
+ Router | RenderContext | Match.Context<Matches[number]>,
74
+ Exclude<Match.Error<Matches[number]>, Redirect>,
75
+ Match.Success<Matches[number]>
76
+ >
77
+
78
+ /**
79
+ * Redirect to a route when no routes match. This variant will utilize the
80
+ * parent Router to redirect a route relative to it.
81
+ */
82
+ readonly relativeRedirect: <P extends string>(
83
+ route: Route<P>,
84
+ ...params: [keyof ParamsOf<P>] extends [never] ? [] : [ParamsOf<P>]
85
+ ) => Fx.Fx<
86
+ Router | RenderContext | Match.Context<Matches[number]>,
87
+ Cause.NoSuchElementException | Exclude<Match.Error<Matches[number]>, Redirect>,
88
+ Match.Success<Matches[number]>
89
+ >
90
+
44
91
  readonly concat: <OtherMatches extends ReadonlyArray<Match.Any>>(
45
92
  other: Matcher<OtherMatches>,
46
93
  ) => Matcher<readonly [...Matches, ...OtherMatches]>
@@ -49,17 +96,24 @@ export interface Matcher<Matches extends ReadonlyArray<Match.Any>> {
49
96
  export function Matcher<const Matches extends ReadonlyArray<Match.Any>>(
50
97
  matches: Chunk.Chunk<Match.Any>,
51
98
  ): Matcher<Matches> {
52
- return {
53
- matches,
99
+ function match<P extends string, R, E, A, Opts extends MatchOptions.Any<P> = never>(
100
+ route: Route<P>,
101
+ render: (params: Fx.Filtered<never, never, ParamsOf<P>>) => Fx.Fx<R, E, A>,
102
+ options?: Opts,
103
+ ): Matcher<readonly [...Matches, Match<P, Fx.Fx<R, E, A>, Opts>]> {
104
+ return Matcher(Chunk.append(matches, Match(route, render, options || {})))
105
+ }
54
106
 
55
- match<P extends string, R, E, A, Opts extends MatchOptions.Any<P> = never>(
107
+ const self: Matcher<Matches> = {
108
+ matches,
109
+ match,
110
+ matchTo<P extends string, A, Opts extends MatchOptions.Any<P> = never>(
56
111
  route: Route<P>,
57
- render: (params: Fx.Filtered<never, never, ParamsOf<P>>) => Fx.Fx<R, E, A>,
112
+ to: (params: ParamsOf<P>) => A,
58
113
  options?: Opts,
59
- ): Matcher<readonly [...Matches, Match<P, Fx.Fx<R, E, A>, Opts>]> {
60
- return Matcher(Chunk.append(matches, Match(route, render, options || {})))
114
+ ): Matcher<readonly [...Matches, Match<P, Fx.Fx<never, never, A>, Opts>]> {
115
+ return match(route, (params) => params.map(to), options)
61
116
  },
62
-
63
117
  matchLazy<P extends string, R, E, A, Opts extends MatchOptions.Any<P> = never>(
64
118
  route: Route<P>,
65
119
  render: () => Promise<(params: Fx.Filtered<never, never, ParamsOf<P>>) => Fx.Fx<R, E, A>>,
@@ -74,15 +128,45 @@ export function Matcher<const Matches extends ReadonlyArray<Match.Any>>(
74
128
  ) => Fx.Fx<R, E, A>,
75
129
  ) => Fx.scoped(matchRoutes(Chunk.toReadonlyArray(matches) as Matches, render)),
76
130
 
131
+ redirect: (route, params?) =>
132
+ redirectEffect(
133
+ self,
134
+ Redirect.redirect(route.make(params || ({} as any)), {
135
+ history: 'replace',
136
+ }),
137
+ ),
138
+
139
+ relativeRedirect: (route, params?) =>
140
+ redirectEffect(
141
+ self,
142
+ Router.withEffect((router: Router) =>
143
+ Effect.gen(function* ($) {
144
+ const parentParams: ParamsOf<string> = yield* $(router.params)
145
+ const allParams = { ...parentParams, ...params }
146
+ const nested = router.route.concat(route)
147
+ const url = nested.make(allParams as any)
148
+
149
+ return yield* $(Redirect.redirect(url, { history: 'replace' }))
150
+ }),
151
+ ),
152
+ ),
153
+
77
154
  concat: <OtherMatches extends ReadonlyArray<Match.Any>>(
78
155
  other: Matcher<OtherMatches>,
79
156
  ): Matcher<readonly [...Matches, ...OtherMatches]> => {
80
157
  return Matcher(Chunk.appendAll(matches, other.matches))
81
158
  },
159
+
160
+ pipe() {
161
+ // eslint-disable-next-line prefer-rest-params
162
+ return Pipeable.pipeArguments(this, arguments)
163
+ },
82
164
  }
165
+
166
+ return self
83
167
  }
84
168
 
85
- export const { match, matchLazy } = Matcher<readonly []>(Chunk.empty())
169
+ export const { match, matchTo, matchLazy } = Matcher<readonly []>(Chunk.empty())
86
170
 
87
171
  export const notFound: {
88
172
  <R, E, A>(
@@ -92,7 +176,7 @@ export const notFound: {
92
176
  ) => Fx.Fx<
93
177
  Router | R | Match.Context<Matches[number]>,
94
178
  Exclude<E | Match.Error<Matches[number]>, Redirect>,
95
- A | Fx.Fx.OutputOf<Match.Rendered<Matches[number]>>
179
+ A | Fx.Fx.Success<Match.Rendered<Matches[number]>>
96
180
  >
97
181
 
98
182
  <Matches extends readonly Match.Any[], R, E, A>(
@@ -101,7 +185,7 @@ export const notFound: {
101
185
  ): Fx.Fx<
102
186
  Router | R | Match.Context<Matches[number]>,
103
187
  Exclude<E | Match.Error<Matches[number]>, Redirect>,
104
- A | Fx.Fx.OutputOf<Match.Rendered<Matches[number]>>
188
+ A | Fx.Fx.Success<Match.Rendered<Matches[number]>>
105
189
  >
106
190
  } = Debug.dual(
107
191
  2,
@@ -48,7 +48,7 @@ export function matchRoutes<
48
48
 
49
49
  return [
50
50
  // If the route is the a single slash, use the route directly to keep any parsing options.
51
- match.route.path === '/' ? match.route : nestedRouter.route,
51
+ nestedRouter.route,
52
52
  render,
53
53
  match.options?.guard as
54
54
  | ((params: ParamsOf<string>) => Effect.Effect<_R, NavigationError, boolean>)
package/src/router.ts CHANGED
@@ -3,10 +3,10 @@ import * as Effect from '@effect/io/Effect'
3
3
  import * as Layer from '@effect/io/Layer'
4
4
  import { Tag } from '@typed/context'
5
5
  import { DomServicesElementParams } from '@typed/dom'
6
- import { Filtered } from '@typed/fx'
6
+ import * as Fx from '@typed/fx'
7
7
  import * as Navigation from '@typed/navigation'
8
8
  import { ParamsOf, PathJoin } from '@typed/path'
9
- import { Route } from '@typed/route'
9
+ import { Route, RouteOptions } from '@typed/route'
10
10
 
11
11
  export interface Router<in out P extends string = string> {
12
12
  /**
@@ -17,13 +17,16 @@ export interface Router<in out P extends string = string> {
17
17
  /**
18
18
  * The current params for the current path.
19
19
  */
20
- readonly params: Filtered<never, never, ParamsOf<P>>
20
+ readonly params: Fx.Filtered<never, never, ParamsOf<P>>
21
21
 
22
22
  /**
23
23
  * Construct a new Router instance by defining a new Route which is concatenated
24
24
  * to the current Route.
25
25
  */
26
- readonly define: <P2 extends string>(route: Route<P2>) => Router<PathJoin<[P, P2]>>
26
+ readonly define: <P2 extends string>(
27
+ route: Route<P2>,
28
+ overrides?: RouteOptions,
29
+ ) => Router<PathJoin<[P, P2]>>
27
30
 
28
31
  /**
29
32
  * The parent Router instance if one exists.
@@ -53,8 +56,11 @@ export const navigation: Layer.Layer<Navigation.Navigation, never, Router> = Rou
53
56
  route,
54
57
  navigation,
55
58
  params: currentPath.filterMap(route.match),
56
- define: <P2 extends string>(other: Route<P2>): Router<PathJoin<[P, P2]>> =>
57
- makeRouter(route.concat(other), Option.some(router)),
59
+ define: <P2 extends string>(
60
+ other: Route<P2>,
61
+ overrides?: RouteOptions,
62
+ ): Router<PathJoin<[P, P2]>> =>
63
+ makeRouter(route.concat(other, overrides), Option.some(router)),
58
64
  parent,
59
65
  }
60
66
 
@@ -78,3 +84,50 @@ export const memory = (
78
84
  options: Navigation.MemoryNavigationOptions,
79
85
  ): Layer.Layer<never, never, Navigation.Navigation | Router> =>
80
86
  Layer.provideMerge(Navigation.memory(options), navigation)
87
+
88
+ const routerNavigation: Layer.Layer<Router, never, Navigation.Navigation> = Layer.effectContext(
89
+ Effect.map(Router, (router) => Navigation.Navigation.build(router.navigation).context),
90
+ )
91
+
92
+ const provideRouterNavigationEffect = Effect.provideSomeLayer(routerNavigation)
93
+ const provideRouterNavigationFx = Fx.provideSomeLayer(routerNavigation)
94
+
95
+ export const back: Effect.Effect<Router, never, Navigation.Destination> =
96
+ provideRouterNavigationEffect(Navigation.back)
97
+
98
+ export const canGoBack: Effect.Effect<Router, never, boolean> & Fx.Fx<Router, never, boolean> =
99
+ Object.assign(
100
+ provideRouterNavigationEffect(Navigation.canGoBack),
101
+ provideRouterNavigationFx(Navigation.canGoBack),
102
+ )
103
+
104
+ export const canGoForward: Effect.Effect<Router, never, boolean> & Fx.Fx<Router, never, boolean> =
105
+ Object.assign(
106
+ provideRouterNavigationEffect(Navigation.canGoForward),
107
+ provideRouterNavigationFx(Navigation.canGoForward),
108
+ )
109
+
110
+ export const cancelNavigation = Navigation.cancelNavigation
111
+
112
+ export const forward = provideRouterNavigationEffect(Navigation.forward)
113
+
114
+ export const navigate: (
115
+ url: string,
116
+ options?: Navigation.NavigateOptions,
117
+ ) => Effect.Effect<Router, never, Navigation.Destination> = (url, options) =>
118
+ provideRouterNavigationEffect(Navigation.navigate(url, options))
119
+
120
+ export const push: (
121
+ url: string,
122
+ options?: Omit<Navigation.NavigateOptions, 'history'>,
123
+ ) => Effect.Effect<Router, never, Navigation.Destination> = (url, options) =>
124
+ navigate(url, { ...options, history: 'push' })
125
+
126
+ export const replace: (
127
+ url: string,
128
+ options?: Omit<Navigation.NavigateOptions, 'history'>,
129
+ ) => Effect.Effect<Router, never, Navigation.Destination> = (url, options) =>
130
+ navigate(url, { ...options, history: 'replace' })
131
+
132
+ export const reload: Effect.Effect<Router, never, Navigation.Destination> =
133
+ provideRouterNavigationEffect(Navigation.reload)