@benjavicente/angular-router-experimental 1.142.11 → 1.142.13
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/fesm2022/tanstack-angular-router-experimental-experimental.mjs +242 -204
- package/dist/fesm2022/tanstack-angular-router-experimental.mjs +1228 -1204
- package/dist/types/tanstack-angular-router-experimental-experimental.d.ts +38 -37
- package/dist/types/tanstack-angular-router-experimental.d.ts +59 -46
- package/package.json +4 -3
- package/src/Match.ts +90 -33
- package/src/Matches.ts +5 -2
- package/src/RouterProvider.ts +3 -0
- package/src/document/build-match-managed-document.ts +1 -1
- package/src/document/install-unified-document-sync.ts +6 -3
- package/src/document/provide-tanstack-body-managed-tags.ts +2 -2
- package/src/document/provide-tanstack-document-title.ts +4 -5
- package/src/document/provide-tanstack-head-managed-tags.ts +2 -2
- package/src/index.ts +6 -2
- package/src/injectCanGoBack.ts +2 -2
- package/src/injectIsShell.ts +7 -0
- package/src/injectLocation.ts +11 -8
- package/src/injectMatch.ts +45 -34
- package/src/injectMatchRoute.ts +4 -5
- package/src/injectMatches.ts +9 -9
- package/src/injectRouterState.ts +15 -10
- package/src/renderer/injectIsCatchingError.ts +20 -8
- package/src/renderer/injectRender.ts +4 -2
- package/src/route.ts +0 -3
- package/src/routerStores.ts +25 -52
- package/src/store/injectSelector.ts +62 -0
- package/src/store/injectStore.ts +33 -0
- package/src/transitioner.ts +12 -25
- package/src/injectStore.ts +0 -87
package/src/transitioner.ts
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
trimPathRight,
|
|
6
6
|
} from '@benjavicente/router-core'
|
|
7
7
|
import { injectRouter } from './injectRouter'
|
|
8
|
-
import { injectStore } from './injectStore'
|
|
8
|
+
import { injectStore } from './store/injectStore'
|
|
9
9
|
import type { AnyRouter } from '@benjavicente/router-core'
|
|
10
10
|
|
|
11
11
|
// Track mount state per router to avoid double-loading
|
|
@@ -46,7 +46,7 @@ export function injectTransitionerSetup() {
|
|
|
46
46
|
|
|
47
47
|
// Track pending state changes
|
|
48
48
|
const hasPendingMatches = injectStore(
|
|
49
|
-
router.stores.
|
|
49
|
+
router.stores.hasPending,
|
|
50
50
|
(value) => value,
|
|
51
51
|
)
|
|
52
52
|
const status = injectStore(router.stores.status, (value) => value)
|
|
@@ -72,7 +72,7 @@ export function injectTransitionerSetup() {
|
|
|
72
72
|
// Implement startTransition similar to React/Solid
|
|
73
73
|
// Angular doesn't have a native startTransition like React 18, so we simulate it
|
|
74
74
|
router.startTransition = (fn: () => void | Promise<void>) => {
|
|
75
|
-
router.stores.isTransitioning.
|
|
75
|
+
router.stores.isTransitioning.set(true)
|
|
76
76
|
|
|
77
77
|
// Helper to end the transition
|
|
78
78
|
const endTransition = () => {
|
|
@@ -84,7 +84,7 @@ export function injectTransitionerSetup() {
|
|
|
84
84
|
{
|
|
85
85
|
read: () => {
|
|
86
86
|
try {
|
|
87
|
-
router.stores.isTransitioning.
|
|
87
|
+
router.stores.isTransitioning.set(false)
|
|
88
88
|
} catch {
|
|
89
89
|
// Ignore errors if component is unmounted
|
|
90
90
|
}
|
|
@@ -133,8 +133,8 @@ export function injectTransitionerSetup() {
|
|
|
133
133
|
isMounted.set(true)
|
|
134
134
|
if (!isAnyPending()) {
|
|
135
135
|
if (status() === 'pending') {
|
|
136
|
-
router.stores.status.
|
|
137
|
-
router.stores.resolvedLocation.
|
|
136
|
+
router.stores.status.set('idle')
|
|
137
|
+
router.stores.resolvedLocation.set(location())
|
|
138
138
|
}
|
|
139
139
|
}
|
|
140
140
|
})
|
|
@@ -176,10 +176,7 @@ export function injectTransitionerSetup() {
|
|
|
176
176
|
if (prevIsLoading() && !isLoading()) {
|
|
177
177
|
router.emit({
|
|
178
178
|
type: 'onLoad',
|
|
179
|
-
...getLocationChangeInfo(
|
|
180
|
-
location(),
|
|
181
|
-
resolvedLocation(),
|
|
182
|
-
),
|
|
179
|
+
...getLocationChangeInfo(location(), resolvedLocation()),
|
|
183
180
|
})
|
|
184
181
|
}
|
|
185
182
|
} catch {
|
|
@@ -194,10 +191,7 @@ export function injectTransitionerSetup() {
|
|
|
194
191
|
if (prevIsPagePending() && !isPagePending()) {
|
|
195
192
|
router.emit({
|
|
196
193
|
type: 'onBeforeRouteMount',
|
|
197
|
-
...getLocationChangeInfo(
|
|
198
|
-
location(),
|
|
199
|
-
resolvedLocation(),
|
|
200
|
-
),
|
|
194
|
+
...getLocationChangeInfo(location(), resolvedLocation()),
|
|
201
195
|
})
|
|
202
196
|
}
|
|
203
197
|
} catch {
|
|
@@ -209,21 +203,14 @@ export function injectTransitionerSetup() {
|
|
|
209
203
|
Angular.effect(() => {
|
|
210
204
|
if (!isMounted()) return
|
|
211
205
|
try {
|
|
212
|
-
if (
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
status() === 'pending'
|
|
216
|
-
) {
|
|
217
|
-
router.stores.status.setState(() => 'idle')
|
|
218
|
-
router.stores.resolvedLocation.setState(() => location())
|
|
206
|
+
if (prevIsAnyPending() && !isAnyPending() && status() === 'pending') {
|
|
207
|
+
router.stores.status.set('idle')
|
|
208
|
+
router.stores.resolvedLocation.set(location())
|
|
219
209
|
}
|
|
220
210
|
|
|
221
211
|
// The router was pending and now it's not
|
|
222
212
|
if (prevIsAnyPending() && !isAnyPending()) {
|
|
223
|
-
const changeInfo = getLocationChangeInfo(
|
|
224
|
-
location(),
|
|
225
|
-
resolvedLocation(),
|
|
226
|
-
)
|
|
213
|
+
const changeInfo = getLocationChangeInfo(location(), resolvedLocation())
|
|
227
214
|
router.emit({
|
|
228
215
|
type: 'onResolved',
|
|
229
216
|
...changeInfo,
|
package/src/injectStore.ts
DELETED
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
assertInInjectionContext,
|
|
3
|
-
effect,
|
|
4
|
-
linkedSignal,
|
|
5
|
-
} from '@angular/core'
|
|
6
|
-
import type { CreateSignalOptions, Signal } from '@angular/core'
|
|
7
|
-
|
|
8
|
-
type ReadableStore<TState> = {
|
|
9
|
-
state: TState
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export function injectStore<TState, TSelected = NoInfer<TState>>(
|
|
13
|
-
storeOrStoreSignal:
|
|
14
|
-
| ReadableStore<TState>
|
|
15
|
-
| (() => ReadableStore<TState>),
|
|
16
|
-
selector: (state: NoInfer<TState>) => TSelected = (d) =>
|
|
17
|
-
d as unknown as TSelected,
|
|
18
|
-
options: CreateSignalOptions<TSelected> = {
|
|
19
|
-
equal: shallow,
|
|
20
|
-
},
|
|
21
|
-
): Signal<TSelected> {
|
|
22
|
-
assertInInjectionContext(injectStore)
|
|
23
|
-
|
|
24
|
-
const storeSignal =
|
|
25
|
-
typeof storeOrStoreSignal === 'function'
|
|
26
|
-
? storeOrStoreSignal
|
|
27
|
-
: () => storeOrStoreSignal
|
|
28
|
-
|
|
29
|
-
const slice = linkedSignal(() => selector(storeSignal().state), options)
|
|
30
|
-
|
|
31
|
-
effect(() => {
|
|
32
|
-
slice()
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
return slice.asReadonly()
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function shallow<T>(objA: T, objB: T) {
|
|
39
|
-
if (Object.is(objA, objB)) {
|
|
40
|
-
return true
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
if (
|
|
44
|
-
typeof objA !== 'object' ||
|
|
45
|
-
objA === null ||
|
|
46
|
-
typeof objB !== 'object' ||
|
|
47
|
-
objB === null
|
|
48
|
-
) {
|
|
49
|
-
return false
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
if (objA instanceof Map && objB instanceof Map) {
|
|
53
|
-
if (objA.size !== objB.size) return false
|
|
54
|
-
for (const [k, v] of objA) {
|
|
55
|
-
if (!objB.has(k) || !Object.is(v, objB.get(k))) return false
|
|
56
|
-
}
|
|
57
|
-
return true
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if (objA instanceof Set && objB instanceof Set) {
|
|
61
|
-
if (objA.size !== objB.size) return false
|
|
62
|
-
for (const v of objA) {
|
|
63
|
-
if (!objB.has(v)) return false
|
|
64
|
-
}
|
|
65
|
-
return true
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
if (objA instanceof Date && objB instanceof Date) {
|
|
69
|
-
return objA.getTime() === objB.getTime()
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
const keysA = Object.keys(objA)
|
|
73
|
-
if (keysA.length !== Object.keys(objB).length) {
|
|
74
|
-
return false
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
for (const key of keysA) {
|
|
78
|
-
if (
|
|
79
|
-
!Object.prototype.hasOwnProperty.call(objB, key) ||
|
|
80
|
-
!Object.is(objA[key as keyof T], objB[key as keyof T])
|
|
81
|
-
) {
|
|
82
|
-
return false
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
return true
|
|
87
|
-
}
|