@typed/navigation 0.3.5 → 0.3.6
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/DOM.d.ts.map +1 -1
- package/dist/DOM.js +11 -13
- package/dist/DOM.js.map +1 -1
- package/dist/cjs/DOM.d.ts.map +1 -1
- package/dist/cjs/DOM.js +10 -12
- package/dist/cjs/DOM.js.map +1 -1
- package/dist/cjs/dom-intent.d.ts +8 -9
- package/dist/cjs/dom-intent.d.ts.map +1 -1
- package/dist/cjs/dom-intent.js +17 -18
- package/dist/cjs/dom-intent.js.map +1 -1
- package/dist/cjs/history.d.ts +1 -1
- package/dist/cjs/history.d.ts.map +1 -1
- package/dist/cjs/history.js +36 -23
- package/dist/cjs/history.js.map +1 -1
- package/dist/cjs/memory-intent.d.ts +6 -7
- package/dist/cjs/memory-intent.d.ts.map +1 -1
- package/dist/cjs/memory-intent.js +8 -1
- package/dist/cjs/memory-intent.js.map +1 -1
- package/dist/cjs/shared-intent.d.ts +2 -3
- package/dist/cjs/shared-intent.d.ts.map +1 -1
- package/dist/cjs/shared-intent.js.map +1 -1
- package/dist/cjs/storage.js +1 -1
- package/dist/cjs/storage.js.map +1 -1
- package/dist/dom-intent.d.ts +8 -9
- package/dist/dom-intent.d.ts.map +1 -1
- package/dist/dom-intent.js +18 -19
- package/dist/dom-intent.js.map +1 -1
- package/dist/history.d.ts +1 -1
- package/dist/history.d.ts.map +1 -1
- package/dist/history.js +36 -23
- package/dist/history.js.map +1 -1
- package/dist/memory-intent.d.ts +6 -7
- package/dist/memory-intent.d.ts.map +1 -1
- package/dist/memory-intent.js +8 -1
- package/dist/memory-intent.js.map +1 -1
- package/dist/shared-intent.d.ts +2 -3
- package/dist/shared-intent.d.ts.map +1 -1
- package/dist/shared-intent.js.map +1 -1
- package/dist/storage.js +1 -1
- package/dist/storage.js.map +1 -1
- package/dist/tsconfig.cjs.build.tsbuildinfo +1 -1
- package/package.json +6 -6
- package/project.json +3 -0
- package/src/DOM.test.ts +1 -4
- package/src/DOM.ts +18 -21
- package/src/dom-intent.ts +29 -37
- package/src/history.ts +43 -23
- package/src/memory-intent.ts +9 -6
- package/src/shared-intent.ts +2 -5
- package/src/storage.ts +1 -1
- package/tsconfig.build.tsbuildinfo +1 -1
- package/src/constant.ts +0 -5
- /package/{vite.config.js → vite.config.mjs} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@typed/navigation",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.6",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -19,11 +19,11 @@
|
|
|
19
19
|
}
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@effect/data": "^0.17.
|
|
22
|
+
"@effect/data": "^0.17.1",
|
|
23
23
|
"@effect/io": "^0.36.1",
|
|
24
|
-
"@typed/context": "0.16.
|
|
25
|
-
"@typed/dom": "8.16.
|
|
26
|
-
"@typed/fx": "1.15.
|
|
24
|
+
"@typed/context": "0.16.6",
|
|
25
|
+
"@typed/dom": "8.16.6",
|
|
26
|
+
"@typed/fx": "1.15.4",
|
|
27
27
|
"@typed/path": "0.5.2",
|
|
28
28
|
"happy-dom": "^10.5.2"
|
|
29
29
|
},
|
|
@@ -35,5 +35,5 @@
|
|
|
35
35
|
"@types/node": "^20.4.5",
|
|
36
36
|
"vitest": "0.33.0"
|
|
37
37
|
},
|
|
38
|
-
"gitHead": "
|
|
38
|
+
"gitHead": "ea7f8dd7aee2a9d47f1feb7c16524178a47f30df"
|
|
39
39
|
}
|
package/project.json
CHANGED
package/src/DOM.test.ts
CHANGED
|
@@ -19,7 +19,6 @@ import {
|
|
|
19
19
|
redirect,
|
|
20
20
|
} from './Navigation.js'
|
|
21
21
|
import { makeServerWindow } from './_makeServerWindow.js'
|
|
22
|
-
import { encodeDestination } from './json.js'
|
|
23
22
|
import { getStoredEvents } from './storage.js'
|
|
24
23
|
|
|
25
24
|
const serviceNavigation = (url: string, options: DomNavigationOptions = {}) => {
|
|
@@ -687,9 +686,7 @@ function popstate(destination: Destination) {
|
|
|
687
686
|
const globalThis = yield* $(GlobalThis)
|
|
688
687
|
const state = {
|
|
689
688
|
// Not a full event, but enough to get the test to pass
|
|
690
|
-
|
|
691
|
-
destination: encodeDestination(destination),
|
|
692
|
-
},
|
|
689
|
+
key: destination.key,
|
|
693
690
|
state: destination.state,
|
|
694
691
|
}
|
|
695
692
|
const event = new globalThis.PopStateEvent('popstate')
|
package/src/DOM.ts
CHANGED
|
@@ -10,7 +10,6 @@ import * as Fx from '@typed/fx'
|
|
|
10
10
|
import { Destination, DestinationKey, Navigation, NavigationError } from './Navigation.js'
|
|
11
11
|
import { makeIntent } from './dom-intent.js'
|
|
12
12
|
import { onHistoryEvent, patchHistory } from './history.js'
|
|
13
|
-
import { NavigationEventJson } from './json.js'
|
|
14
13
|
import { makeModel } from './model.js'
|
|
15
14
|
import { getInitialValues } from './storage.js'
|
|
16
15
|
|
|
@@ -33,15 +32,18 @@ export const dom = (
|
|
|
33
32
|
Effect.gen(function* ($) {
|
|
34
33
|
// Get resources
|
|
35
34
|
const context = yield* $(Effect.context<NavigationServices>())
|
|
36
|
-
const history = Context.get(context, History)
|
|
37
35
|
const document = Context.get(context, Document)
|
|
38
36
|
const base = document.querySelector('base')
|
|
39
37
|
const baseHref = base ? getBasePathFromHref(base.href) : '/'
|
|
40
38
|
|
|
39
|
+
// Patch History API to enable sending events
|
|
40
|
+
const [history, historyEvents] = yield* $(patchHistory)
|
|
41
|
+
|
|
41
42
|
// Create model and intent
|
|
42
43
|
const [initialEntries, initialIndex] = yield* $(getInitialValues(baseHref, options))
|
|
44
|
+
|
|
43
45
|
const model = yield* $(makeModel(initialEntries, initialIndex))
|
|
44
|
-
const intent = makeIntent(model, baseHref, options)
|
|
46
|
+
const intent = makeIntent(model, baseHref, history, options)
|
|
45
47
|
|
|
46
48
|
// Used to ensure ordering of navigation events
|
|
47
49
|
const lock = Effect.unsafeMakeSemaphore(1).withPermits(1)
|
|
@@ -108,38 +110,33 @@ export const dom = (
|
|
|
108
110
|
reload: provideLocked(catchNavigationError(intent.reload)),
|
|
109
111
|
}
|
|
110
112
|
|
|
111
|
-
// Patch History API to enable sending events
|
|
112
|
-
const historyEvents = yield* $(patchHistory)
|
|
113
|
-
|
|
114
113
|
// Listen to various events and update our model
|
|
115
114
|
yield* $(
|
|
116
115
|
Fx.mergeAll(
|
|
117
116
|
// Listen to history events and keep track of entries
|
|
118
117
|
pipe(
|
|
119
118
|
historyEvents,
|
|
120
|
-
Fx.
|
|
119
|
+
Fx.mapEffect((event) => lock(onHistoryEvent(event, intent))),
|
|
121
120
|
),
|
|
122
121
|
// Listen to hash changes and push them to the history
|
|
123
122
|
pipe(
|
|
124
123
|
addWindowListener('hashchange', { capture: true }),
|
|
125
|
-
Fx.
|
|
124
|
+
Fx.mapEffect((ev) => lock(intent.push(ev.newURL, { state: history.state }, true))),
|
|
126
125
|
),
|
|
127
126
|
// Listen to popstate events and go to the correct entry
|
|
128
127
|
pipe(
|
|
129
128
|
addWindowListener('popstate'),
|
|
130
|
-
Fx.
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
Fx.compact,
|
|
142
|
-
Fx.flattenEffect,
|
|
129
|
+
Fx.mapEffect(
|
|
130
|
+
Effect.unifiedFn((ev) => {
|
|
131
|
+
// TODO: Should we throw some kind of error here?
|
|
132
|
+
// This should never happen if you are solely using the Navigation Service
|
|
133
|
+
if (!ev.state || !ev.state.key) {
|
|
134
|
+
return lock(intent.push(location.href, { state: history.state }, true))
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return lock(intent.goTo(ev.state.key))
|
|
138
|
+
}),
|
|
139
|
+
),
|
|
143
140
|
),
|
|
144
141
|
),
|
|
145
142
|
Fx.drain,
|
package/src/dom-intent.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Option } from '@effect/data/Option'
|
|
2
|
-
import * as Cause from '@effect/io/Cause'
|
|
3
2
|
import * as Effect from '@effect/io/Effect'
|
|
4
|
-
import {
|
|
3
|
+
import { Location } from '@typed/dom'
|
|
5
4
|
|
|
6
5
|
import type { DomNavigationOptions } from './DOM.js'
|
|
7
6
|
import {
|
|
@@ -11,8 +10,6 @@ import {
|
|
|
11
10
|
NavigationEvent,
|
|
12
11
|
NavigationType,
|
|
13
12
|
} from './Navigation.js'
|
|
14
|
-
import { ServiceId } from './constant.js'
|
|
15
|
-
import { encodeEvent } from './json.js'
|
|
16
13
|
import { Model } from './model.js'
|
|
17
14
|
import {
|
|
18
15
|
Notify,
|
|
@@ -50,11 +47,7 @@ export type DomIntent = {
|
|
|
50
47
|
|
|
51
48
|
readonly goTo: (
|
|
52
49
|
key: string,
|
|
53
|
-
) => Effect.Effect<
|
|
54
|
-
Storage | History,
|
|
55
|
-
Cause.NoSuchElementException | NavigationError,
|
|
56
|
-
Option<Destination>
|
|
57
|
-
>
|
|
50
|
+
) => Effect.Effect<Storage | History, NavigationError, Option<Destination>>
|
|
58
51
|
|
|
59
52
|
readonly reload: ReturnType<typeof makeReload>
|
|
60
53
|
|
|
@@ -66,15 +59,16 @@ export type DomIntent = {
|
|
|
66
59
|
export const makeIntent = (
|
|
67
60
|
model: Model,
|
|
68
61
|
base: string,
|
|
62
|
+
history: History,
|
|
69
63
|
options: DomNavigationOptions,
|
|
70
64
|
): DomIntent => {
|
|
71
65
|
const maxEntries = Math.abs(options.maxEntries ?? DEFAULT_MAX_ENTRIES)
|
|
72
66
|
const notify = makeNotify(model)
|
|
73
67
|
const notifyEnd = makeNotifyEnd(model)
|
|
74
68
|
const save = makeSave(model)
|
|
75
|
-
const go = makeGo(model, notify, notifyEnd, save)
|
|
76
|
-
const replace = makeReplace(model, notify, notifyEnd, save, base)
|
|
77
|
-
const push = makePush(model, notify, notifyEnd, save, base, maxEntries)
|
|
69
|
+
const go = makeGo(model, notify, notifyEnd, save, history)
|
|
70
|
+
const replace = makeReplace(model, notify, notifyEnd, save, history, base)
|
|
71
|
+
const push = makePush(model, notify, notifyEnd, save, base, history, maxEntries)
|
|
78
72
|
|
|
79
73
|
return {
|
|
80
74
|
back: (skipHistory: boolean) => go(-1, skipHistory),
|
|
@@ -96,7 +90,7 @@ export type Intent = ReturnType<typeof makeIntent>
|
|
|
96
90
|
|
|
97
91
|
export const makeSave =
|
|
98
92
|
(model: Model) =>
|
|
99
|
-
(event: NavigationEvent): Effect.Effect<Storage,
|
|
93
|
+
(event: NavigationEvent): Effect.Effect<Storage, never, void> =>
|
|
100
94
|
Effect.gen(function* ($) {
|
|
101
95
|
const events = yield* $(model.events)
|
|
102
96
|
const index = yield* $(model.index)
|
|
@@ -132,7 +126,14 @@ export const makeReload = (model: Model, notify: Notify, save: Save<Storage>) =>
|
|
|
132
126
|
})
|
|
133
127
|
|
|
134
128
|
export const makeReplace =
|
|
135
|
-
(
|
|
129
|
+
(
|
|
130
|
+
model: Model,
|
|
131
|
+
notify: Notify,
|
|
132
|
+
notifyEnd: NotifyEnd,
|
|
133
|
+
save: Save<Storage>,
|
|
134
|
+
history: History,
|
|
135
|
+
base: string,
|
|
136
|
+
) =>
|
|
136
137
|
(url: string, options: NavigateOptions = {}, skipHistory = false) =>
|
|
137
138
|
Effect.gen(function* ($) {
|
|
138
139
|
const location = yield* $(Location)
|
|
@@ -151,14 +152,7 @@ export const makeReplace =
|
|
|
151
152
|
yield* $(notify(event))
|
|
152
153
|
|
|
153
154
|
if (!skipHistory) {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
history.replaceState.call(
|
|
157
|
-
ServiceId,
|
|
158
|
-
{ state: options.state, event: encodeEvent(event) },
|
|
159
|
-
'',
|
|
160
|
-
url,
|
|
161
|
-
)
|
|
155
|
+
history.replaceState({ key: destination.key, state: options.state }, '', url)
|
|
162
156
|
}
|
|
163
157
|
|
|
164
158
|
const currentIndex = yield* $(model.index)
|
|
@@ -184,15 +178,22 @@ export const makePush =
|
|
|
184
178
|
notifyEnd: NotifyEnd,
|
|
185
179
|
save: Save<Storage>,
|
|
186
180
|
base: string,
|
|
181
|
+
history: History,
|
|
187
182
|
maxEntries: number,
|
|
188
183
|
) =>
|
|
189
184
|
(url: string, options: NavigateOptions = {}, skipHistory = false) =>
|
|
190
185
|
Effect.gen(function* ($) {
|
|
191
186
|
const location = yield* $(Location)
|
|
192
187
|
const entry = yield* $(model.currentEntry.get)
|
|
188
|
+
const destinationUrl = getUrl(url, base, location.origin)
|
|
189
|
+
|
|
190
|
+
if (entry.url.href === destinationUrl.href) {
|
|
191
|
+
return entry
|
|
192
|
+
}
|
|
193
|
+
|
|
193
194
|
const destination: Destination = {
|
|
194
195
|
key: yield* $(createKey),
|
|
195
|
-
url:
|
|
196
|
+
url: destinationUrl,
|
|
196
197
|
state: options.state,
|
|
197
198
|
}
|
|
198
199
|
const event: NavigationEvent = {
|
|
@@ -205,14 +206,7 @@ export const makePush =
|
|
|
205
206
|
yield* $(notify(event))
|
|
206
207
|
|
|
207
208
|
if (!skipHistory) {
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
history.pushState.call(
|
|
211
|
-
ServiceId,
|
|
212
|
-
{ state: options.state, event: encodeEvent(event) },
|
|
213
|
-
'',
|
|
214
|
-
url,
|
|
215
|
-
)
|
|
209
|
+
history.pushState({ key: destination.key, state: options.state }, '', url)
|
|
216
210
|
}
|
|
217
211
|
|
|
218
212
|
const currentIndex = yield* $(model.index)
|
|
@@ -228,7 +222,7 @@ export const makePush =
|
|
|
228
222
|
)
|
|
229
223
|
|
|
230
224
|
// Update the index to the new destination
|
|
231
|
-
yield* $(model.index.update((i) => i + 1))
|
|
225
|
+
yield* $(model.index.update((i) => Math.min(i + 1, maxEntries)))
|
|
232
226
|
|
|
233
227
|
yield* $(save(event))
|
|
234
228
|
yield* $(notifyEnd(event))
|
|
@@ -237,7 +231,7 @@ export const makePush =
|
|
|
237
231
|
})
|
|
238
232
|
|
|
239
233
|
export const makeGo =
|
|
240
|
-
(model: Model, notify: Notify, notifyEnd: NotifyEnd, save: Save<Storage
|
|
234
|
+
(model: Model, notify: Notify, notifyEnd: NotifyEnd, save: Save<Storage>, history: History) =>
|
|
241
235
|
(delta: number, skipHistory = false) =>
|
|
242
236
|
Effect.gen(function* ($) {
|
|
243
237
|
const currentEntries = yield* $(model.events)
|
|
@@ -250,7 +244,7 @@ export const makeGo =
|
|
|
250
244
|
const nextIndex =
|
|
251
245
|
delta > 0
|
|
252
246
|
? Math.min(currentIndex + delta, totalEntries - 1)
|
|
253
|
-
: Math.max(currentIndex + delta, 0)
|
|
247
|
+
: Math.min(Math.max(currentIndex + delta, 0))
|
|
254
248
|
const nextEntry = currentEntries[nextIndex]
|
|
255
249
|
|
|
256
250
|
yield* $(
|
|
@@ -261,9 +255,7 @@ export const makeGo =
|
|
|
261
255
|
)
|
|
262
256
|
|
|
263
257
|
if (!skipHistory) {
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
history.go.call(ServiceId, delta)
|
|
258
|
+
history.go(delta)
|
|
267
259
|
}
|
|
268
260
|
|
|
269
261
|
yield* $(model.index.set(nextIndex))
|
package/src/history.ts
CHANGED
|
@@ -7,7 +7,6 @@ import { History } from '@typed/dom'
|
|
|
7
7
|
import * as Fx from '@typed/fx'
|
|
8
8
|
|
|
9
9
|
import { Destination, NavigationError } from './Navigation.js'
|
|
10
|
-
import { ServiceId } from './constant.js'
|
|
11
10
|
import { DomIntent } from './dom-intent.js'
|
|
12
11
|
|
|
13
12
|
export type HistoryEvent = PushStateEvent | ReplaceStateEvent | GoEvent | BackEvent | ForwardEvent
|
|
@@ -40,9 +39,33 @@ export interface ForwardEvent {
|
|
|
40
39
|
export const patchHistory: Effect.Effect<
|
|
41
40
|
History | Scope.Scope,
|
|
42
41
|
never,
|
|
43
|
-
Fx.Subject<never, HistoryEvent>
|
|
42
|
+
readonly [History, Fx.Subject<never, HistoryEvent>]
|
|
44
43
|
> = Effect.gen(function* ($) {
|
|
45
44
|
const history = yield* $(History)
|
|
45
|
+
|
|
46
|
+
const stateDescriptor = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(history), 'state')
|
|
47
|
+
|
|
48
|
+
// Create a clone that always operates on the original history
|
|
49
|
+
const clone: History = {
|
|
50
|
+
get length() {
|
|
51
|
+
return history.length
|
|
52
|
+
},
|
|
53
|
+
get scrollRestoration() {
|
|
54
|
+
return history.scrollRestoration
|
|
55
|
+
},
|
|
56
|
+
set scrollRestoration(value) {
|
|
57
|
+
history.scrollRestoration = value
|
|
58
|
+
},
|
|
59
|
+
get state() {
|
|
60
|
+
return stateDescriptor?.get?.call(history)
|
|
61
|
+
},
|
|
62
|
+
back: history.back.bind(history),
|
|
63
|
+
forward: history.forward.bind(history),
|
|
64
|
+
go: history.go.bind(history),
|
|
65
|
+
pushState: history.pushState.bind(history),
|
|
66
|
+
replaceState: history.replaceState.bind(history),
|
|
67
|
+
}
|
|
68
|
+
|
|
46
69
|
const scope = yield* $(Effect.scope)
|
|
47
70
|
const historyEvents = Fx.makeSubject<never, HistoryEvent>()
|
|
48
71
|
const runtime = yield* $(Effect.runtime<never>())
|
|
@@ -54,7 +77,7 @@ export const patchHistory: Effect.Effect<
|
|
|
54
77
|
// unpatch history upon finalization
|
|
55
78
|
yield* $(Effect.addFinalizer(() => Effect.sync(cleanup)))
|
|
56
79
|
|
|
57
|
-
return historyEvents
|
|
80
|
+
return [clone, historyEvents]
|
|
58
81
|
})
|
|
59
82
|
|
|
60
83
|
function patchHistory_(history: History, sendEvent: (event: HistoryEvent) => void) {
|
|
@@ -64,45 +87,40 @@ function patchHistory_(history: History, sendEvent: (event: HistoryEvent) => voi
|
|
|
64
87
|
const back = history.back
|
|
65
88
|
const forward = history.forward
|
|
66
89
|
|
|
67
|
-
history.pushState = function (state,
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if (url && this !== ServiceId) sendEvent({ _tag: 'PushState', state, url: url.toString() })
|
|
90
|
+
history.pushState = function (state, _, url) {
|
|
91
|
+
if (url) sendEvent({ _tag: 'PushState', state, url: url.toString() })
|
|
71
92
|
}
|
|
72
93
|
|
|
73
|
-
history.replaceState = function (state,
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
if (url && this !== ServiceId) sendEvent({ _tag: 'ReplaceState', state, url: url.toString() })
|
|
94
|
+
history.replaceState = function (state, _, url) {
|
|
95
|
+
if (url) sendEvent({ _tag: 'ReplaceState', state, url: url.toString() })
|
|
77
96
|
}
|
|
78
97
|
|
|
79
98
|
history.go = function (delta) {
|
|
80
99
|
if (!delta) return
|
|
81
100
|
|
|
82
|
-
|
|
83
|
-
if (this !== ServiceId) sendEvent({ _tag: 'Go', delta })
|
|
101
|
+
sendEvent({ _tag: 'Go', delta })
|
|
84
102
|
}
|
|
85
103
|
|
|
86
104
|
history.back = function () {
|
|
87
|
-
|
|
88
|
-
if (this !== ServiceId) sendEvent({ _tag: 'Back' })
|
|
105
|
+
sendEvent({ _tag: 'Back' })
|
|
89
106
|
}
|
|
90
107
|
|
|
91
108
|
history.forward = function () {
|
|
92
|
-
|
|
93
|
-
if (this !== ServiceId) sendEvent({ _tag: 'Forward' })
|
|
109
|
+
sendEvent({ _tag: 'Forward' })
|
|
94
110
|
}
|
|
95
111
|
|
|
96
112
|
const stateDescriptor = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(history), 'state')
|
|
113
|
+
|
|
114
|
+
// Override state to always return the original state
|
|
97
115
|
Object.defineProperty(history, 'state', {
|
|
98
|
-
...stateDescriptor,
|
|
99
116
|
get() {
|
|
100
|
-
|
|
117
|
+
const state = stateDescriptor?.get?.call(history)
|
|
118
|
+
|
|
119
|
+
if (state && state.key && state.state) return state.state
|
|
120
|
+
|
|
121
|
+
return state
|
|
101
122
|
},
|
|
102
123
|
})
|
|
103
|
-
Object.defineProperty(history, 'originalState', {
|
|
104
|
-
...stateDescriptor,
|
|
105
|
-
})
|
|
106
124
|
|
|
107
125
|
// Reset history to original state
|
|
108
126
|
return () => {
|
|
@@ -112,7 +130,9 @@ function patchHistory_(history: History, sendEvent: (event: HistoryEvent) => voi
|
|
|
112
130
|
history.back = back
|
|
113
131
|
history.forward = forward
|
|
114
132
|
|
|
115
|
-
if (stateDescriptor)
|
|
133
|
+
if (stateDescriptor) {
|
|
134
|
+
Object.defineProperty(history, 'state', stateDescriptor)
|
|
135
|
+
}
|
|
116
136
|
}
|
|
117
137
|
}
|
|
118
138
|
|
package/src/memory-intent.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Option } from '@effect/data/Option'
|
|
2
|
-
import * as Cause from '@effect/io/Cause'
|
|
3
2
|
import * as Effect from '@effect/io/Effect'
|
|
4
3
|
|
|
5
4
|
import type { MemoryNavigationOptions } from './Memory.js'
|
|
@@ -42,9 +41,7 @@ export type MemoryIntent = {
|
|
|
42
41
|
|
|
43
42
|
readonly go: ReturnType<typeof makeGo>
|
|
44
43
|
|
|
45
|
-
readonly goTo: (
|
|
46
|
-
key: string,
|
|
47
|
-
) => Effect.Effect<never, Cause.NoSuchElementException | NavigationError, Option<Destination>>
|
|
44
|
+
readonly goTo: (key: string) => Effect.Effect<never, NavigationError, Option<Destination>>
|
|
48
45
|
|
|
49
46
|
readonly reload: ReturnType<typeof makeReload>
|
|
50
47
|
|
|
@@ -83,7 +80,7 @@ export type Intent = ReturnType<typeof makeIntent>
|
|
|
83
80
|
|
|
84
81
|
export const makeSave: (
|
|
85
82
|
model: Model,
|
|
86
|
-
) => (event: NavigationEvent) => Effect.Effect<never,
|
|
83
|
+
) => (event: NavigationEvent) => Effect.Effect<never, never, void> =
|
|
87
84
|
(model: Model) => (event: NavigationEvent) =>
|
|
88
85
|
Effect.gen(function* ($) {
|
|
89
86
|
const events = yield* $(model.events)
|
|
@@ -209,7 +206,7 @@ export const makeGo = (model: Model, notify: Notify, save: Save<never>) => (delt
|
|
|
209
206
|
yield* $(
|
|
210
207
|
notify({
|
|
211
208
|
...nextEntry,
|
|
212
|
-
navigationType:
|
|
209
|
+
navigationType: getNavigationType(currentIndex, nextIndex),
|
|
213
210
|
}),
|
|
214
211
|
)
|
|
215
212
|
|
|
@@ -219,3 +216,9 @@ export const makeGo = (model: Model, notify: Notify, save: Save<never>) => (delt
|
|
|
219
216
|
|
|
220
217
|
return nextEntry.destination
|
|
221
218
|
})
|
|
219
|
+
|
|
220
|
+
function getNavigationType(currentIndex: number, nextIndex: number): NavigationType {
|
|
221
|
+
if (nextIndex > currentIndex) return NavigationType.Forward
|
|
222
|
+
if (nextIndex < currentIndex) return NavigationType.Back
|
|
223
|
+
return NavigationType.Reload
|
|
224
|
+
}
|
package/src/shared-intent.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import * as Option from '@effect/data/Option'
|
|
2
|
-
import * as Cause from '@effect/io/Cause'
|
|
3
2
|
import * as Effect from '@effect/io/Effect'
|
|
4
3
|
import * as Scope from '@effect/io/Scope'
|
|
5
4
|
|
|
@@ -9,9 +8,7 @@ import { Model } from './model.js'
|
|
|
9
8
|
export type Notify = (event: NavigationEvent) => Effect.Effect<never, NavigationError, void>
|
|
10
9
|
export type NotifyEnd = (event: NavigationEvent) => Effect.Effect<never, never, void>
|
|
11
10
|
|
|
12
|
-
export type Save<R> = (
|
|
13
|
-
event: NavigationEvent,
|
|
14
|
-
) => Effect.Effect<R, Cause.NoSuchElementException, void>
|
|
11
|
+
export type Save<R> = (event: NavigationEvent) => Effect.Effect<R, never, void>
|
|
15
12
|
|
|
16
13
|
// Anytime there are changes to the model, we need to notify all event handlers
|
|
17
14
|
export const makeNotify = (model: Model) => (event: NavigationEvent) =>
|
|
@@ -102,7 +99,7 @@ export const makeGoTo =
|
|
|
102
99
|
model: Model,
|
|
103
100
|
go: (delta: number, skipHistory?: boolean) => Effect.Effect<R, E, Destination>,
|
|
104
101
|
) =>
|
|
105
|
-
(key: string): Effect.Effect<R,
|
|
102
|
+
(key: string): Effect.Effect<R, E, Option.Option<Destination>> =>
|
|
106
103
|
Effect.gen(function* ($) {
|
|
107
104
|
const entries = yield* $(model.entries)
|
|
108
105
|
const currentIndex = yield* $(model.index)
|
package/src/storage.ts
CHANGED
|
@@ -69,7 +69,7 @@ export const getInitialValues = (
|
|
|
69
69
|
const initial: Destination = {
|
|
70
70
|
key: options.initialKey ?? (yield* $(createKey)),
|
|
71
71
|
url: initialUrl,
|
|
72
|
-
state: history.state
|
|
72
|
+
state: history.state,
|
|
73
73
|
}
|
|
74
74
|
const initialEvent: NavigationEvent = {
|
|
75
75
|
destination: initial,
|