@typed/navigation 0.13.5 → 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.
Files changed (42) hide show
  1. package/dist/cjs/Blocking.js +8 -8
  2. package/dist/cjs/Blocking.js.map +1 -1
  3. package/dist/cjs/Layer.js +1 -1
  4. package/dist/cjs/Layer.js.map +1 -1
  5. package/dist/cjs/Navigation.js +66 -57
  6. package/dist/cjs/Navigation.js.map +1 -1
  7. package/dist/cjs/internal/fromWindow.js +32 -32
  8. package/dist/cjs/internal/fromWindow.js.map +1 -1
  9. package/dist/cjs/internal/memory.js +18 -20
  10. package/dist/cjs/internal/memory.js.map +1 -1
  11. package/dist/cjs/internal/shared.js +88 -88
  12. package/dist/cjs/internal/shared.js.map +1 -1
  13. package/dist/dts/Blocking.d.ts +1 -1
  14. package/dist/dts/Blocking.d.ts.map +1 -1
  15. package/dist/dts/Layer.d.ts +2 -1
  16. package/dist/dts/Layer.d.ts.map +1 -1
  17. package/dist/dts/Navigation.d.ts +122 -199
  18. package/dist/dts/Navigation.d.ts.map +1 -1
  19. package/dist/dts/internal/fromWindow.d.ts +1 -1
  20. package/dist/dts/internal/fromWindow.d.ts.map +1 -1
  21. package/dist/dts/internal/memory.d.ts +1 -1
  22. package/dist/dts/internal/memory.d.ts.map +1 -1
  23. package/dist/dts/internal/shared.d.ts +34 -68
  24. package/dist/dts/internal/shared.d.ts.map +1 -1
  25. package/dist/esm/Blocking.js +7 -7
  26. package/dist/esm/Blocking.js.map +1 -1
  27. package/dist/esm/Layer.js.map +1 -1
  28. package/dist/esm/Navigation.js +55 -46
  29. package/dist/esm/Navigation.js.map +1 -1
  30. package/dist/esm/internal/fromWindow.js +25 -25
  31. package/dist/esm/internal/fromWindow.js.map +1 -1
  32. package/dist/esm/internal/memory.js +15 -17
  33. package/dist/esm/internal/memory.js.map +1 -1
  34. package/dist/esm/internal/shared.js +76 -76
  35. package/dist/esm/internal/shared.js.map +1 -1
  36. package/package.json +8 -8
  37. package/src/Blocking.ts +21 -23
  38. package/src/Layer.ts +2 -1
  39. package/src/Navigation.ts +81 -75
  40. package/src/internal/fromWindow.ts +44 -47
  41. package/src/internal/memory.ts +17 -23
  42. package/src/internal/shared.ts +82 -91
package/src/Navigation.ts CHANGED
@@ -3,15 +3,16 @@
3
3
  */
4
4
 
5
5
  import type * as HttpClient from "@effect/platform/HttpClient"
6
- import { Parser, ParseResult } from "@effect/schema"
6
+ import { ParseResult } from "@effect/schema"
7
7
  import * as Schema from "@effect/schema/Schema"
8
8
  import { Tagged } from "@typed/context"
9
9
  import * as RefSubject from "@typed/fx/RefSubject"
10
10
  import type { Uuid } from "@typed/id"
11
11
  import * as IdSchema from "@typed/id/Schema"
12
- import type { Option, Scope } from "effect"
13
12
  import * as Data from "effect/Data"
14
13
  import * as Effect from "effect/Effect"
14
+ import type * as Option from "effect/Option"
15
+ import type * as Scope from "effect/Scope"
15
16
  import type { Simplify } from "effect/Types"
16
17
 
