@typed/navigation 0.10.3 → 0.11.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/src/Navigation.ts CHANGED
@@ -35,45 +35,45 @@ export interface Navigation {
35
35
  readonly navigate: (
36
36
  url: string | URL,
37
37
  options?: NavigateOptions
38
- ) => Effect.Effect<never, NavigationError, Destination>
38
+ ) => Effect.Effect<Destination, NavigationError>
39
39
 
40
- readonly back: (options?: { readonly info?: unknown }) => Effect.Effect<never, NavigationError, Destination>
40
+ readonly back: (options?: { readonly info?: unknown }) => Effect.Effect<Destination, NavigationError>
41
41
 
42
- readonly forward: (options?: { readonly info?: unknown }) => Effect.Effect<never, NavigationError, Destination>
42
+ readonly forward: (options?: { readonly info?: unknown }) => Effect.Effect<Destination, NavigationError>
43
43
 
44
44
  readonly traverseTo: (
45
45
  key: Destination["key"],
46
46
  options?: { readonly info?: unknown }
47
- ) => Effect.Effect<never, NavigationError, Destination>
47
+ ) => Effect.Effect<Destination, NavigationError>
48
48
 
49
49
  readonly updateCurrentEntry: (
50
50
  options: { readonly state: unknown }
51
- ) => Effect.Effect<never, NavigationError, Destination>
51
+ ) => Effect.Effect<Destination, NavigationError>
52
52
 
53
53
  readonly reload: (
54
54
  options?: { readonly info?: unknown; readonly state?: unknown }
55
- ) => Effect.Effect<never, NavigationError, Destination>
55
+ ) => Effect.Effect<Destination, NavigationError>
56
56
 
57
57
  readonly beforeNavigation: <R = never, R2 = never>(
58
58
  handler: BeforeNavigationHandler<R, R2>
59
- ) => Effect.Effect<R | R2 | Scope.Scope, never, void>
59
+ ) => Effect.Effect<void, never, R | R2 | Scope.Scope>
60
60
 
61
61
  readonly onNavigation: <R = never, R2 = never>(
62
62
  handler: NavigationHandler<R, R2>
63
- ) => Effect.Effect<R | R2 | Scope.Scope, never, void>
63
+ ) => Effect.Effect<void, never, R | R2 | Scope.Scope>
64
64
 
65
65
  readonly submit: (
66
66
  data: FormData,
67
67
  formInput?: Simplify<Omit<FormInputFrom, "data">>
68
68
  ) => Effect.Effect<
69
- HttpClient.client.Client.Default,
69
+ Option.Option<HttpClient.response.ClientResponse>,
70
70
  NavigationError | HttpClient.error.HttpClientError,
71
- Option.Option<HttpClient.response.ClientResponse>
71
+ Scope.Scope | HttpClient.client.Client.Default
72
72
  >
73
73
 
74
74
  readonly onFormData: <R = never, R2 = never>(
75
75
  handler: FormDataHandler<R, R2>
76
- ) => Effect.Effect<R | R2 | Scope.Scope, never, void>
76
+ ) => Effect.Effect<void, never, R | R2 | Scope.Scope>
77
77
  }
78
78
 
