@tanstack/router-core 1.171.15 → 1.171.16-pre.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/dist/cjs/Matches.cjs.map +1 -1
- package/dist/cjs/Matches.d.cts +3 -12
- package/dist/cjs/await-signal.cjs +21 -0
- package/dist/cjs/await-signal.cjs.map +1 -0
- package/dist/cjs/await-signal.d.cts +1 -0
- package/dist/cjs/index.cjs +3 -1
- package/dist/cjs/index.d.cts +3 -2
- package/dist/cjs/isServer/client.cjs +2 -0
- package/dist/cjs/isServer/client.cjs.map +1 -1
- package/dist/cjs/isServer/client.d.cts +1 -0
- package/dist/cjs/isServer/development.cjs +2 -0
- package/dist/cjs/isServer/development.cjs.map +1 -1
- package/dist/cjs/isServer/development.d.cts +1 -0
- package/dist/cjs/isServer/server.cjs +2 -0
- package/dist/cjs/isServer/server.cjs.map +1 -1
- package/dist/cjs/isServer/server.d.cts +1 -0
- package/dist/cjs/load-client.cjs +1470 -0
- package/dist/cjs/load-client.cjs.map +1 -0
- package/dist/cjs/load-client.d.cts +147 -0
- package/dist/cjs/load-server.cjs +565 -0
- package/dist/cjs/load-server.cjs.map +1 -0
- package/dist/cjs/load-server.d.cts +16 -0
- package/dist/cjs/redirect.cjs.map +1 -1
- package/dist/cjs/redirect.d.cts +0 -1
- package/dist/cjs/route.cjs.map +1 -1
- package/dist/cjs/router.cjs +187 -442
- package/dist/cjs/router.cjs.map +1 -1
- package/dist/cjs/router.d.cts +61 -51
- package/dist/cjs/ssr/client.cjs +2 -2
- package/dist/cjs/ssr/createRequestHandler.cjs +60 -9
- package/dist/cjs/ssr/createRequestHandler.cjs.map +1 -1
- package/dist/cjs/ssr/createRequestHandler.d.cts +1 -0
- package/dist/cjs/ssr/handlerCallback.cjs +49 -4
- package/dist/cjs/ssr/handlerCallback.cjs.map +1 -1
- package/dist/cjs/ssr/handlerCallback.d.cts +3 -0
- package/dist/cjs/ssr/server.cjs +4 -0
- package/dist/cjs/ssr/server.d.cts +2 -2
- package/dist/cjs/ssr/ssr-client.d.cts +1 -10
- package/dist/cjs/ssr/ssr-match-id.cjs +2 -2
- package/dist/cjs/ssr/ssr-match-id.cjs.map +1 -1
- package/dist/cjs/ssr/ssr-server.cjs +6 -6
- package/dist/cjs/ssr/ssr-server.cjs.map +1 -1
- package/dist/cjs/ssr/transformStreamWithRouter.cjs +27 -1
- package/dist/cjs/ssr/transformStreamWithRouter.cjs.map +1 -1
- package/dist/cjs/ssr/transformStreamWithRouter.d.cts +2 -0
- package/dist/cjs/ssr/types.d.cts +0 -1
- package/dist/cjs/stores.cjs +30 -104
- package/dist/cjs/stores.cjs.map +1 -1
- package/dist/cjs/stores.d.cts +7 -32
- package/dist/cjs/utils.cjs +0 -4
- package/dist/cjs/utils.cjs.map +1 -1
- package/dist/esm/Matches.d.ts +3 -12
- package/dist/esm/Matches.js.map +1 -1
- package/dist/esm/await-signal.d.ts +1 -0
- package/dist/esm/await-signal.js +21 -0
- package/dist/esm/await-signal.js.map +1 -0
- package/dist/esm/index.d.ts +3 -2
- package/dist/esm/index.js +3 -2
- package/dist/esm/isServer/client.d.ts +1 -0
- package/dist/esm/isServer/client.js +2 -1
- package/dist/esm/isServer/client.js.map +1 -1
- package/dist/esm/isServer/development.d.ts +1 -0
- package/dist/esm/isServer/development.js +2 -1
- package/dist/esm/isServer/development.js.map +1 -1
- package/dist/esm/isServer/server.d.ts +1 -0
- package/dist/esm/isServer/server.js +2 -1
- package/dist/esm/isServer/server.js.map +1 -1
- package/dist/esm/load-client.d.ts +147 -0
- package/dist/esm/load-client.js +1462 -0
- package/dist/esm/load-client.js.map +1 -0
- package/dist/esm/load-server.d.ts +16 -0
- package/dist/esm/load-server.js +565 -0
- package/dist/esm/load-server.js.map +1 -0
- package/dist/esm/redirect.d.ts +0 -1
- package/dist/esm/redirect.js.map +1 -1
- package/dist/esm/route.js.map +1 -1
- package/dist/esm/router.d.ts +61 -51
- package/dist/esm/router.js +188 -444
- package/dist/esm/router.js.map +1 -1
- package/dist/esm/ssr/client.js +1 -1
- package/dist/esm/ssr/createRequestHandler.d.ts +1 -0
- package/dist/esm/ssr/createRequestHandler.js +61 -11
- package/dist/esm/ssr/createRequestHandler.js.map +1 -1
- package/dist/esm/ssr/handlerCallback.d.ts +3 -0
- package/dist/esm/ssr/handlerCallback.js +47 -5
- package/dist/esm/ssr/handlerCallback.js.map +1 -1
- package/dist/esm/ssr/server.d.ts +2 -2
- package/dist/esm/ssr/server.js +3 -3
- package/dist/esm/ssr/ssr-client.d.ts +1 -10
- package/dist/esm/ssr/ssr-match-id.js +2 -2
- package/dist/esm/ssr/ssr-match-id.js.map +1 -1
- package/dist/esm/ssr/ssr-server.js +6 -6
- package/dist/esm/ssr/ssr-server.js.map +1 -1
- package/dist/esm/ssr/transformStreamWithRouter.d.ts +2 -0
- package/dist/esm/ssr/transformStreamWithRouter.js +27 -1
- package/dist/esm/ssr/transformStreamWithRouter.js.map +1 -1
- package/dist/esm/ssr/types.d.ts +0 -1
- package/dist/esm/stores.d.ts +7 -32
- package/dist/esm/stores.js +30 -104
- package/dist/esm/stores.js.map +1 -1
- package/dist/esm/utils.js +1 -4
- package/dist/esm/utils.js.map +1 -1
- package/package.json +3 -3
- package/src/Matches.ts +6 -21
- package/src/await-signal.ts +27 -0
- package/src/index.ts +1 -3
- package/src/isServer/client.ts +1 -0
- package/src/isServer/development.ts +1 -0
- package/src/isServer/server.ts +1 -0
- package/src/load-client.ts +2701 -0
- package/src/load-server.ts +849 -0
- package/src/redirect.ts +0 -1
- package/src/route.ts +2 -11
- package/src/router.ts +379 -769
- package/src/ssr/createRequestHandler.ts +109 -16
- package/src/ssr/handlerCallback.ts +76 -10
- package/src/ssr/server.ts +4 -1
- package/src/ssr/ssr-client.ts +1 -310
- package/src/ssr/ssr-match-id.ts +11 -2
- package/src/ssr/ssr-server.ts +9 -8
- package/src/ssr/transformStreamWithRouter.ts +37 -1
- package/src/ssr/types.ts +0 -1
- package/src/stores.ts +46 -208
- package/dist/cjs/load-matches.cjs +0 -658
- package/dist/cjs/load-matches.cjs.map +0 -1
- package/dist/cjs/load-matches.d.cts +0 -18
- package/dist/cjs/ssr/ssr-client.cjs +0 -183
- package/dist/cjs/ssr/ssr-client.cjs.map +0 -1
- package/dist/esm/load-matches.d.ts +0 -18
- package/dist/esm/load-matches.js +0 -656
- package/dist/esm/load-matches.js.map +0 -1
- package/dist/esm/ssr/ssr-client.js +0 -183
- package/dist/esm/ssr/ssr-client.js.map +0 -1
- package/src/load-matches.ts +0 -1278
|
@@ -4,6 +4,8 @@ import { TSR_SCRIPT_BARRIER_ID } from './constants'
|
|
|
4
4
|
import type { AnyRouter } from '../router'
|
|
5
5
|
|
|
6
6
|
export type TransformStreamWithRouterOptions = {
|
|
7
|
+
/** The request lifetime that owns this response stream. */
|
|
8
|
+
signal?: AbortSignal
|
|
7
9
|
/** Timeout for serialization to complete after app render finishes (default: 60000ms) */
|
|
8
10
|
timeoutMs?: number
|
|
9
11
|
/** Maximum lifetime of the stream transform (default: 120000ms). Safety net for cleanup. */
|
|
@@ -196,6 +198,22 @@ function createAbortNotifier(opts?: TransformStreamWithRouterOptions) {
|
|
|
196
198
|
}
|
|
197
199
|
}
|
|
198
200
|
|
|
201
|
+
function listenToAbort(
|
|
202
|
+
signal: AbortSignal | undefined,
|
|
203
|
+
onAbort: (reason?: unknown) => void,
|
|
204
|
+
) {
|
|
205
|
+
if (!signal) {
|
|
206
|
+
return
|
|
207
|
+
}
|
|
208
|
+
if (signal.aborted) {
|
|
209
|
+
onAbort(signal.reason)
|
|
210
|
+
return
|
|
211
|
+
}
|
|
212
|
+
const listener = () => onAbort(signal.reason)
|
|
213
|
+
signal.addEventListener('abort', listener, { once: true })
|
|
214
|
+
return () => signal.removeEventListener('abort', listener)
|
|
215
|
+
}
|
|
216
|
+
|
|
199
217
|
export function transformStreamWithRouter(
|
|
200
218
|
router: AnyRouter,
|
|
201
219
|
appStream: ReadableStream,
|
|
@@ -224,6 +242,7 @@ function makeFastPathStream(
|
|
|
224
242
|
let controller: ReadableStreamDefaultController<Uint8Array> | undefined
|
|
225
243
|
let state: MergeState = MergeState.ReadingBody
|
|
226
244
|
let lifetimeTimeoutHandle: ReturnType<typeof setTimeout> | undefined
|
|
245
|
+
let stopListeningToAbort: (() => void) | undefined
|
|
227
246
|
let stopListeningToInjectedHtml: (() => void) | undefined
|
|
228
247
|
const readerState = createReaderState(appStream)
|
|
229
248
|
const notifyAbort = createAbortNotifier(opts)
|
|
@@ -251,6 +270,8 @@ function makeFastPathStream(
|
|
|
251
270
|
clearTimeout(lifetimeTimeoutHandle)
|
|
252
271
|
lifetimeTimeoutHandle = undefined
|
|
253
272
|
}
|
|
273
|
+
stopListeningToAbort?.()
|
|
274
|
+
stopListeningToAbort = undefined
|
|
254
275
|
try {
|
|
255
276
|
stopListeningToInjectedHtml?.()
|
|
256
277
|
} catch {
|
|
@@ -360,6 +381,11 @@ function makeFastPathStream(
|
|
|
360
381
|
},
|
|
361
382
|
})
|
|
362
383
|
|
|
384
|
+
stopListeningToAbort = listenToAbort(opts?.signal, (reason) => {
|
|
385
|
+
safeError(reason)
|
|
386
|
+
cleanup(reason)
|
|
387
|
+
})
|
|
388
|
+
|
|
363
389
|
return stream
|
|
364
390
|
}
|
|
365
391
|
|
|
@@ -380,6 +406,7 @@ function makeMainStream(
|
|
|
380
406
|
let stopListeningToSerializationFinished: (() => void) | undefined
|
|
381
407
|
let serializationTimeoutHandle: ReturnType<typeof setTimeout> | undefined
|
|
382
408
|
let lifetimeTimeoutHandle: ReturnType<typeof setTimeout> | undefined
|
|
409
|
+
let stopListeningToAbort: (() => void) | undefined
|
|
383
410
|
let cleanedUp = false
|
|
384
411
|
|
|
385
412
|
let controller: ReadableStreamDefaultController<Uint8Array> | undefined
|
|
@@ -509,6 +536,8 @@ function makeMainStream(
|
|
|
509
536
|
}
|
|
510
537
|
stopListeningToInjectedHtml = undefined
|
|
511
538
|
stopListeningToSerializationFinished = undefined
|
|
539
|
+
stopListeningToAbort?.()
|
|
540
|
+
stopListeningToAbort = undefined
|
|
512
541
|
|
|
513
542
|
if (serializationTimeoutHandle !== undefined) {
|
|
514
543
|
clearTimeout(serializationTimeoutHandle)
|
|
@@ -763,7 +792,14 @@ function makeMainStream(
|
|
|
763
792
|
if (cleanedUp || isDone()) return stream
|
|
764
793
|
}
|
|
765
794
|
|
|
766
|
-
|
|
795
|
+
stopListeningToAbort = listenToAbort(opts?.signal, (reason) => {
|
|
796
|
+
safeError(reason)
|
|
797
|
+
cleanup(reason)
|
|
798
|
+
})
|
|
799
|
+
if (cleanedUp || isDone())
|
|
800
|
+
return stream
|
|
801
|
+
|
|
802
|
+
// Transform the appStream
|
|
767
803
|
;(async () => {
|
|
768
804
|
try {
|
|
769
805
|
while (true) {
|
package/src/ssr/types.ts
CHANGED
package/src/stores.ts
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
import { createLRUCache } from './lru-cache'
|
|
2
1
|
import { arraysEqual, functionalUpdate } from './utils'
|
|
3
2
|
|
|
4
3
|
import type { AnyRoute } from './route'
|
|
5
4
|
import type { RouterState } from './router'
|
|
6
5
|
import type { FullSearchSchema } from './routeInfo'
|
|
7
6
|
import type { ParsedLocation } from './location'
|
|
8
|
-
import type { AnyRedirect } from './redirect'
|
|
9
7
|
import type { AnyRouteMatch } from './Matches'
|
|
10
8
|
|
|
11
9
|
export interface RouterReadableStore<TValue> {
|
|
@@ -34,12 +32,9 @@ export type StoreConfig = {
|
|
|
34
32
|
createMutableStore: MutableStoreFactory
|
|
35
33
|
createReadonlyStore: ReadonlyStoreFactory
|
|
36
34
|
batch: RouterBatchFn
|
|
37
|
-
init?: (stores: RouterStores<AnyRoute>) => void
|
|
38
35
|
}
|
|
39
36
|
|
|
40
|
-
type MatchStore = RouterWritableStore<AnyRouteMatch
|
|
41
|
-
routeId?: string
|
|
42
|
-
}
|
|
37
|
+
type MatchStore = RouterWritableStore<AnyRouteMatch | undefined>
|
|
43
38
|
type ReadableStore<TValue> = RouterReadableStore<TValue>
|
|
44
39
|
|
|
45
40
|
/** SSR non-reactive createMutableStore */
|
|
@@ -71,272 +66,115 @@ export function createNonReactiveReadonlyStore<TValue>(
|
|
|
71
66
|
|
|
72
67
|
export interface RouterStores<in out TRouteTree extends AnyRoute> {
|
|
73
68
|
status: RouterWritableStore<RouterState<TRouteTree>['status']>
|
|
74
|
-
loadedAt: RouterWritableStore<number>
|
|
75
|
-
isLoading: RouterWritableStore<boolean>
|
|
76
|
-
isTransitioning: RouterWritableStore<boolean>
|
|
77
69
|
location: RouterWritableStore<ParsedLocation<FullSearchSchema<TRouteTree>>>
|
|
78
70
|
resolvedLocation: RouterWritableStore<
|
|
79
71
|
ParsedLocation<FullSearchSchema<TRouteTree>> | undefined
|
|
80
72
|
>
|
|
81
|
-
|
|
82
|
-
redirect: RouterWritableStore<AnyRedirect | undefined>
|
|
83
|
-
matchesId: RouterWritableStore<Array<string>>
|
|
84
|
-
pendingIds: RouterWritableStore<Array<string>>
|
|
85
|
-
/** @internal */
|
|
86
|
-
cachedIds: RouterWritableStore<Array<string>>
|
|
73
|
+
ids: RouterWritableStore<Array<string>>
|
|
87
74
|
matches: ReadableStore<Array<AnyRouteMatch>>
|
|
88
|
-
pendingMatches: ReadableStore<Array<AnyRouteMatch>>
|
|
89
|
-
cachedMatches: ReadableStore<Array<AnyRouteMatch>>
|
|
90
|
-
firstId: ReadableStore<string | undefined>
|
|
91
|
-
hasPending: ReadableStore<boolean>
|
|
92
|
-
matchRouteDeps: ReadableStore<{
|
|
93
|
-
locationHref: string
|
|
94
|
-
resolvedLocationHref: string | undefined
|
|
95
|
-
status: RouterState<TRouteTree>['status']
|
|
96
|
-
}>
|
|
97
75
|
__store: RouterReadableStore<RouterState<TRouteTree>>
|
|
98
76
|
|
|
99
|
-
|
|
100
|
-
pendingMatchStores: Map<string, MatchStore>
|
|
101
|
-
cachedMatchStores: Map<string, MatchStore>
|
|
77
|
+
byRoute: Map<string, MatchStore>
|
|
102
78
|
|
|
103
79
|
/**
|
|
104
|
-
* Get
|
|
105
|
-
*
|
|
106
|
-
* The computed depends on matchesId + the individual match store, so
|
|
107
|
-
* subscribers are only notified when the resolved match state changes.
|
|
80
|
+
* Get the stable atom for a route's presented match. The atom remains in the
|
|
81
|
+
* pool when the route leaves and contains `undefined` until it re-enters.
|
|
108
82
|
*/
|
|
109
|
-
|
|
83
|
+
getMatchStore: (
|
|
110
84
|
routeId: string,
|
|
111
85
|
) => RouterReadableStore<AnyRouteMatch | undefined>
|
|
112
86
|
|
|
113
87
|
setMatches: (nextMatches: Array<AnyRouteMatch>) => void
|
|
114
|
-
setPending: (nextMatches: Array<AnyRouteMatch>) => void
|
|
115
|
-
setCached: (nextMatches: Array<AnyRouteMatch>) => void
|
|
116
88
|
}
|
|
117
89
|
|
|
118
90
|
export function createRouterStores<TRouteTree extends AnyRoute>(
|
|
119
|
-
|
|
91
|
+
initialLocation: RouterState<TRouteTree>['location'],
|
|
120
92
|
config: StoreConfig,
|
|
121
93
|
): RouterStores<TRouteTree> {
|
|
122
|
-
const { createMutableStore, createReadonlyStore, batch
|
|
94
|
+
const { createMutableStore, createReadonlyStore, batch } = config
|
|
123
95
|
|
|
124
96
|
// non reactive utilities
|
|
125
|
-
const
|
|
126
|
-
const pendingMatchStores = new Map<string, MatchStore>()
|
|
127
|
-
const cachedMatchStores = new Map<string, MatchStore>()
|
|
97
|
+
const byRoute = new Map<string, MatchStore>()
|
|
128
98
|
|
|
129
99
|
// atoms
|
|
130
|
-
const status = createMutableStore(
|
|
131
|
-
const
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
const
|
|
135
|
-
const resolvedLocation = createMutableStore(initialState.resolvedLocation)
|
|
136
|
-
const statusCode = createMutableStore(initialState.statusCode)
|
|
137
|
-
const redirect = createMutableStore(initialState.redirect)
|
|
138
|
-
const matchesId = createMutableStore<Array<string>>([])
|
|
139
|
-
const pendingIds = createMutableStore<Array<string>>([])
|
|
140
|
-
const cachedIds = createMutableStore<Array<string>>([])
|
|
100
|
+
const status = createMutableStore<RouterState<TRouteTree>['status']>('idle')
|
|
101
|
+
const location = createMutableStore(initialLocation)
|
|
102
|
+
const resolvedLocation =
|
|
103
|
+
createMutableStore<RouterState<TRouteTree>['resolvedLocation']>(undefined)
|
|
104
|
+
const ids = createMutableStore<Array<string>>([])
|
|
141
105
|
|
|
142
106
|
// 1st order derived stores
|
|
143
107
|
const matches = createReadonlyStore(() =>
|
|
144
|
-
|
|
145
|
-
)
|
|
146
|
-
const pendingMatches = createReadonlyStore(() =>
|
|
147
|
-
readPoolMatches(pendingMatchStores, pendingIds.get()),
|
|
148
|
-
)
|
|
149
|
-
const cachedMatches = createReadonlyStore(() =>
|
|
150
|
-
readPoolMatches(cachedMatchStores, cachedIds.get()),
|
|
151
|
-
)
|
|
152
|
-
const firstId = createReadonlyStore(() => matchesId.get()[0])
|
|
153
|
-
const hasPending = createReadonlyStore(() =>
|
|
154
|
-
matchesId.get().some((matchId) => {
|
|
155
|
-
const store = matchStores.get(matchId)
|
|
156
|
-
return store?.get().status === 'pending'
|
|
157
|
-
}),
|
|
108
|
+
ids.get().map((id) => byRoute.get(id)!.get()!),
|
|
158
109
|
)
|
|
159
|
-
const matchRouteDeps = createReadonlyStore(() => ({
|
|
160
|
-
locationHref: location.get().href,
|
|
161
|
-
resolvedLocationHref: resolvedLocation.get()?.href,
|
|
162
|
-
status: status.get(),
|
|
163
|
-
}))
|
|
164
110
|
|
|
165
111
|
// compatibility "big" state store
|
|
166
112
|
const __store = createReadonlyStore(() => ({
|
|
167
113
|
status: status.get(),
|
|
168
|
-
|
|
169
|
-
isLoading: isLoading.get(),
|
|
170
|
-
isTransitioning: isTransitioning.get(),
|
|
114
|
+
isLoading: status.get() === 'pending',
|
|
171
115
|
matches: matches.get(),
|
|
172
116
|
location: location.get(),
|
|
173
117
|
resolvedLocation: resolvedLocation.get(),
|
|
174
|
-
statusCode: statusCode.get(),
|
|
175
|
-
redirect: redirect.get(),
|
|
176
118
|
}))
|
|
177
119
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
// 64 max size is arbitrary, this is only for active matches anyway so
|
|
184
|
-
// it should be plenty. And we already have a 32 limit due to route
|
|
185
|
-
// matching bitmask anyway.
|
|
186
|
-
const matchStoreByRouteIdCache = createLRUCache<
|
|
187
|
-
string,
|
|
188
|
-
RouterReadableStore<AnyRouteMatch | undefined>
|
|
189
|
-
>(64)
|
|
190
|
-
|
|
191
|
-
function getRouteMatchStore(
|
|
192
|
-
routeId: string,
|
|
193
|
-
): RouterReadableStore<AnyRouteMatch | undefined> {
|
|
194
|
-
let cached = matchStoreByRouteIdCache.get(routeId)
|
|
195
|
-
if (!cached) {
|
|
196
|
-
cached = createReadonlyStore(() => {
|
|
197
|
-
// Reading matchesId.get() tracks it as a dependency.
|
|
198
|
-
// When matchesId changes (navigation), this computed re-evaluates.
|
|
199
|
-
const ids = matchesId.get()
|
|
200
|
-
for (const id of ids) {
|
|
201
|
-
const matchStore = matchStores.get(id)
|
|
202
|
-
if (matchStore && matchStore.routeId === routeId) {
|
|
203
|
-
// Reading matchStore.get() tracks it as a dependency.
|
|
204
|
-
// When the match store's state changes, this re-evaluates.
|
|
205
|
-
return matchStore.get()
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
return undefined
|
|
209
|
-
})
|
|
210
|
-
matchStoreByRouteIdCache.set(routeId, cached)
|
|
120
|
+
function getMatchStore(routeId: string): MatchStore {
|
|
121
|
+
let matchStore = byRoute.get(routeId)
|
|
122
|
+
if (!matchStore) {
|
|
123
|
+
matchStore = createMutableStore<AnyRouteMatch | undefined>(undefined)
|
|
124
|
+
byRoute.set(routeId, matchStore)
|
|
211
125
|
}
|
|
212
|
-
return
|
|
126
|
+
return matchStore
|
|
213
127
|
}
|
|
214
128
|
|
|
215
129
|
const store = {
|
|
216
130
|
// atoms
|
|
217
131
|
status,
|
|
218
|
-
loadedAt,
|
|
219
|
-
isLoading,
|
|
220
|
-
isTransitioning,
|
|
221
132
|
location,
|
|
222
133
|
resolvedLocation,
|
|
223
|
-
|
|
224
|
-
redirect,
|
|
225
|
-
matchesId,
|
|
226
|
-
pendingIds,
|
|
227
|
-
cachedIds,
|
|
134
|
+
ids,
|
|
228
135
|
|
|
229
136
|
// derived
|
|
230
137
|
matches,
|
|
231
|
-
pendingMatches,
|
|
232
|
-
cachedMatches,
|
|
233
|
-
firstId,
|
|
234
|
-
hasPending,
|
|
235
|
-
matchRouteDeps,
|
|
236
138
|
|
|
237
139
|
// non-reactive state
|
|
238
|
-
|
|
239
|
-
pendingMatchStores,
|
|
240
|
-
cachedMatchStores,
|
|
140
|
+
byRoute,
|
|
241
141
|
|
|
242
142
|
// compatibility "big" state
|
|
243
143
|
__store,
|
|
244
144
|
|
|
245
|
-
// per-
|
|
246
|
-
|
|
145
|
+
// stable per-route presentation atoms
|
|
146
|
+
getMatchStore,
|
|
247
147
|
|
|
248
148
|
// methods
|
|
249
149
|
setMatches,
|
|
250
|
-
setPending,
|
|
251
|
-
setCached,
|
|
252
150
|
}
|
|
253
151
|
|
|
254
|
-
// initialize the active matches
|
|
255
|
-
setMatches(initialState.matches as Array<AnyRouteMatch>)
|
|
256
|
-
init?.(store)
|
|
257
|
-
|
|
258
152
|
// setters to update non-reactive utilities in sync with the reactive stores
|
|
259
153
|
function setMatches(nextMatches: Array<AnyRouteMatch>) {
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
function setPending(nextMatches: Array<AnyRouteMatch>) {
|
|
270
|
-
reconcileMatchPool(
|
|
271
|
-
nextMatches,
|
|
272
|
-
pendingMatchStores,
|
|
273
|
-
pendingIds,
|
|
274
|
-
createMutableStore,
|
|
275
|
-
batch,
|
|
276
|
-
)
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
function setCached(nextMatches: Array<AnyRouteMatch>) {
|
|
280
|
-
reconcileMatchPool(
|
|
281
|
-
nextMatches,
|
|
282
|
-
cachedMatchStores,
|
|
283
|
-
cachedIds,
|
|
284
|
-
createMutableStore,
|
|
285
|
-
batch,
|
|
286
|
-
)
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
return store
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
function readPoolMatches(
|
|
293
|
-
pool: Map<string, MatchStore>,
|
|
294
|
-
ids: Array<string>,
|
|
295
|
-
): Array<AnyRouteMatch> {
|
|
296
|
-
const matches: Array<AnyRouteMatch> = []
|
|
297
|
-
for (const id of ids) {
|
|
298
|
-
const matchStore = pool.get(id)
|
|
299
|
-
if (matchStore) {
|
|
300
|
-
matches.push(matchStore.get())
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
return matches
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
function reconcileMatchPool(
|
|
307
|
-
nextMatches: Array<AnyRouteMatch>,
|
|
308
|
-
pool: Map<string, MatchStore>,
|
|
309
|
-
idStore: RouterWritableStore<Array<string>>,
|
|
310
|
-
createMutableStore: MutableStoreFactory,
|
|
311
|
-
batch: RouterBatchFn,
|
|
312
|
-
): void {
|
|
313
|
-
const nextIds = nextMatches.map((d) => d.id)
|
|
314
|
-
const nextIdSet = new Set(nextIds)
|
|
315
|
-
|
|
316
|
-
batch(() => {
|
|
317
|
-
for (const id of pool.keys()) {
|
|
318
|
-
if (!nextIdSet.has(id)) {
|
|
319
|
-
pool.delete(id)
|
|
154
|
+
const previousIds = ids.get()
|
|
155
|
+
const nextIds = nextMatches.map((match) => match.routeId)
|
|
156
|
+
|
|
157
|
+
batch(() => {
|
|
158
|
+
// Publish lane membership first so framework trees reconcile departures
|
|
159
|
+
// before observers of a leaving route receive its tombstone.
|
|
160
|
+
if (!arraysEqual(previousIds, nextIds)) {
|
|
161
|
+
ids.set(nextIds)
|
|
320
162
|
}
|
|
321
|
-
}
|
|
322
163
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
matchStore.routeId = nextMatch.routeId
|
|
328
|
-
pool.set(nextMatch.id, matchStore)
|
|
329
|
-
continue
|
|
164
|
+
for (const id of previousIds) {
|
|
165
|
+
if (!nextIds.includes(id)) {
|
|
166
|
+
byRoute.get(id)!.set(() => undefined)
|
|
167
|
+
}
|
|
330
168
|
}
|
|
331
169
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
170
|
+
for (const nextMatch of nextMatches) {
|
|
171
|
+
const matchStore = getMatchStore(nextMatch.routeId)
|
|
172
|
+
if (matchStore.get() !== nextMatch) {
|
|
173
|
+
matchStore.set(nextMatch)
|
|
174
|
+
}
|
|
335
175
|
}
|
|
336
|
-
}
|
|
176
|
+
})
|
|
177
|
+
}
|
|
337
178
|
|
|
338
|
-
|
|
339
|
-
idStore.set(nextIds)
|
|
340
|
-
}
|
|
341
|
-
})
|
|
179
|
+
return store
|
|
342
180
|
}
|