@typed/navigation 0.13.5 → 0.15.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 +123 -200
  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
@@ -33,10 +33,10 @@ export type NavigationState = {
33
33
  readonly transition: Option.Option<Transition>
34
34
  }
35
35
 
36
- export const NavigationState = Schema.struct({
37
- entries: Schema.array(Destination),
38
- index: Schema.number,
39
- transition: Schema.optionFromNullable(Transition)
36
+ export const NavigationState = Schema.Struct({
37
+ entries: Schema.Array(Destination),
38
+ index: Schema.Number,
39
+ transition: Schema.OptionFromNullishOr(Transition, null)
40
40
  })
41
41
 
42
42
  export const getUrl = (origin: string, urlOrPath: string | URL): URL => {
@@ -72,12 +72,12 @@ export function setupFromModelAndIntent(
72
72
  const transition = RefSubject.map(state, (s) => s.transition)
73
73
 
74
74
  const runBeforeHandlers = (event: BeforeNavigationEvent) =>
75
- Effect.gen(function*(_) {
76
- const handlers = yield* _(beforeHandlers)
75
+ Effect.gen(function*() {
76
+ const handlers = yield* beforeHandlers
77
77
  const matches: Array<Effect.Effect<unknown, RedirectError | CancelNavigation>> = []
78
78
 
79
79
  for (const [handler, ctx] of handlers) {
80
- const exit = yield* _(handler(event), Effect.provide(ctx), Effect.either)
80
+ const exit = yield* handler(event).pipe(Effect.provide(ctx), Effect.either)
81
81
  if (Either.isRight(exit)) {
82
82
  const match = exit.right
83
83
  if (Option.isSome(match)) {
@@ -90,7 +90,7 @@ export function setupFromModelAndIntent(
90
90
 
91
91
  if (matches.length > 0) {
92
92
  for (const match of matches) {
93
- const exit = yield* _(match, Effect.either)
93
+ const exit = yield* Effect.either(match)
94
94
  if (Either.isLeft(exit)) {
95
95
  return Option.some(exit.left)
96
96
  }
@@ -101,19 +101,19 @@ export function setupFromModelAndIntent(
101
101
  })
102
102
 
103
103
  const runHandlers = (event: NavigationEvent) =>
104
- Effect.gen(function*(_) {
105
- const eventHandlers = yield* _(handlers)
104
+ Effect.gen(function*() {
105
+ const eventHandlers = yield* handlers
106
106
  const matches: Array<Effect.Effect<unknown>> = []
107
107
 
108
108
  for (const [handler, ctx] of eventHandlers) {
109
- const match = yield* _(handler(event), Effect.provide(ctx))
109
+ const match = yield* Effect.provide(handler(event), ctx)
110
110
  if (Option.isSome(match)) {
111
111
  matches.push(Effect.provide(match.value, ctx))
112
112
  }
113
113
  }
114
114
 
115
115
  if (matches.length > 0) {
116
- yield* _(Effect.all(matches, { discard: true }))
116
+ yield* Effect.all(matches, { discard: true })
117
117
  }
118
118
  })
119
119
 
@@ -124,14 +124,14 @@ export function setupFromModelAndIntent(
124
124
  NavigationError | HttpClient.error.HttpClientError,
125
125
  Scope.Scope | HttpClient.client.Client.Default
126
126
  > =>
127
- Effect.gen(function*(_) {
128
- const handlers = yield* _(formDataHandlers)
127
+ Effect.gen(function*() {
128
+ const handlers = yield* formDataHandlers
129
129
  const matches: Array<
130
130
  Effect.Effect<Option.Option<HttpClient.response.ClientResponse>, RedirectError | CancelNavigation>
131
131
  > = []
132
132
 
133
133
  for (const [handler, ctx] of handlers) {
134
- const exit = yield* _(handler(event), Effect.provide(ctx), Effect.either)
134
+ const exit = yield* handler(event).pipe(Effect.provide(ctx), Effect.either)
135
135
  if (Either.isRight(exit)) {
136
136
  const match = exit.right
137
137
  if (Option.isSome(match)) {
@@ -144,7 +144,7 @@ export function setupFromModelAndIntent(
144
144
 
145
145
  if (matches.length > 0) {
146
146
  for (const match of matches) {
147
- const exit = yield* _(match, Effect.either)
147
+ const exit = yield* Effect.either(match)
148
148
  if (Either.isLeft(exit)) {
149
149
  return Either.left(exit.left)
150
150
  } else if (Option.isSome(exit.right)) {
@@ -153,9 +153,7 @@ export function setupFromModelAndIntent(
153
153
  }
154
154
  } else {
155
155
  // Only if there are 0 matches, we'll make a request to the server ourselves
156
- const response = yield* _(
157
- makeFormDataRequest(event, Option.getOrElse(event.action, () => event.from.url.href))
158
- )
156
+ const response = yield* makeFormDataRequest(event, Option.getOrElse(event.action, () => event.from.url.href))
159
157
 
160
158
  return Either.right(Option.some(response))
161
159
  }
@@ -170,26 +168,26 @@ export function setupFromModelAndIntent(
170
168
  depth: number,
171
169
  skipCommit: boolean = false
172
170
  ): Effect.Effect<Destination, NavigationError> =>
173
- Effect.gen(function*(_) {
174
- let current = yield* _(get)
175
- current = yield* _(set({ ...current, transition: Option.some(beforeEvent) }))
171
+ Effect.gen(function*() {
172
+ let current = yield* get
173
+ current = yield* set({ ...current, transition: Option.some(beforeEvent) })
176
174
 
177
175
  if (!skipCommit) {
178
- const beforeError = yield* _(runBeforeHandlers(beforeEvent))
176
+ const beforeError = yield* runBeforeHandlers(beforeEvent)
179
177
 
180
178
  if (Option.isSome(beforeError)) {
181
- return yield* _(handleError(beforeError.value, get, set, depth))
179
+ return yield* handleError(beforeError.value, get, set, depth)
182
180
  }
183
181
  }
184
182
 
185
- const to = isDestination(beforeEvent.to) ? beforeEvent.to : yield* _(upgradeProposedDestination(beforeEvent.to))
183
+ const to = isDestination(beforeEvent.to) ? beforeEvent.to : yield* upgradeProposedDestination(beforeEvent.to)
186
184
 
187
185
  if (!skipCommit) {
188
- yield* _(commit(to, beforeEvent))
186
+ yield* commit(to, beforeEvent)
189
187
  }
190
188
 
191
189
  if (newNavigationState) {
192
- const { entries, index } = yield* _(set(newNavigationState()))
190
+ const { entries, index } = yield* set(newNavigationState())
193
191
 
194
192
  return entries[index]
195
193
  } else {
@@ -203,24 +201,24 @@ export function setupFromModelAndIntent(
203
201
  const index = current.index + 1
204
202
  const entries = current.entries.slice(0, index).concat([to])
205
203
 
206
- yield* _(set({ entries, index, transition: Option.none() }))
204
+ yield* set({ entries, index, transition: Option.none() })
207
205
  } else if (beforeEvent.type === "replace") {
208
206
  const index = current.index
209
207
  const before = current.entries.slice(0, index)
210
208
  const after = current.entries.slice(index + 1)
211
209
  const entries = [...before, to, ...after]
212
210
 
213
- yield* _(set({ entries, index, transition: Option.none() }))
211
+ yield* set({ entries, index, transition: Option.none() })
214
212
  } else if (beforeEvent.type === "reload") {
215
- yield* _(set({ ...current, transition: Option.none() }))
213
+ yield* set({ ...current, transition: Option.none() })
216
214
  } else {
217
215
  const { delta } = beforeEvent
218
216
  const nextIndex = current.index + delta
219
217
 
220
- yield* _(set({ ...current, index: nextIndex, transition: Option.none() }))
218
+ yield* set({ ...current, index: nextIndex, transition: Option.none() })
221
219
  }
222
220
 
223
- yield* _(runHandlers(event))
221
+ yield* runHandlers(event)
224
222
  }
225
223
 
226
224
  return to
@@ -232,33 +230,32 @@ export function setupFromModelAndIntent(
232
230
  set: (a: NavigationState) => Effect.Effect<NavigationState>,
233
231
  depth: number
234
232
  ): Effect.Effect<Destination, NavigationError> =>
235
- Effect.gen(function*(_) {
233
+ Effect.gen(function*() {
236
234
  if (depth >= 25) {
237
- return yield* _(Effect.dieMessage(`Redirect loop detected.`))
235
+ return yield* Effect.dieMessage(`Redirect loop detected.`)
238
236
  }
239
237
 
240
- const { entries, index } = yield* _(get)
238
+ const { entries, index } = yield* get
241
239
  const from = entries[index]
242
240
 
243
241
  if (error._tag === "CancelNavigation") {
244
- yield* _(set({ entries, index, transition: Option.none() }))
242
+ yield* set({ entries, index, transition: Option.none() })
245
243
 
246
244
  return from
247
245
  } else {
248
- const event = yield* _(makeRedirectEvent(origin, error, from))
246
+ const event = yield* makeRedirectEvent(origin, error, from)
249
247
 
250
- return yield* _(runNavigationEvent(event, get, set, depth + 1))
248
+ return yield* runNavigationEvent(event, get, set, depth + 1)
251
249
  }
252
250
  }).pipe(GetRandomValues.provide(getRandomValues))
253
251
 
254
252
  const navigate = (pathOrUrl: string | URL, options?: NavigateOptions, skipCommit: boolean = false) =>
255
253
  state.runUpdates(({ get, set }) =>
256
- Effect.gen(function*(_) {
257
- const state = yield* _(get)
254
+ Effect.gen(function*() {
255
+ const state = yield* get
258
256
  const from = state.entries[state.index]
259
257
  const history = options?.history ?? "auto"
260
- const to = yield* _(
261
- makeOrUpdateDestination(state, getUrl(origin, pathOrUrl), options?.state, origin),
258
+ const to = yield* makeOrUpdateDestination(state, getUrl(origin, pathOrUrl), options?.state, origin).pipe(
262
259
  GetRandomValues.provide(getRandomValues)
263
260
  )
264
261
  const type = history === "auto" ? from.key === to.key ? "replace" : "push" : history
@@ -270,21 +267,21 @@ export function setupFromModelAndIntent(
270
267
  info: options?.info
271
268
  }
272
269
 
273
- return yield* _(runNavigationEvent(event, get, set, 0, skipCommit))
270
+ return yield* runNavigationEvent(event, get, set, 0, skipCommit)
274
271
  })
275
272
  )
276
273
 
277
274
  const traverseTo = (key: Destination["key"], options?: { readonly info?: unknown }, skipCommit: boolean = false) =>
278
275
  state.runUpdates(({ get, set }) =>
279
- Effect.gen(function*(_) {
280
- const state = yield* _(get)
276
+ Effect.gen(function*() {
277
+ const state = yield* get
281
278
  const { entries, index } = state
282
279
  const from = entries[index]
283
280
  const nextIndex = entries.findIndex((e) => e.key === key)
284
281
 
285
282
  if (nextIndex === -1) return from
286
283
 
287
- const id = yield* _(makeUuid, GetRandomValues.provide(getRandomValues))
284
+ const id = yield* makeUuid.pipe(GetRandomValues.provide(getRandomValues))
288
285
  const to = { ...entries[nextIndex], id }
289
286
  const delta = nextIndex - index
290
287
  const event: BeforeNavigationEvent = {
@@ -295,32 +292,32 @@ export function setupFromModelAndIntent(
295
292
  info: options?.info
296
293
  }
297
294
 
298
- return yield* _(runNavigationEvent(event, get, set, 0, skipCommit))
295
+ return yield* runNavigationEvent(event, get, set, 0, skipCommit)
299
296
  })
300
297
  )
301
298
 
302
299
  const back = (options?: { readonly info?: unknown }, skipCommit: boolean = false) =>
303
- Effect.gen(function*(_) {
304
- const { entries, index } = yield* _(state)
300
+ Effect.gen(function*() {
301
+ const { entries, index } = yield* state
305
302
  if (index === 0) return entries[index]
306
303
  const { key } = entries[index - 1]
307
304
 
308
- return yield* _(traverseTo(key, options, skipCommit))
305
+ return yield* traverseTo(key, options, skipCommit)
309
306
  })
310
307
 
311
308
  const forward = (options?: { readonly info?: unknown }, skipCommit: boolean = false) =>
312
- Effect.gen(function*(_) {
313
- const { entries, index } = yield* _(state)
309
+ Effect.gen(function*() {
310
+ const { entries, index } = yield* state
314
311
  if (index === entries.length - 1) return entries[index]
315
312
  const { key } = entries[index + 1]
316
313
 
317
- return yield* _(traverseTo(key, options, skipCommit))
314
+ return yield* traverseTo(key, options, skipCommit)
318
315
  })
319
316
 
320
317
  const reload = (options?: { readonly info?: unknown }, skipCommit: boolean = false) =>
321
318
  state.runUpdates(({ get, set }) =>
322
- Effect.gen(function*(_) {
323
- const { entries, index } = yield* _(state)
319
+ Effect.gen(function*() {
320
+ const { entries, index } = yield* state
324
321
  const current = entries[index]
325
322
 
326
323
  const event: BeforeNavigationEvent = {
@@ -331,7 +328,7 @@ export function setupFromModelAndIntent(
331
328
  info: options?.info
332
329
  }
333
330
 
334
- return yield* _(runNavigationEvent(event, get, set, 0, skipCommit))
331
+ return yield* runNavigationEvent(event, get, set, 0, skipCommit)
335
332
  })
336
333
  )
337
334
 
@@ -373,8 +370,8 @@ export function setupFromModelAndIntent(
373
370
 
374
371
  const updateCurrentEntry = (options: { readonly state: unknown }) =>
375
372
  state.runUpdates(({ get, set }) =>
376
- Effect.gen(function*(_) {
377
- const { entries, index } = yield* _(get)
373
+ Effect.gen(function*() {
374
+ const { entries, index } = yield* get
378
375
  const current = entries[index]
379
376
  const event: BeforeNavigationEvent = {
380
377
  type: "replace",
@@ -384,7 +381,7 @@ export function setupFromModelAndIntent(
384
381
  info: null
385
382
  }
386
383
 
387
- return yield* _(runNavigationEvent(event, get, set, 0))
384
+ return yield* runNavigationEvent(event, get, set, 0)
388
385
  })
389
386
  )
390
387
 
@@ -397,8 +394,8 @@ export function setupFromModelAndIntent(
397
394
  Scope.Scope | HttpClient.client.Client.Default
398
395
  > =>
399
396
  state.runUpdates(({ get, set }) =>
400
- Effect.gen(function*(_) {
401
- const { entries, index } = yield* _(get)
397
+ Effect.gen(function*() {
398
+ const { entries, index } = yield* get
402
399
  const from = entries[index]
403
400
  const event: FormDataEvent = {
404
401
  from,
@@ -409,10 +406,10 @@ export function setupFromModelAndIntent(
409
406
  encoding: Option.fromNullable(input?.encoding)
410
407
  }
411
408
 
412
- const either = yield* _(runFormDataHandlers(event))
409
+ const either = yield* runFormDataHandlers(event)
413
410
 
414
411
  if (Either.isLeft(either)) {
415
- yield* _(handleError(either.left, get, set, 0))
412
+ yield* handleError(either.left, get, set, 0)
416
413
  return Option.none<HttpClient.response.ClientResponse>()
417
414
  } else {
418
415
  if (Option.isNone(either.right)) {
@@ -428,7 +425,7 @@ export function setupFromModelAndIntent(
428
425
  // And we have a location header
429
426
  if (Option.isSome(location)) {
430
427
  // Then we navigate to that location
431
- yield* _(navigate(location.value, { history: "replace" }))
428
+ yield* navigate(location.value, { history: "replace" })
432
429
  }
433
430
  }
434
431
 
@@ -483,9 +480,9 @@ export function makeRedirectEvent(
483
480
  redirect: RedirectError,
484
481
  from: Destination
485
482
  ) {
486
- return Effect.gen(function*(_) {
483
+ return Effect.gen(function*() {
487
484
  const url = getUrl(origin, redirect.path)
488
- const to = yield* _(makeDestination(url, redirect.options?.state, origin))
485
+ const to = yield* makeDestination(url, redirect.options?.state, origin)
489
486
  const event: BeforeNavigationEvent = {
490
487
  type: "replace",
491
488
  from,
@@ -504,12 +501,12 @@ export function makeOrUpdateDestination(
504
501
  state: unknown,
505
502
  origin: string
506
503
  ) {
507
- return Effect.gen(function*(_) {
504
+ return Effect.gen(function*() {
508
505
  const current = navigationState.entries[navigationState.index]
509
506
  const isSameOriginAndPath = url.origin === current.url.origin && url.pathname === current.url.pathname
510
507
 
511
508
  if (isSameOriginAndPath) {
512
- const id = yield* _(makeUuid)
509
+ const id = yield* makeUuid
513
510
  const destination: Destination = {
514
511
  id,
515
512
  key: current.key,
@@ -520,13 +517,13 @@ export function makeOrUpdateDestination(
520
517
 
521
518
  return destination
522
519
  } else {
523
- return yield* _(makeDestination(url, state, origin))
520
+ return yield* makeDestination(url, state, origin)
524
521
  }
525
522
  })
526
523
  }
527
524
 
528
525
  export function makeDestination(url: URL, state: unknown, origin: string) {
529
- return Effect.gen(function*(_) {
526
+ return Effect.gen(function*() {
530
527
  if (isPatchedState(state)) {
531
528
  const destination: Destination = {
532
529
  id: state.id,
@@ -539,8 +536,8 @@ export function makeDestination(url: URL, state: unknown, origin: string) {
539
536
  return destination
540
537
  }
541
538
 
542
- const id = yield* _(makeUuid)
543
- const key = yield* _(makeUuid)
539
+ const id = yield* makeUuid
540
+ const key = yield* makeUuid
544
541
 
545
542
  const destination: Destination = {
546
543
  id,
@@ -555,9 +552,9 @@ export function makeDestination(url: URL, state: unknown, origin: string) {
555
552
  }
556
553
 
557
554
  export function upgradeProposedDestination(proposed: ProposedDestination) {
558
- return Effect.gen(function*(_) {
559
- const id = yield* _(makeUuid)
560
- const key = yield* _(makeUuid)
555
+ return Effect.gen(function*() {
556
+ const id = yield* makeUuid
557
+ const key = yield* makeUuid
561
558
 
562
559
  const destination: Destination = {
563
560
  id,
@@ -607,24 +604,18 @@ export function isDestination(proposed: ProposedDestination): proposed is Destin
607
604
  const strictEqual = <A>(a: A, b: A) => a === b
608
605
 
609
606
  export function makeHandlersState() {
610
- return Effect.gen(function*(_) {
611
- const beforeHandlers = yield* _(
612
- RefSubject.fromEffect(
613
- Effect.sync(() => new Set<readonly [BeforeNavigationHandler<any, any>, Context.Context<any>]>()),
614
- { eq: strictEqual }
615
- )
607
+ return Effect.gen(function*() {
608
+ const beforeHandlers = yield* RefSubject.fromEffect(
609
+ Effect.sync(() => new Set<readonly [BeforeNavigationHandler<any, any>, Context.Context<any>]>()),
610
+ { eq: strictEqual }
616
611
  )
617
- const handlers = yield* _(
618
- RefSubject.fromEffect(
619
- Effect.sync(() => new Set<readonly [NavigationHandler<any, any>, Context.Context<any>]>()),
620
- { eq: strictEqual }
621
- )
612
+ const handlers = yield* RefSubject.fromEffect(
613
+ Effect.sync(() => new Set<readonly [NavigationHandler<any, any>, Context.Context<any>]>()),
614
+ { eq: strictEqual }
622
615
  )
623
- const formDataHandlers = yield* _(
624
- RefSubject.fromEffect(
625
- Effect.sync(() => new Set<readonly [FormDataHandler<any, any>, Context.Context<any>]>()),
626
- { eq: strictEqual }
627
- )
616
+ const formDataHandlers = yield* RefSubject.fromEffect(
617
+ Effect.sync(() => new Set<readonly [FormDataHandler<any, any>, Context.Context<any>]>()),
618
+ { eq: strictEqual }
628
619
  )
629
620
 
630
621
  return {