79
79
  /**
@@ -203,11 +203,11 @@ export interface NavigationEvent extends Schema.Schema.To<typeof NavigationEvent
203
203
  export type BeforeNavigationHandler<R, R2> = (
204
204
  event: BeforeNavigationEvent
205
205
  ) => Effect.Effect<
206
- R,
207
- RedirectError | CancelNavigation,
208
206
  Option.Option<
209
- Effect.Effect<R2, RedirectError | CancelNavigation, unknown>
210
- >
207
+ Effect.Effect<unknown, RedirectError | CancelNavigation, R2>
208
+ >,
209
+ RedirectError | CancelNavigation,
210
+ R
211
211
  >
212
212
 
213
213
  /**
@@ -216,11 +216,11 @@ export type BeforeNavigationHandler<R, R2> = (
216
216
  export type NavigationHandler<R, R2> = (
217
217
  event: NavigationEvent
218
218
  ) => Effect.Effect<
219
- R,
220
- never,
221
219
  Option.Option<
222
- Effect.Effect<R2, never, unknown>
223
- >
220
+ Effect.Effect<unknown, never, R2>
221
+ >,
222
+ never,
223
+ R
224
224
  >
225
225
 
226
226
  /**
@@ -229,11 +229,11 @@ export type NavigationHandler<R, R2> = (
229
229
  export type FormDataHandler<R, R2> = (
230
230
  event: FormDataEvent
231
231
  ) => Effect.Effect<
232
- R,
233
- RedirectError | CancelNavigation,
234
232
  Option.Option<
235
- Effect.Effect<R2, RedirectError | CancelNavigation, Option.Option<HttpClient.response.ClientResponse>>
236
- >
233
+ Effect.Effect<Option.Option<HttpClient.response.ClientResponse>, RedirectError | CancelNavigation, R2>
234
+ >,
235
+ RedirectError | CancelNavigation,
236
+ R
237
237
  >
238
238
 
239
239
  /**
@@ -400,12 +400,12 @@ export function isCancelNavigation(e: unknown): e is CancelNavigation {
400
400
  export const navigate = (
401
401
  url: string | URL,
402
402
  options?: NavigateOptions
403
- ): Effect.Effect<Navigation, NavigationError, Destination> => Navigation.withEffect((n) => n.navigate(url, options))
403
+ ): Effect.Effect<Destination, NavigationError, Navigation> => Navigation.withEffect((n) => n.navigate(url, options))
404
404
 
405
405
  /**
406
406
  * @since 1.0.0
407
407
  */
408
- export const back: (options?: { readonly info?: unknown }) => Effect.Effect<Navigation, NavigationError, Destination> =
408
+ export const back: (options?: { readonly info?: unknown }) => Effect.Effect<Destination, NavigationError, Navigation> =
409
409
  (opts) => Navigation.withEffect((n) => n.back(opts))
410
410
 
411
411
  /**
@@ -413,7 +413,7 @@ export const back: (options?: { readonly info?: unknown }) => Effect.Effect<Navi
413
413
  */
414
414
  export const forward: (
415
415
  options?: { readonly info?: unknown }
416
- ) => Effect.Effect<Navigation, NavigationError, Destination> = (
416
+ ) => Effect.Effect<Destination, NavigationError, Navigation> = (
417
417
  opts
418
418
  ) => Navigation.withEffect((n) => n.forward(opts))
419
419
 
@@ -423,7 +423,7 @@ export const forward: (
423
423
  export const traverseTo: (
424
424
  key: Uuid,
425
425
  options?: { readonly info?: unknown }
426
- ) => Effect.Effect<Navigation, NavigationError, Destination> = (key, opts) =>
426
+ ) => Effect.Effect<Destination, NavigationError, Navigation> = (key, opts) =>
427
427
  Navigation.withEffect((n) => n.traverseTo(key, opts))
428
428
 
429
429
  /**
@@ -431,7 +431,7 @@ export const traverseTo: (
431
431
  */
432
432
  export const updateCurrentEntry: (
433
433
  options: { readonly state: unknown }
434
- ) => Effect.Effect<Navigation, NavigationError, Destination> = (opts) =>
434
+ ) => Effect.Effect<Destination, NavigationError, Navigation> = (opts) =>
435
435
  Navigation.withEffect((n) => n.updateCurrentEntry(opts))
436
436
 
437
437
  /**
@@ -439,7 +439,7 @@ export const updateCurrentEntry: (
439
439
  */
440
440
  export const reload: (
441
441
  options?: { readonly info?: unknown; readonly state?: unknown }
442
- ) => Effect.Effect<Navigation, NavigationError, Destination> = (
442
+ ) => Effect.Effect<Destination, NavigationError, Navigation> = (
443
443
  opts
444
444
  ) => Navigation.withEffect((n) => n.reload(opts))
445
445
 
@@ -508,9 +508,9 @@ export function submit(
508
508
  data: FormData,
509
509
  formInput?: Simplify<Omit<FormInputFrom, "data">>
510
510
  ): Effect.Effect<
511
- Navigation | HttpClient.client.Client.Default,
511
+ Option.Option<HttpClient.response.ClientResponse>,
512
512
  NavigationError | HttpClient.error.HttpClientError,