17
18
  /**
@@ -83,40 +84,42 @@ export const Navigation: Tagged<Navigation> = Tagged<Navigation, Navigation>("@t
83
84
 
84
85
  const urlSchema_ = Schema.instanceOf(URL).pipe(Schema.equivalence((a, b) => a.href === b.href))
85
86
 
86
- const urlSchema = Schema.string.pipe(
87
+ const urlSchema = Schema.String.pipe(
87
88
  Schema.transformOrFail(
88
89
  urlSchema_,
89
- (s) =>
90
- Effect.suspend(() => {
91
- try {
92
- return Effect.succeed(new URL(s))
93
- } catch {
94
- return Effect.fail(ParseResult.type(urlSchema_.ast, s, `Expected a URL`))
95
- }
96
- }),
97
- (url) => Effect.succeed(url.toString())
90
+ {
91
+ decode: (s) =>
92
+ Effect.suspend(() => {
93
+ try {
94
+ return Effect.succeed(new URL(s))
95
+ } catch {
96
+ return Effect.fail(new ParseResult.Type(urlSchema_.ast, s, `Expected a URL`))
97
+ }
98
+ }),
99
+ encode: (url) => Effect.succeed(url.toString())
100
+ }
98
101
  )
99
102
  )
100
103
 
101
104
  /**
102
105
  * @since 1.0.0
103
106
  */
104
- export const Destination = Schema.struct({
107
+ export const Destination = Schema.Struct({
105
108
  id: IdSchema.uuid,
106
109
  key: IdSchema.uuid,
107
110
  url: urlSchema,
108
- state: Schema.unknown,
109
- sameDocument: Schema.boolean
111
+ state: Schema.Unknown,
112
+ sameDocument: Schema.Boolean
110
113
  })
111
114
 
112
115
  /**
113
116
  * @since 1.0.0
114
117
  */
115
- export type DestinationJson = Schema.Schema.From<typeof Destination>
118
+ export type DestinationJson = Schema.Schema.Encoded<typeof Destination>
116
119
  /**
117
120
  * @since 1.0.0
118
121
  */
119
- export interface Destination extends Schema.Schema.To<typeof Destination> {}
122
+ export interface Destination extends Schema.Schema.Type<typeof Destination> {}
120
123
 
121
124
  /**
122
125
  * @since 1.0.0
@@ -126,76 +129,76 @@ export const ProposedDestination = Destination.pipe(Schema.omit("id", "key"))
126
129
  /**
127
130
  * @since 1.0.0
128
131
  */
129
- export type ProposedDestinationJson = Schema.Schema.From<typeof ProposedDestination>
132
+ export type ProposedDestinationJson = Schema.Schema.Encoded<typeof ProposedDestination>
130
133
  /**
131
134
  * @since 1.0.0
132
135
  */
133
- export interface ProposedDestination extends Schema.Schema.To<typeof ProposedDestination> {}
136
+ export interface ProposedDestination extends Schema.Schema.Type<typeof ProposedDestination> {}
134
137
 
135
138
  /**
136
139
  * @since 1.0.0
137
140
  */
138
- export const NavigationType = Schema.literal("push", "replace", "reload", "traverse")
141
+ export const NavigationType = Schema.Literal("push", "replace", "reload", "traverse")
139
142
  /**
140
143
  * @since 1.0.0
141
144
  */
142
- export type NavigationType = Schema.Schema.To<typeof NavigationType>
145
+ export type NavigationType = Schema.Schema.Type<typeof NavigationType>
143
146
 
144
147
  /**
145
148
  * @since 1.0.0
146
149
  */
147
- export const Transition = Schema.struct({
150
+ export const Transition = Schema.Struct({
148
151
  type: NavigationType,
149
152
  from: Destination,
150
- to: Schema.union(ProposedDestination, Destination)
153
+ to: Schema.Union(ProposedDestination, Destination)
151
154
  })
152
155
 
153
156
  /**
154
157
  * @since 1.0.0
155
158
  */
156
- export type TransitionJson = Schema.Schema.From<typeof Transition>
159
+ export type TransitionJson = Schema.Schema.Encoded<typeof Transition>
157
160
  /**
158
161
  * @since 1.0.0
159
162
  */
160
- export interface Transition extends Schema.Schema.To<typeof Transition> {}
163
+ export interface Transition extends Schema.Schema.Type<typeof Transition> {}
161
164
 
162
165
  /**
163
166
  * @since 1.0.0
164
167
  */
165
- export const BeforeNavigationEvent = Schema.struct({
168
+ export const BeforeNavigationEvent = Schema.Struct({
166
169
  type: NavigationType,
167
170
  from: Destination,
168
- delta: Schema.number,
169
- to: Schema.union(ProposedDestination, Destination),
170
- info: Schema.unknown
171
+ delta: Schema.Number,
172
+ to: Schema.Union(ProposedDestination, Destination),
173
+ info: Schema.Unknown
171
174
  })
172
175
 
173
176
  /**
174
177
  * @since 1.0.0
175
178
  */
176
- export type BeforeNavigationEventJson = Schema.Schema.From<typeof BeforeNavigationEvent>
179
+ export type BeforeNavigationEventJson = Schema.Schema.Encoded<typeof BeforeNavigationEvent>
177
180
  /**
178
181
  * @since 1.0.0
179
182
  */
180
- export interface BeforeNavigationEvent extends Schema.Schema.To<typeof BeforeNavigationEvent> {}
183
+ export interface BeforeNavigationEvent extends Schema.Schema.Type<typeof BeforeNavigationEvent> {}
181
184
 
182
185
  /**
183
186
  * @since 1.0.0
184
187
  */
185
- export const NavigationEvent = Schema.struct({
188
+ export const NavigationEvent = Schema.Struct({
186
189
  type: NavigationType,
187
190
  destination: Destination,
188
- info: Schema.unknown
191
+ info: Schema.Unknown
189
192
  })
190
193
 
191
194
  /**
192
195
  * @since 1.0.0
193
196
  */
194
- export type NavigationEventJson = Schema.Schema.From<typeof NavigationEvent>
197
+ export type NavigationEventJson = Schema.Schema.Encoded<typeof NavigationEvent>
195
198
  /**
196
199
  * @since 1.0.0
197
200
  */
198
- export interface NavigationEvent extends Schema.Schema.To<typeof NavigationEvent> {}
201
+ export interface NavigationEvent extends Schema.Schema.Type<typeof NavigationEvent> {}
199
202
 
200
203
  /**
201
204
  * @since 1.0.0
@@ -268,19 +271,19 @@ export interface NavigateOptions {
268
271
  /**
269
272
  * @since 1.0.0
270
273
  */
271
- export const FileSchemaFrom = Schema.struct({
272
- _id: Schema.literal("File"),
273
- name: Schema.string,
274
- data: Schema.string // Base64 encoded
274
+ export const FileSchemaFrom = Schema.Struct({
275
+ _id: Schema.Literal("File"),
276
+ name: Schema.String,
277
+ data: Schema.String // Base64 encoded
275
278
  })
276
279
 
277
280
  /**
278
281
  * @since 1.0.0
279
282
  */
280
- export type FileSchemaFrom = Schema.Schema.From<typeof FileSchemaFrom>
283
+ export type FileSchemaFrom = Schema.Schema.Encoded<typeof FileSchemaFrom>
281
284
 
282
- const decodeBase64 = Parser.decode(Schema.Base64)
283
- const encodeBase64 = Parser.encode(Schema.Base64)
285
+ const decodeBase64 = ParseResult.decode(Schema.Base64)
286
+ const encodeBase64 = ParseResult.encode(Schema.Base64)
284
287
 
285
288
  /**
286
289
  * @since 1.0.0
@@ -288,35 +291,39 @@ const encodeBase64 = Parser.encode(Schema.Base64)
288
291
  export const FileSchema = FileSchemaFrom.pipe(
289
292
  Schema.transformOrFail(
290
293
  Schema.instanceOf(File),
291
- ({ data, name }) => Effect.map(decodeBase64(data), (buffer) => new File([buffer], name)),
292
- (file) =>
293
- Effect.promise(() => file.arrayBuffer()).pipe(
294
- Effect.flatMap((buffer) => encodeBase64(new Uint8Array(buffer))),
295
- Effect.map((data): FileSchemaFrom => ({ _id: "File", name: file.name, data }))
296
- )
294
+ {
295
+ decode: ({ data, name }) => Effect.map(decodeBase64(data), (buffer) => new File([buffer], name)),
296
+ encode: (file) =>
297
+ Effect.promise(() => file.arrayBuffer()).pipe(
298
+ Effect.flatMap((buffer) => encodeBase64(new Uint8Array(buffer))),
299
+ Effect.map((data): FileSchemaFrom => ({ _id: "File", name: file.name, data }))
300
+ )
301
+ }
297
302
  )
298
303
  )
299
304
 
300
305
  /**
301
306
  * @since 1.0.0
302
307
  */
303
- export const FormDataSchema = Schema.record(Schema.string, Schema.union(Schema.string, FileSchema)).pipe(
308
+ export const FormDataSchema = Schema.Record(Schema.String, Schema.Union(Schema.String, FileSchema)).pipe(
304
309
  Schema.transform(
305
310
  Schema.instanceOf(FormData),
306
- (formData) => {
307
- const data = new FormData()
308
-
309
- for (const [key, value] of Object.entries(formData)) {
310
- if (value instanceof File) {
311
- data.append(key, value, value.name)
312
- } else {
313
- data.append(key, value)
311
+ {
312
+ decode: (formData) => {
313
+ const data = new FormData()
314
+
315
+ for (const [key, value] of Object.entries(formData)) {
316
+ if (value instanceof File) {
317
+ data.append(key, value, value.name)
318
+ } else {
319
+ data.append(key, value)
320
+ }
314
321
  }
315
- }
316
322
 
317
- return data
318
- },
319
- (formData) => Object.fromEntries(formData.entries())
323
+ return data
324
+ },
325
+ encode: (formData) => Object.fromEntries(formData.entries())
326
+ }
320
327
  )
321
328
  )
322
329
 
@@ -325,38 +332,38 @@ const optionNullable = { as: "Option", nullable: true } as const
325
332
  /**
326
333
  * @since 1.0.0
327
334
  */
328
- export const FormInputSchema = Schema.struct({
329
- name: Schema.optional(Schema.string, optionNullable),
330
- action: Schema.optional(Schema.string, optionNullable),
331
- method: Schema.optional(Schema.string, optionNullable),
332
- encoding: Schema.optional(Schema.string, optionNullable),
335
+ export const FormInputSchema = Schema.Struct({
336
+ name: Schema.optional(Schema.String, optionNullable),
337
+ action: Schema.optional(Schema.String, optionNullable),
338
+ method: Schema.optional(Schema.String, optionNullable),
339
+ encoding: Schema.optional(Schema.String, optionNullable),
333
340
  data: FormDataSchema
334
341
  })
335
342
 
336
343
  /**
337
344
  * @since 1.0.0
338
345
  */
339
- export type FormInputFrom = Schema.Schema.From<typeof FormInputSchema>
346
+ export type FormInputFrom = Schema.Schema.Encoded<typeof FormInputSchema>
340
347
 
341
348
  /**
342
349
  * @since 1.0.0
343
350
  */
344
- export interface FormInput extends Schema.Schema.To<typeof FormInputSchema> {}
351
+ export interface FormInput extends Schema.Schema.Type<typeof FormInputSchema> {}
345
352
 
346
353
  /**
347
354
  * @since 1.0.0
348
355
  */
349
- export const FormDataEvent = Schema.extend(Schema.struct({ from: Destination }), FormInputSchema)
356
+ export const FormDataEvent = Schema.extend(Schema.Struct({ from: Destination }), FormInputSchema)
350
357
 
351
358
  /**
352
359
  * @since 1.0.0
353
360
  */
354
- export type FormDataEventJson = Schema.Schema.From<typeof FormDataEvent>
361
+ export type FormDataEventJson = Schema.Schema.Encoded<typeof FormDataEvent>
355
362
 
356
363
  /**
357
364
  * @since 1.0.0
358
365
  */
359
- export interface FormDataEvent extends Schema.Schema.To<typeof FormDataEvent> {}
366
+ export interface FormDataEvent extends Schema.Schema.Type<typeof FormDataEvent> {}
360
367
 
361
368
  /**
362
369
  * @since 1.0.0
@@ -461,11 +468,10 @@ export function getCurrentPathFromUrl(location: Pick<URL, "pathname" | "search"
461
468
  /**
462
469
  * @since 1.0.0
463
470
  */
464
- export const CurrentPath: RefSubject.Computed<string, never, Navigation> = RefSubject.map(
465
- CurrentEntry,
466
- (d) => getCurrentPathFromUrl(d.url)
471
+ export const CurrentPath: RefSubject.Computed<string, never, Navigation> = RefSubject.computedFromTag(
472
+ Navigation,
473
+ (nav) => RefSubject.map(nav.currentEntry, (e) => getCurrentPathFromUrl(e.url))
467
474
  )
468
-
469
475
  /**
470
476
  * @since 1.0.0
471
477
  */
@@ -10,8 +10,9 @@ import * as Option from "effect/Option"
10
10
  import * as Runtime from "effect/Runtime"
11
11
  import * as Scope from "effect/Scope"
12
12
 
13
- import { Schema } from "@effect/schema"
14
- import { Exit, type Layer } from "effect"
13
+ import * as Schema from "@effect/schema/Schema"
14
+ import * as Exit from "effect/Exit"
15
+ import type * as Layer from "effect/Layer"
15
16
  import type { Commit } from "../Layer.js"
16
17
  import type { BeforeNavigationEvent, Destination, NavigationEvent, Transition } from "../Navigation.js"
17
18
  import { Navigation, NavigationError } from "../Navigation.js"
@@ -41,14 +42,12 @@ declare global {
41
42
  export const fromWindow: Layer.Layer<Navigation, never, Window> = Navigation.scoped(
42
43
  Window.withEffect((window) => {
43
44
  const getRandomValues = (length: number) => Effect.sync(() => window.crypto.getRandomValues(new Uint8Array(length)))
44
- return Effect.gen(function*(_) {
45
- const { run, runPromise } = yield* _(scopedRuntime<never>())
45
+ return Effect.gen(function*() {
46
+ const { run, runPromise } = yield* scopedRuntime<never>()
46
47
  const hasNativeNavigation = !!window.navigation
47
- const modelAndIntent = yield* _(
48
- hasNativeNavigation
49
- ? setupWithNavigation(window.navigation!, runPromise)
50
- : setupWithHistory(window, (event) => run(handleHistoryEvent(event)))
51
- )
48
+ const modelAndIntent = yield* hasNativeNavigation
49
+ ? setupWithNavigation(window.navigation!, runPromise)
50
+ : setupWithHistory(window, (event) => run(handleHistoryEvent(event)))
52
51
 
53
52
  const navigation = setupFromModelAndIntent(
54
53
  modelAndIntent,
@@ -61,26 +60,28 @@ export const fromWindow: Layer.Layer<Navigation, never, Window> = Navigation.sco
61
60
  return navigation
62
61
 
63
62
  function handleHistoryEvent(event: HistoryEvent) {
64
- return Effect.gen(function*(_) {
63
+ return Effect.gen(function*() {
65
64
  if (event._tag === "PushState") {
66
- return yield* _(navigation.navigate(event.url, {}, event.skipCommit))
65
+ return yield* navigation.navigate(event.url, {}, event.skipCommit)
67
66
  } else if (event._tag === "ReplaceState") {
68
67
  if (Option.isSome(event.url)) {
69
- return yield* _(
70
- navigation.navigate(event.url.value, { history: "replace", state: event.state }, event.skipCommit)
68
+ return yield* navigation.navigate(
69
+ event.url.value,
70
+ { history: "replace", state: event.state },
71
+ event.skipCommit
71
72
  )
72
73
  } else {
73
- return yield* _(navigation.updateCurrentEntry(event))
74
+ return yield* navigation.updateCurrentEntry(event)
74
75
  }
75
76
  } else if (event._tag === "Traverse") {
76
- const { entries, index } = yield* _(modelAndIntent.state)
77
+ const { entries, index } = yield* modelAndIntent.state
77
78
  const toIndex = Math.min(Math.max(0, index + event.delta), entries.length - 1)
78
79
  const to = entries[toIndex]
79
80
 
80
- return yield* _(navigation.traverseTo(to.key, {}, event.skipCommit))
81
+ return yield* navigation.traverseTo(to.key, {}, event.skipCommit)
81
82
  } else {
82
- yield* _(navigation.traverseTo(event.key, {}, event.skipCommit))
83
- return yield* _(navigation.updateCurrentEntry({ state: event.state }))
83
+ yield* navigation.traverseTo(event.key, {}, event.skipCommit)
84
+ return yield* navigation.updateCurrentEntry({ state: event.state })
84
85
  }
85
86
  })
86
87
  }
@@ -110,16 +111,14 @@ function setupWithNavigation(
110
111
  navigation: NativeNavigation,
111
112
  runPromise: <E, A>(effect: Effect.Effect<A, E, Scope.Scope>) => Promise<A>
112
113
  ): Effect.Effect<ModelAndIntent, never, Scope.Scope | GetRandomValues> {
113
- return Effect.gen(function*(_) {
114
- const state = yield* _(
115
- RefSubject.fromEffect(
116
- Effect.sync((): NavigationState => getNavigationState(navigation)),
117
- { eq: Equivalence.make(Schema.to(Schema.to(NavigationState))) }
118
- )
114
+ return Effect.gen(function*() {
115
+ const state = yield* RefSubject.fromEffect(
116
+ Effect.sync((): NavigationState => getNavigationState(navigation)),
117
+ { eq: Equivalence.make(Schema.typeSchema(Schema.typeSchema(NavigationState))) }
119
118
  )
120
119
  const canGoBack = RefSubject.map(state, (s) => s.index > 0)
121
120
  const canGoForward = RefSubject.map(state, (s) => s.index < s.entries.length - 1)
122
- const { beforeHandlers, formDataHandlers, handlers } = yield* _(makeHandlersState())
121
+ const { beforeHandlers, formDataHandlers, handlers } = yield* makeHandlersState()
123
122
  const commit: Commit = (to: Destination, event: BeforeNavigationEvent) =>
124
123
  Effect.gen(function*(_) {
125
124
  const { key, state, url } = to
@@ -144,8 +143,8 @@ function setupWithNavigation(
144
143
  })
145
144
 
146
145
  const runHandlers = (native: NativeEvent) =>
147
- Effect.gen(function*(_) {
148
- const eventHandlers = yield* _(handlers)
146
+ Effect.gen(function*() {
147
+ const eventHandlers = yield* handlers
149
148
  const matches: Array<Effect.Effect<unknown>> = []
150
149
 
151
150
  const event: NavigationEvent = {
@@ -155,14 +154,14 @@ function setupWithNavigation(
155
154
  }
156
155
 
157
156
  for (const [handler, ctx] of eventHandlers) {
158
- const match = yield* _(handler(event), Effect.provide(ctx))
157
+ const match = yield* Effect.provide(handler(event), ctx)
159
158
  if (Option.isSome(match)) {
160
159
  matches.push(Effect.provide(match.value, ctx))
161
160
  }
162
161
  }
163
162
 
164
163
  if (matches.length > 0) {
165
- yield* _(Effect.all(matches))
164
+ yield* Effect.all(matches)
166
165
  }
167
166
  })
168
167
 
@@ -217,30 +216,28 @@ function setupWithHistory(
217
216
  window: Window,
218
217
  onEvent: (event: HistoryEvent) => void
219
218
  ): Effect.Effect<ModelAndIntent, never, GetRandomValues | Scope.Scope> {
220
- return Effect.gen(function*(_) {
219
+ return Effect.gen(function*() {
221
220
  const { location } = window
222
221
  const { original: history, unpatch } = patchHistory(window, onEvent)
223
222
 
224
- yield* _(Effect.addFinalizer(() => unpatch))
225
-
226
- const state = yield* _(
227
- RefSubject.fromEffect(
228
- Effect.suspend(() =>
229
- Effect.map(
230
- makeDestination(
231
- new URL(location.href),
232
- history.state,
233
- location.origin
234
- ),
235
- (destination): NavigationState => ({ entries: [destination], index: 0, transition: Option.none() })
236
- )
237
- ),
238
- { eq: Equivalence.make(Schema.to(NavigationState)) }
239
- )
223
+ yield* Effect.addFinalizer(() => unpatch)
224
+
225
+ const state = yield* RefSubject.fromEffect(
226
+ Effect.suspend(() =>
227
+ Effect.map(
228
+ makeDestination(
229
+ new URL(location.href),
230
+ history.state,
231
+ location.origin
232
+ ),
233
+ (destination): NavigationState => ({ entries: [destination], index: 0, transition: Option.none() })
234
+ )
235
+ ),
236
+ { eq: Equivalence.make(Schema.typeSchema(NavigationState)) }
240
237
  )
241
238
  const canGoBack = RefSubject.map(state, (s) => s.index > 0)
242
239
  const canGoForward = RefSubject.map(state, (s) => s.index < s.entries.length - 1)
243
- const { beforeHandlers, formDataHandlers, handlers } = yield* _(makeHandlersState())
240
+ const { beforeHandlers, formDataHandlers, handlers } = yield* makeHandlersState()
244
241
  const commit: Commit = ({ id, key, state, url }: Destination, event: BeforeNavigationEvent) =>
245
242
  Effect.sync(() => {
246
243
  const { type } = event
@@ -2,8 +2,8 @@ import { Schema } from "@effect/schema"
2
2
  import * as Equivalence from "@effect/schema/Equivalence"
3
3
  import * as RefSubject from "@typed/fx/RefSubject"
4
4
  import { GetRandomValues, getRandomValues } from "@typed/id"
5
- import type { Layer } from "effect"
6
5
  import * as Effect from "effect/Effect"
6
+ import type * as Layer from "effect/Layer"
7
7
  import * as Option from "effect/Option"
8
8
  import type * as Scope from "effect/Scope"
9
9
  import type { Commit, InitialMemoryOptions, MemoryOptions } from "../Layer.js"
@@ -20,9 +20,9 @@ import {
20
20
 
21
21
  export const memory = (options: MemoryOptions): Layer.Layer<Navigation> =>
22
22
  Navigation.scoped(
23
- Effect.gen(function*(_) {
24
- const getRandomValues = yield* _(GetRandomValues)
25
- const modelAndIntent = yield* _(setupMemory(options))
23
+ Effect.gen(function*() {
24
+ const getRandomValues = yield* GetRandomValues
25
+ const modelAndIntent = yield* setupMemory(options)
26
26
  const current = options.entries[options.currentIndex ?? 0]
27
27
  const origin = options.origin ?? getOriginFromUrl(current.url)
28
28
  const base = options.base ?? "/"
@@ -35,11 +35,11 @@ export function initialMemory(
35
35
  options: InitialMemoryOptions
36
36
  ): Layer.Layer<Navigation> {
37
37
  return Navigation.scoped(
38
- Effect.gen(function*(_) {
39
- const getRandomValues = yield* _(GetRandomValues)
38
+ Effect.gen(function*() {
39
+ const getRandomValues = yield* GetRandomValues
40
40
  const origin = options.origin ?? getOriginFromUrl(options.url)
41
41
  const base = options.base ?? "/"
42
- const destination = yield* _(makeDestination(getUrl(origin, options.url), options.state, origin))
42
+ const destination = yield* makeDestination(getUrl(origin, options.url), options.state, origin)
43
43
  const memoryOptions: MemoryOptions = {
44
44
  entries: [destination],
45
45
  origin,
@@ -47,7 +47,7 @@ export function initialMemory(
47
47
  currentIndex: 0,
48
48
  maxEntries: options.maxEntries
49
49
  }
50
- const modelAndIntent = yield* _(setupMemory(memoryOptions))
50
+ const modelAndIntent = yield* setupMemory(memoryOptions)
51
51
 
52
52
  return setupFromModelAndIntent(modelAndIntent, origin, base, getRandomValues)
53
53
  }).pipe(Effect.provide(getRandomValues))
@@ -57,23 +57,17 @@ export function initialMemory(
57
57
  function setupMemory(
58
58
  options: MemoryOptions
59
59
  ): Effect.Effect<ModelAndIntent, never, GetRandomValues | Scope.Scope> {
60
- return Effect.gen(function*(_) {
61
- const state = yield* _(
62
- RefSubject.fromEffect(
63
- Effect.sync((): NavigationState => {
64
- return {
65
- entries: options.entries,
66
- index: options.currentIndex ?? options.entries.length - 1,
67
- transition: Option.none()
68
- }
69
- }),
70
- { eq: Equivalence.make(Schema.to(NavigationState)) }
71
- )
72
- )
60
+ return Effect.gen(function*() {
61
+ const state = yield* RefSubject.of<NavigationState>({
62
+ entries: options.entries,
63
+ index: options.currentIndex ?? options.entries.length - 1,
64
+ transition: Option.none()
65
+ }, { eq: Equivalence.make(Schema.typeSchema(NavigationState)) })
66
+
73
67
  const canGoBack = RefSubject.map(state, (s) => s.index > 0)
74
68
  const canGoForward = RefSubject.map(state, (s) => s.index < s.entries.length - 1)
75
- const { beforeHandlers, formDataHandlers, handlers } = yield* _(makeHandlersState())
76
- const commit: Commit = options.commit ?? (() => Effect.unit)
69
+ const { beforeHandlers, formDataHandlers, handlers } = yield* makeHandlersState()
70
+ const commit: Commit = options.commit ?? (() => Effect.void)
77
71
 
78
72
  return {
79
73
  state,