513
- Option.Option<HttpClient.response.ClientResponse>
513
+ Navigation | HttpClient.client.Client.Default | Scope.Scope
514
514
  > {
515
515
  return Navigation.withEffect((n) => n.submit(data, formInput))
516
516
  }
@@ -520,6 +520,6 @@ export function submit(
520
520
  */
521
521
  export function onFormData<R = never, R2 = never>(
522
522
  handler: FormDataHandler<R, R2>
523
- ): Effect.Effect<Navigation | R | R2 | Scope.Scope, never, void> {
523
+ ): Effect.Effect<void, never, Navigation | R | R2 | Scope.Scope> {
524
524
  return Navigation.withEffect((n) => n.onFormData(handler))
525
525
  }
@@ -38,7 +38,7 @@ declare global {
38
38
  }
39
39
  }
40
40
 
41
- export const fromWindow: Layer.Layer<Window, never, Navigation> = Navigation.scoped(
41
+ export const fromWindow: Layer.Layer<Navigation, never, Window> = Navigation.scoped(
42
42
  Window.withEffect((window) => {
43
43
  const getRandomValues = (length: number) => Effect.sync(() => window.crypto.getRandomValues(new Uint8Array(length)))
44
44
  return Effect.gen(function*(_) {
@@ -108,12 +108,8 @@ const getNavigationState = (navigation: NativeNavigation): NavigationState => {
108
108
 
109
109
  function setupWithNavigation(
110
110
  navigation: NativeNavigation,
111
- runPromise: <E, A>(effect: Effect.Effect<Scope.Scope, E, A>) => Promise<A>
112
- ): Effect.Effect<
113
- Scope.Scope | GetRandomValues,
114
- never,
115
- ModelAndIntent
116
- > {
111
+ runPromise: <E, A>(effect: Effect.Effect<A, E, Scope.Scope>) => Promise<A>
112
+ ): Effect.Effect<ModelAndIntent, never, Scope.Scope | GetRandomValues> {
117
113
  return Effect.gen(function*(_) {
118
114
  const state = yield* _(
119
115
  RefSubject.fromEffect(
@@ -150,7 +146,7 @@ function setupWithNavigation(
150
146
  const runHandlers = (native: NativeEvent) =>
151
147
  Effect.gen(function*(_) {
152
148
  const eventHandlers = yield* _(handlers)
153
- const matches: Array<Effect.Effect<never, never, unknown>> = []
149
+ const matches: Array<Effect.Effect<unknown>> = []
154
150
 
155
151
  const event: NavigationEvent = {
156
152
  type: native.navigationType,
@@ -220,11 +216,7 @@ function shouldNotIntercept(navigationEvent: NativeEvent): boolean {
220
216
  function setupWithHistory(
221
217
  window: Window,
222
218
  onEvent: (event: HistoryEvent) => void
223
- ): Effect.Effect<
224
- GetRandomValues | Scope.Scope,
225
- never,
226
- ModelAndIntent
227
- > {
219
+ ): Effect.Effect<ModelAndIntent, never, GetRandomValues | Scope.Scope> {
228
220
  return Effect.gen(function*(_) {
229
221
  const { location } = window
230
222
  const { original: history, unpatch } = patchHistory(window, onEvent)
@@ -411,19 +403,15 @@ function patchHistory(window: Window, onEvent: (event: HistoryEvent) => void) {
411
403
  type ScopedRuntime<R> = {
412
404
  readonly runtime: Runtime.Runtime<R | Scope.Scope>
413
405
  readonly scope: Scope.Scope
414
- readonly run: <E, A>(effect: Effect.Effect<R | Scope.Scope, E, A>) => Fiber.RuntimeFiber<E, A>
415
- readonly runPromise: <E, A>(effect: Effect.Effect<R | Scope.Scope, E, A>) => Promise<A>
406
+ readonly run: <E, A>(effect: Effect.Effect<A, E, R | Scope.Scope>) => Fiber.RuntimeFiber<A, E>
407
+ readonly runPromise: <E, A>(effect: Effect.Effect<A, E, R | Scope.Scope>) => Promise<A>
416
408
  }
417
409
 
418
- function scopedRuntime<R>(): Effect.Effect<
419
- R | Scope.Scope,
420
- never,
421
- ScopedRuntime<R>
422
- > {
410
+ function scopedRuntime<R>(): Effect.Effect<ScopedRuntime<R>, never, R | Scope.Scope> {
423
411
  return Effect.map(Effect.runtime<R | Scope.Scope>(), (runtime) => {
424
412
  const scope = Context.get(runtime.context, Scope.Scope)
425
413
  const runFork = Runtime.runFork(runtime)
426
- const runPromise = <E, A>(effect: Effect.Effect<R | Scope.Scope, E, A>): Promise<A> =>
414
+ const runPromise = <E, A>(effect: Effect.Effect<A, E, R | Scope.Scope>): Promise<A> =>
427
415
  new Promise((resolve, reject) => {
428
416
  const fiber = runFork(effect, { scope })
429
417
  fiber.addObserver(Exit.match({
@@ -18,7 +18,7 @@ import {
18
18
  setupFromModelAndIntent
19
19
  } from "./shared.js"
20
20
 
21
- export const memory = (options: MemoryOptions): Layer.Layer<never, never, Navigation> =>
21
+ export const memory = (options: MemoryOptions): Layer.Layer<Navigation> =>
22
22
  Navigation.scoped(
23
23
  Effect.gen(function*(_) {
24
24
  const getRandomValues = yield* _(GetRandomValues)
@@ -33,7 +33,7 @@ export const memory = (options: MemoryOptions): Layer.Layer<never, never, Naviga
33
33
 
34
34
  export function initialMemory(
35
35
  options: InitialMemoryOptions
36
- ): Layer.Layer<never, never, Navigation> {
36
+ ): Layer.Layer<Navigation> {
37
37
  return Navigation.scoped(
38
38
  Effect.gen(function*(_) {
39
39
  const getRandomValues = yield* _(GetRandomValues)
@@ -56,11 +56,7 @@ export function initialMemory(
56
56
 
57
57
  function setupMemory(
58
58
  options: MemoryOptions
59
- ): Effect.Effect<
60
- GetRandomValues | Scope.Scope,
61
- never,
62
- ModelAndIntent
63
- > {
59
+ ): Effect.Effect<ModelAndIntent, never, GetRandomValues | Scope.Scope> {
64
60
  return Effect.gen(function*(_) {
65
61
  const state = yield* _(
66
62
  RefSubject.fromEffect(
@@ -92,7 +92,7 @@ export function setupFromModelAndIntent(
92
92
  const runBeforeHandlers = (event: BeforeNavigationEvent) =>
93
93
  Effect.gen(function*(_) {
94
94
  const handlers = yield* _(beforeHandlers)
95
- const matches: Array<Effect.Effect<never, RedirectError | CancelNavigation, unknown>> = []
95
+ const matches: Array<Effect.Effect<unknown, RedirectError | CancelNavigation>> = []
96
96
 
97
97
  for (const [handler, ctx] of handlers) {
98
98
  const exit = yield* _(handler(event), Effect.provide(ctx), Effect.either)
@@ -121,7 +121,7 @@ export function setupFromModelAndIntent(
121
121
  const runHandlers = (event: NavigationEvent) =>
122
122
  Effect.gen(function*(_) {
123
123
  const eventHandlers = yield* _(handlers)
124
- const matches: Array<Effect.Effect<never, never, unknown>> = []
124
+ const matches: Array<Effect.Effect<unknown>> = []
125
125
 
126
126
  for (const [handler, ctx] of eventHandlers) {
127
127
  const match = yield* _(handler(event), Effect.provide(ctx))
@@ -138,14 +138,14 @@ export function setupFromModelAndIntent(
138
138
  const runFormDataHandlers = (
139
139
  event: FormDataEvent
140
140
  ): Effect.Effect<
141
- HttpClient.client.Client.Default,
141
+ Either.Either<RedirectError | CancelNavigation, Option.Option<HttpClient.response.ClientResponse>>,
142
142
  NavigationError | HttpClient.error.HttpClientError,
143
- Either.Either<RedirectError | CancelNavigation, Option.Option<HttpClient.response.ClientResponse>>
143
+ Scope.Scope | HttpClient.client.Client.Default
144
144
  > =>
145
145
  Effect.gen(function*(_) {
146
146
  const handlers = yield* _(formDataHandlers)
147
147
  const matches: Array<
148
- Effect.Effect<never, RedirectError | CancelNavigation, Option.Option<HttpClient.response.ClientResponse>>
148
+ Effect.Effect<Option.Option<HttpClient.response.ClientResponse>, RedirectError | CancelNavigation>
149
149
  > = []
150
150
 
151
151
  for (const [handler, ctx] of handlers) {
@@ -183,11 +183,11 @@ export function setupFromModelAndIntent(
183
183
 
184
184
  const runNavigationEvent = (
185
185
  beforeEvent: BeforeNavigationEvent,
186
- get: Effect.Effect<never, never, NavigationState>,
187
- set: (a: NavigationState) => Effect.Effect<never, never, NavigationState>,
186
+ get: Effect.Effect<NavigationState>,
187
+ set: (a: NavigationState) => Effect.Effect<NavigationState>,
188
188
  depth: number,
189
189
  skipCommit: boolean = false
190
- ): Effect.Effect<never, NavigationError, Destination> =>
190
+ ): Effect.Effect<Destination, NavigationError> =>
191
191
  Effect.gen(function*(_) {
192
192
  let current = yield* _(get)
193
193
  current = yield* _(set({ ...current, transition: Option.some(beforeEvent) }))
@@ -246,10 +246,10 @@ export function setupFromModelAndIntent(
246
246
 
247
247
  const handleError = (
248
248
  error: RedirectError | CancelNavigation,
249
- get: Effect.Effect<never, never, NavigationState>,
250
- set: (a: NavigationState) => Effect.Effect<never, never, NavigationState>,
249
+ get: Effect.Effect<NavigationState>,
250
+ set: (a: NavigationState) => Effect.Effect<NavigationState>,
251
251
  depth: number
252
- ): Effect.Effect<never, NavigationError, Destination> =>
252
+ ): Effect.Effect<Destination, NavigationError> =>
253
253
  Effect.gen(function*(_) {
254
254
  if (depth >= 25) {
255
255
  return yield* _(Effect.dieMessage(`Redirect loop detected.`))
@@ -355,7 +355,7 @@ export function setupFromModelAndIntent(
355
355
 
356
356
  const beforeNavigation = <R = never, R2 = never>(
357
357
  handler: BeforeNavigationHandler<R, R2>
358
- ): Effect.Effect<R | R2 | Scope.Scope, never, void> =>
358
+ ): Effect.Effect<void, never, R | R2 | Scope.Scope> =>
359
359
  Effect.contextWithEffect((ctx) => {
360
360
  const entry = [handler, ctx] as const
361
361
 
@@ -373,7 +373,7 @@ export function setupFromModelAndIntent(
373
373
 
374
374
  const onNavigation = <R = never, R2 = never>(
375
375
  handler: NavigationHandler<R, R2>
376
- ): Effect.Effect<R | R2 | Scope.Scope, never, void> =>
376
+ ): Effect.Effect<void, never, R | R2 | Scope.Scope> =>
377
377
  Effect.contextWithEffect((ctx) => {
378
378
  const entry = [handler, ctx] as const
379
379
 
@@ -410,9 +410,9 @@ export function setupFromModelAndIntent(
410
410
  data: FormData,
411
411
  input?: Omit<FormInputFrom, "data">
412
412
  ): Effect.Effect<
413
- HttpClient.client.Client.Default,
413
+ Option.Option<HttpClient.response.ClientResponse>,
414
414
  NavigationError | HttpClient.error.HttpClientError,
415
- Option.Option<HttpClient.response.ClientResponse>
415
+ Scope.Scope | HttpClient.client.Client.Default
416
416
  > =>
417
417
  state.runUpdates(({ get, set }) =>
418
418
  Effect.gen(function*(_) {
@@ -457,7 +457,7 @@ export function setupFromModelAndIntent(
457
457
 
458
458
  const onFormData = <R = never, R2 = never>(
459
459
  handler: FormDataHandler<R, R2>
460
- ): Effect.Effect<R | R2 | Scope.Scope, never, void> =>
460
+ ): Effect.Effect<void, never, R | R2 | Scope.Scope> =>
461
461
  Effect.contextWithEffect((ctx) => {
462
462
  const entry = [handler, ctx] as const
463
463