@tanstack/router-core 1.126.2 → 1.127.2
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 +1 -1
- package/dist/cjs/index.d.cts +1 -2
- package/dist/cjs/router.cjs +8 -25
- package/dist/cjs/router.cjs.map +1 -1
- package/dist/cjs/router.d.cts +9 -57
- package/dist/cjs/ssr/client.cjs +0 -2
- package/dist/cjs/ssr/client.cjs.map +1 -1
- package/dist/cjs/ssr/client.d.cts +1 -2
- package/dist/cjs/ssr/createRequestHandler.cjs +2 -1
- package/dist/cjs/ssr/createRequestHandler.cjs.map +1 -1
- package/dist/cjs/ssr/seroval-plugins.cjs +34 -0
- package/dist/cjs/ssr/seroval-plugins.cjs.map +1 -0
- package/dist/cjs/ssr/seroval-plugins.d.cts +10 -0
- package/dist/cjs/ssr/server.cjs +0 -4
- package/dist/cjs/ssr/server.cjs.map +1 -1
- package/dist/cjs/ssr/server.d.cts +1 -3
- package/dist/cjs/ssr/ssr-client.cjs +18 -56
- package/dist/cjs/ssr/ssr-client.cjs.map +1 -1
- package/dist/cjs/ssr/ssr-client.d.cts +17 -57
- package/dist/cjs/ssr/ssr-server.cjs +75 -220
- package/dist/cjs/ssr/ssr-server.cjs.map +1 -1
- package/dist/cjs/ssr/ssr-server.d.cts +14 -28
- package/dist/cjs/ssr/transformStreamWithRouter.cjs +1 -0
- package/dist/cjs/ssr/transformStreamWithRouter.cjs.map +1 -1
- package/dist/cjs/ssr/tsrScript.cjs +1 -1
- package/dist/cjs/ssr/tsrScript.cjs.map +1 -1
- package/dist/cjs/ssr/tsrScript.d.cts +0 -1
- package/dist/esm/Matches.d.ts +1 -1
- package/dist/esm/Matches.js.map +1 -1
- package/dist/esm/index.d.ts +1 -2
- package/dist/esm/router.d.ts +9 -57
- package/dist/esm/router.js +8 -25
- package/dist/esm/router.js.map +1 -1
- package/dist/esm/ssr/client.d.ts +1 -2
- package/dist/esm/ssr/client.js +1 -3
- package/dist/esm/ssr/client.js.map +1 -1
- package/dist/esm/ssr/createRequestHandler.js +3 -2
- package/dist/esm/ssr/createRequestHandler.js.map +1 -1
- package/dist/esm/ssr/seroval-plugins.d.ts +10 -0
- package/dist/esm/ssr/seroval-plugins.js +34 -0
- package/dist/esm/ssr/seroval-plugins.js.map +1 -0
- package/dist/esm/ssr/server.d.ts +1 -3
- package/dist/esm/ssr/server.js +1 -5
- package/dist/esm/ssr/ssr-client.d.ts +17 -57
- package/dist/esm/ssr/ssr-client.js +18 -56
- package/dist/esm/ssr/ssr-client.js.map +1 -1
- package/dist/esm/ssr/ssr-server.d.ts +14 -28
- package/dist/esm/ssr/ssr-server.js +76 -221
- package/dist/esm/ssr/ssr-server.js.map +1 -1
- package/dist/esm/ssr/transformStreamWithRouter.js +1 -0
- package/dist/esm/ssr/transformStreamWithRouter.js.map +1 -1
- package/dist/esm/ssr/tsrScript.d.ts +0 -1
- package/dist/esm/ssr/tsrScript.js +1 -1
- package/dist/esm/ssr/tsrScript.js.map +1 -1
- package/package.json +3 -3
- package/src/Matches.ts +1 -1
- package/src/index.ts +0 -18
- package/src/router.ts +15 -82
- package/src/ssr/client.ts +1 -11
- package/src/ssr/createRequestHandler.ts +2 -2
- package/src/ssr/seroval-plugins.ts +43 -0
- package/src/ssr/server.ts +1 -14
- package/src/ssr/ssr-client.ts +35 -128
- package/src/ssr/ssr-server.ts +89 -307
- package/src/ssr/transformStreamWithRouter.ts +1 -0
- package/src/ssr/tsrScript.ts +4 -88
- package/dist/cjs/serializer.cjs +0 -146
- package/dist/cjs/serializer.cjs.map +0 -1
- package/dist/cjs/serializer.d.cts +0 -28
- package/dist/esm/serializer.d.ts +0 -28
- package/dist/esm/serializer.js +0 -146
- package/dist/esm/serializer.js.map +0 -1
- package/src/serializer.ts +0 -205
package/src/router.ts
CHANGED
|
@@ -46,7 +46,6 @@ import type {
|
|
|
46
46
|
Updater,
|
|
47
47
|
} from './utils'
|
|
48
48
|
import type { ParsedLocation } from './location'
|
|
49
|
-
import type { DeferredPromiseState } from './defer'
|
|
50
49
|
import type {
|
|
51
50
|
AnyContext,
|
|
52
51
|
AnyRoute,
|
|
@@ -78,7 +77,6 @@ import type {
|
|
|
78
77
|
NavigateFn,
|
|
79
78
|
} from './RouterProvider'
|
|
80
79
|
import type { Manifest } from './manifest'
|
|
81
|
-
import type { TsrSerializer } from './serializer'
|
|
82
80
|
import type { AnySchema, AnyValidator } from './validators'
|
|
83
81
|
import type { NavigateOptions, ResolveRelativePath, ToOptions } from './link'
|
|
84
82
|
import type { NotFoundError } from './not-found'
|
|
@@ -288,7 +286,7 @@ export interface RouterOptions<
|
|
|
288
286
|
* @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#dehydrate-method)
|
|
289
287
|
* @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/external-data-loading#critical-dehydrationhydration)
|
|
290
288
|
*/
|
|
291
|
-
dehydrate?: () => TDehydrated
|
|
289
|
+
dehydrate?: () => Awaitable<TDehydrated>
|
|
292
290
|
/**
|
|
293
291
|
* A function that will be called when the router is hydrated.
|
|
294
292
|
*
|
|
@@ -452,7 +450,7 @@ type NavigationEventInfo = {
|
|
|
452
450
|
hashChanged: boolean
|
|
453
451
|
}
|
|
454
452
|
|
|
455
|
-
export
|
|
453
|
+
export interface RouterEvents {
|
|
456
454
|
onBeforeNavigate: {
|
|
457
455
|
type: 'onBeforeNavigate'
|
|
458
456
|
} & NavigationEventInfo
|
|
@@ -468,10 +466,6 @@ export type RouterEvents = {
|
|
|
468
466
|
onBeforeRouteMount: {
|
|
469
467
|
type: 'onBeforeRouteMount'
|
|
470
468
|
} & NavigationEventInfo
|
|
471
|
-
onInjectedHtml: {
|
|
472
|
-
type: 'onInjectedHtml'
|
|
473
|
-
promise: Promise<string>
|
|
474
|
-
}
|
|
475
469
|
onRendered: {
|
|
476
470
|
type: 'onRendered'
|
|
477
471
|
} & NavigationEventInfo
|
|
@@ -486,6 +480,11 @@ export type RouterListener<TRouterEvent extends RouterEvent> = {
|
|
|
486
480
|
fn: ListenerFn<TRouterEvent>
|
|
487
481
|
}
|
|
488
482
|
|
|
483
|
+
export type SubscribeFn = <TType extends keyof RouterEvents>(
|
|
484
|
+
eventType: TType,
|
|
485
|
+
fn: ListenerFn<RouterEvents[TType]>,
|
|
486
|
+
) => () => void
|
|
487
|
+
|
|
489
488
|
export interface MatchRoutesOpts {
|
|
490
489
|
preload?: boolean
|
|
491
490
|
throwOnError?: boolean
|
|
@@ -523,11 +522,6 @@ export type RouterConstructorOptions<
|
|
|
523
522
|
> &
|
|
524
523
|
RouterContextOptions<TRouteTree>
|
|
525
524
|
|
|
526
|
-
export interface RouterErrorSerializer<TSerializedError> {
|
|
527
|
-
serialize: (err: unknown) => TSerializedError
|
|
528
|
-
deserialize: (err: TSerializedError) => unknown
|
|
529
|
-
}
|
|
530
|
-
|
|
531
525
|
export type PreloadRouteFn<
|
|
532
526
|
TRouteTree extends AnyRoute,
|
|
533
527
|
TTrailingSlashOption extends TrailingSlashOption,
|
|
@@ -624,11 +618,6 @@ export type CommitLocationFn = ({
|
|
|
624
618
|
|
|
625
619
|
export type StartTransitionFn = (fn: () => void) => void
|
|
626
620
|
|
|
627
|
-
export type SubscribeFn = <TType extends keyof RouterEvents>(
|
|
628
|
-
eventType: TType,
|
|
629
|
-
fn: ListenerFn<RouterEvents[TType]>,
|
|
630
|
-
) => () => void
|
|
631
|
-
|
|
632
621
|
export interface MatchRoutesFn {
|
|
633
622
|
(
|
|
634
623
|
pathname: string,
|
|
@@ -658,16 +647,16 @@ export type ClearCacheFn<TRouter extends AnyRouter> = (opts?: {
|
|
|
658
647
|
filter?: (d: MakeRouteMatchUnion<TRouter>) => boolean
|
|
659
648
|
}) => void
|
|
660
649
|
|
|
661
|
-
export interface
|
|
650
|
+
export interface ServerSsr {
|
|
662
651
|
injectedHtml: Array<InjectedHtmlEntry>
|
|
663
652
|
injectHtml: (getHtml: () => string | Promise<string>) => Promise<void>
|
|
664
653
|
injectScript: (
|
|
665
654
|
getScript: () => string | Promise<string>,
|
|
666
655
|
opts?: { logScript?: boolean },
|
|
667
656
|
) => Promise<void>
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
657
|
+
isDehydrated: () => boolean
|
|
658
|
+
onRenderFinished: (listener: () => void) => void
|
|
659
|
+
dehydrate: () => Promise<void>
|
|
671
660
|
}
|
|
672
661
|
|
|
673
662
|
export type AnyRouterWithContext<TContext> = RouterCore<
|
|
@@ -710,29 +699,6 @@ export function defaultSerializeError(err: unknown) {
|
|
|
710
699
|
data: err,
|
|
711
700
|
}
|
|
712
701
|
}
|
|
713
|
-
export interface ExtractedBaseEntry {
|
|
714
|
-
dataType: '__beforeLoadContext' | 'loaderData'
|
|
715
|
-
type: string
|
|
716
|
-
path: Array<string>
|
|
717
|
-
id: number
|
|
718
|
-
matchIndex: number
|
|
719
|
-
}
|
|
720
|
-
|
|
721
|
-
export interface ExtractedStream extends ExtractedBaseEntry {
|
|
722
|
-
type: 'stream'
|
|
723
|
-
streamState: StreamState
|
|
724
|
-
}
|
|
725
|
-
|
|
726
|
-
export interface ExtractedPromise extends ExtractedBaseEntry {
|
|
727
|
-
type: 'promise'
|
|
728
|
-
promiseState: DeferredPromiseState<any>
|
|
729
|
-
}
|
|
730
|
-
|
|
731
|
-
export type ExtractedEntry = ExtractedStream | ExtractedPromise
|
|
732
|
-
|
|
733
|
-
export type StreamState = {
|
|
734
|
-
promises: Array<ControlledPromise<string | null>>
|
|
735
|
-
}
|
|
736
702
|
|
|
737
703
|
export type TrailingSlashOption = 'always' | 'never' | 'preserve'
|
|
738
704
|
|
|
@@ -838,7 +804,7 @@ export class RouterCore<
|
|
|
838
804
|
})
|
|
839
805
|
|
|
840
806
|
if (typeof document !== 'undefined') {
|
|
841
|
-
|
|
807
|
+
self.__TSR_ROUTER__ = this
|
|
842
808
|
}
|
|
843
809
|
}
|
|
844
810
|
|
|
@@ -1293,7 +1259,7 @@ export class RouterCore<
|
|
|
1293
1259
|
error: undefined,
|
|
1294
1260
|
paramsError: parseErrors[index],
|
|
1295
1261
|
__routeContext: {},
|
|
1296
|
-
__beforeLoadContext:
|
|
1262
|
+
__beforeLoadContext: undefined,
|
|
1297
1263
|
context: {},
|
|
1298
1264
|
abortController: new AbortController(),
|
|
1299
1265
|
fetchCount: 0,
|
|
@@ -2188,10 +2154,6 @@ export class RouterCore<
|
|
|
2188
2154
|
this._handleNotFound(matches, err, {
|
|
2189
2155
|
updateMatch,
|
|
2190
2156
|
})
|
|
2191
|
-
this.serverSsr?.onMatchSettled({
|
|
2192
|
-
router: this,
|
|
2193
|
-
match: this.getMatch(match.id)!,
|
|
2194
|
-
})
|
|
2195
2157
|
throw err
|
|
2196
2158
|
}
|
|
2197
2159
|
}
|
|
@@ -2449,8 +2411,7 @@ export class RouterCore<
|
|
|
2449
2411
|
}
|
|
2450
2412
|
|
|
2451
2413
|
const beforeLoadContext =
|
|
2452
|
-
|
|
2453
|
-
{}
|
|
2414
|
+
await route.options.beforeLoad?.(beforeLoadFnContext)
|
|
2454
2415
|
|
|
2455
2416
|
if (
|
|
2456
2417
|
isRedirect(beforeLoadContext) ||
|
|
@@ -2543,10 +2504,6 @@ export class RouterCore<
|
|
|
2543
2504
|
...prev,
|
|
2544
2505
|
...head,
|
|
2545
2506
|
}))
|
|
2546
|
-
this.serverSsr?.onMatchSettled({
|
|
2547
|
-
router: this,
|
|
2548
|
-
match: this.getMatch(matchId)!,
|
|
2549
|
-
})
|
|
2550
2507
|
return this.getMatch(matchId)!
|
|
2551
2508
|
} else {
|
|
2552
2509
|
await potentialPendingMinPromise()
|
|
@@ -2708,11 +2665,6 @@ export class RouterCore<
|
|
|
2708
2665
|
...head,
|
|
2709
2666
|
}))
|
|
2710
2667
|
}
|
|
2711
|
-
|
|
2712
|
-
this.serverSsr?.onMatchSettled({
|
|
2713
|
-
router: this,
|
|
2714
|
-
match: this.getMatch(matchId)!,
|
|
2715
|
-
})
|
|
2716
2668
|
} catch (err) {
|
|
2717
2669
|
const head = await executeHead()
|
|
2718
2670
|
|
|
@@ -2773,10 +2725,6 @@ export class RouterCore<
|
|
|
2773
2725
|
...prev,
|
|
2774
2726
|
...head,
|
|
2775
2727
|
}))
|
|
2776
|
-
this.serverSsr?.onMatchSettled({
|
|
2777
|
-
router: this,
|
|
2778
|
-
match: this.getMatch(matchId)!,
|
|
2779
|
-
})
|
|
2780
2728
|
}
|
|
2781
2729
|
}
|
|
2782
2730
|
if (!loaderIsRunningAsync) {
|
|
@@ -3076,24 +3024,9 @@ export class RouterCore<
|
|
|
3076
3024
|
|
|
3077
3025
|
ssr?: {
|
|
3078
3026
|
manifest: Manifest | undefined
|
|
3079
|
-
serializer: TsrSerializer
|
|
3080
3027
|
}
|
|
3081
3028
|
|
|
3082
|
-
serverSsr?:
|
|
3083
|
-
injectedHtml: Array<InjectedHtmlEntry>
|
|
3084
|
-
injectHtml: (getHtml: () => string | Promise<string>) => Promise<void>
|
|
3085
|
-
injectScript: (
|
|
3086
|
-
getScript: () => string | Promise<string>,
|
|
3087
|
-
opts?: { logScript?: boolean },
|
|
3088
|
-
) => Promise<void>
|
|
3089
|
-
streamValue: (key: string, value: any) => void
|
|
3090
|
-
streamedKeys: Set<string>
|
|
3091
|
-
onMatchSettled: (opts: { router: AnyRouter; match: AnyRouteMatch }) => any
|
|
3092
|
-
}
|
|
3093
|
-
|
|
3094
|
-
clientSsr?: {
|
|
3095
|
-
getStreamedValue: <T>(key: string) => T | undefined
|
|
3096
|
-
}
|
|
3029
|
+
serverSsr?: ServerSsr
|
|
3097
3030
|
|
|
3098
3031
|
_handleNotFound = (
|
|
3099
3032
|
matches: Array<AnyRouteMatch>,
|
package/src/ssr/client.ts
CHANGED
|
@@ -2,14 +2,4 @@ export { mergeHeaders, headersInitToObject } from './headers'
|
|
|
2
2
|
export { json } from './json'
|
|
3
3
|
export type { JsonResponse } from './json'
|
|
4
4
|
export { hydrate } from './ssr-client'
|
|
5
|
-
export
|
|
6
|
-
DehydratedRouter,
|
|
7
|
-
ClientExtractedBaseEntry,
|
|
8
|
-
TsrSsrGlobal,
|
|
9
|
-
ClientExtractedEntry,
|
|
10
|
-
SsrMatch,
|
|
11
|
-
ClientExtractedPromise,
|
|
12
|
-
ClientExtractedStream,
|
|
13
|
-
ResolvePromiseState,
|
|
14
|
-
} from './ssr-client'
|
|
15
|
-
export { tsrSerializer } from '../serializer'
|
|
5
|
+
export * from './ssr-client'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createMemoryHistory } from '@tanstack/history'
|
|
2
2
|
import { mergeHeaders } from './headers'
|
|
3
|
-
import { attachRouterServerSsrUtils
|
|
3
|
+
import { attachRouterServerSsrUtils } from './ssr-server'
|
|
4
4
|
import type { HandlerCallback } from './handlerCallback'
|
|
5
5
|
import type { AnyRouter } from '../router'
|
|
6
6
|
import type { Manifest } from '../manifest'
|
|
@@ -39,7 +39,7 @@ export function createRequestHandler<TRouter extends AnyRouter>({
|
|
|
39
39
|
|
|
40
40
|
await router.load()
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
await router.serverSsr?.dehydrate()
|
|
43
43
|
|
|
44
44
|
const responseHeaders = getRequestHeaders({
|
|
45
45
|
router,
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { createPlugin } from 'seroval'
|
|
2
|
+
import type { SerovalNode } from 'seroval'
|
|
3
|
+
|
|
4
|
+
interface ErrorNode {
|
|
5
|
+
message: SerovalNode
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* this plugin serializes only the `message` part of an Error
|
|
10
|
+
* this helps with serializing e.g. a ZodError which has functions attached that cannot be serialized
|
|
11
|
+
*/
|
|
12
|
+
export const ShallowErrorPlugin = /* @__PURE__ */ createPlugin<
|
|
13
|
+
Error,
|
|
14
|
+
ErrorNode
|
|
15
|
+
>({
|
|
16
|
+
tag: 'tanstack-start:seroval-plugins/Error',
|
|
17
|
+
test(value) {
|
|
18
|
+
return value instanceof Error
|
|
19
|
+
},
|
|
20
|
+
parse: {
|
|
21
|
+
sync(value, ctx) {
|
|
22
|
+
return {
|
|
23
|
+
message: ctx.parse(value.message),
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
async async(value, ctx) {
|
|
27
|
+
return {
|
|
28
|
+
message: await ctx.parse(value.message),
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
stream(value, ctx) {
|
|
32
|
+
return {
|
|
33
|
+
message: ctx.parse(value.message),
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
serialize(node, ctx) {
|
|
38
|
+
return 'new Error(' + ctx.serialize(node.message) + ')'
|
|
39
|
+
},
|
|
40
|
+
deserialize(node, ctx) {
|
|
41
|
+
return new Error(ctx.deserialize(node.message) as string)
|
|
42
|
+
},
|
|
43
|
+
})
|
package/src/ssr/server.ts
CHANGED
|
@@ -7,17 +7,4 @@ export {
|
|
|
7
7
|
transformStreamWithRouter,
|
|
8
8
|
transformReadableStreamWithRouter,
|
|
9
9
|
} from './transformStreamWithRouter'
|
|
10
|
-
export {
|
|
11
|
-
attachRouterServerSsrUtils,
|
|
12
|
-
dehydrateRouter,
|
|
13
|
-
extractAsyncLoaderData,
|
|
14
|
-
onMatchSettled,
|
|
15
|
-
replaceBy,
|
|
16
|
-
} from './ssr-server'
|
|
17
|
-
export type {
|
|
18
|
-
ServerExtractedBaseEntry,
|
|
19
|
-
ServerExtractedEntry,
|
|
20
|
-
ServerExtractedPromise,
|
|
21
|
-
ServerExtractedStream,
|
|
22
|
-
} from './ssr-server'
|
|
23
|
-
export * from './tsrScript'
|
|
10
|
+
export { attachRouterServerSsrUtils } from './ssr-server'
|
package/src/ssr/ssr-client.ts
CHANGED
|
@@ -1,114 +1,62 @@
|
|
|
1
1
|
import invariant from 'tiny-invariant'
|
|
2
|
-
import { isPlainObject } from '../utils'
|
|
3
|
-
import { tsrSerializer } from '../serializer'
|
|
4
|
-
import type { DeferredPromiseState } from '../defer'
|
|
5
2
|
import type { MakeRouteMatch } from '../Matches'
|
|
6
|
-
import type { AnyRouter
|
|
3
|
+
import type { AnyRouter } from '../router'
|
|
7
4
|
import type { Manifest } from '../manifest'
|
|
8
5
|
import type { RouteContextOptions } from '../route'
|
|
6
|
+
import type { GLOBAL_TSR } from './ssr-server'
|
|
9
7
|
|
|
10
8
|
declare global {
|
|
11
9
|
interface Window {
|
|
12
|
-
|
|
10
|
+
[GLOBAL_TSR]?: TsrSsrGlobal
|
|
13
11
|
}
|
|
14
12
|
}
|
|
15
13
|
|
|
16
14
|
export interface TsrSsrGlobal {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
{
|
|
21
|
-
value: any
|
|
22
|
-
parsed: any
|
|
23
|
-
}
|
|
24
|
-
>
|
|
25
|
-
cleanScripts: () => void
|
|
26
|
-
dehydrated?: any
|
|
27
|
-
initMatch: (match: SsrMatch) => void
|
|
28
|
-
resolvePromise: (opts: {
|
|
29
|
-
matchId: string
|
|
30
|
-
id: number
|
|
31
|
-
promiseState: DeferredPromiseState<any>
|
|
32
|
-
}) => void
|
|
33
|
-
injectChunk: (opts: { matchId: string; id: number; chunk: string }) => void
|
|
34
|
-
closeStream: (opts: { matchId: string; id: number }) => void
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export interface SsrMatch {
|
|
38
|
-
id: string
|
|
39
|
-
__beforeLoadContext: string
|
|
40
|
-
loaderData?: string
|
|
41
|
-
error?: string
|
|
42
|
-
extracted?: Array<ClientExtractedEntry>
|
|
43
|
-
updatedAt: MakeRouteMatch['updatedAt']
|
|
44
|
-
status: MakeRouteMatch['status']
|
|
45
|
-
ssr?: boolean | 'data-only'
|
|
15
|
+
router?: DehydratedRouter
|
|
16
|
+
// clean scripts, shortened since this is sent for each streamed script
|
|
17
|
+
c: () => void
|
|
46
18
|
}
|
|
47
19
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export interface ClientExtractedBaseEntry {
|
|
63
|
-
type: string
|
|
64
|
-
path: Array<string>
|
|
20
|
+
function hydrateMatch(
|
|
21
|
+
deyhydratedMatch: DehydratedMatch,
|
|
22
|
+
): Partial<MakeRouteMatch> {
|
|
23
|
+
return {
|
|
24
|
+
id: deyhydratedMatch.i,
|
|
25
|
+
__beforeLoadContext: deyhydratedMatch.b,
|
|
26
|
+
loaderData: deyhydratedMatch.l,
|
|
27
|
+
status: deyhydratedMatch.s,
|
|
28
|
+
ssr: deyhydratedMatch.ssr,
|
|
29
|
+
updatedAt: deyhydratedMatch.u,
|
|
30
|
+
error: deyhydratedMatch.e,
|
|
31
|
+
}
|
|
65
32
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
33
|
+
export interface DehydratedMatch {
|
|
34
|
+
i: MakeRouteMatch['id']
|
|
35
|
+
b?: MakeRouteMatch['__beforeLoadContext']
|
|
36
|
+
l?: MakeRouteMatch['loaderData']
|
|
37
|
+
e?: MakeRouteMatch['error']
|
|
38
|
+
u: MakeRouteMatch['updatedAt']
|
|
39
|
+
s: MakeRouteMatch['status']
|
|
40
|
+
ssr?: MakeRouteMatch['ssr']
|
|
71
41
|
}
|
|
72
42
|
|
|
73
43
|
export interface DehydratedRouter {
|
|
74
44
|
manifest: Manifest | undefined
|
|
75
|
-
dehydratedData
|
|
76
|
-
lastMatchId
|
|
45
|
+
dehydratedData?: any
|
|
46
|
+
lastMatchId?: string
|
|
47
|
+
matches: Array<DehydratedMatch>
|
|
77
48
|
}
|
|
78
49
|
|
|
79
50
|
export async function hydrate(router: AnyRouter): Promise<any> {
|
|
80
51
|
invariant(
|
|
81
|
-
window
|
|
82
|
-
'Expected to find a dehydrated data on window.
|
|
52
|
+
window.$_TSR?.router,
|
|
53
|
+
'Expected to find a dehydrated data on window.$_TSR.router, but we did not. Please file an issue!',
|
|
83
54
|
)
|
|
84
55
|
|
|
85
|
-
const { manifest, dehydratedData, lastMatchId } =
|
|
86
|
-
window.__TSR_SSR__.dehydrated,
|
|
87
|
-
) as DehydratedRouter
|
|
56
|
+
const { manifest, dehydratedData, lastMatchId } = window.$_TSR.router
|
|
88
57
|
|
|
89
58
|
router.ssr = {
|
|
90
59
|
manifest,
|
|
91
|
-
serializer: tsrSerializer,
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
router.clientSsr = {
|
|
95
|
-
getStreamedValue: <T>(key: string): T | undefined => {
|
|
96
|
-
if (router.isServer) {
|
|
97
|
-
return undefined
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
const streamedValue = window.__TSR_SSR__?.streamedValues[key]
|
|
101
|
-
|
|
102
|
-
if (!streamedValue) {
|
|
103
|
-
return
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
if (!streamedValue.parsed) {
|
|
107
|
-
streamedValue.parsed = router.ssr!.serializer.parse(streamedValue.value)
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
return streamedValue.parsed
|
|
111
|
-
},
|
|
112
60
|
}
|
|
113
61
|
|
|
114
62
|
// Hydrate the router state
|
|
@@ -126,16 +74,15 @@ export async function hydrate(router: AnyRouter): Promise<any> {
|
|
|
126
74
|
// First step is to reyhdrate loaderData and __beforeLoadContext
|
|
127
75
|
let firstNonSsrMatchIndex: number | undefined = undefined
|
|
128
76
|
matches.forEach((match) => {
|
|
129
|
-
const dehydratedMatch = window
|
|
130
|
-
(d) => d.
|
|
77
|
+
const dehydratedMatch = window.$_TSR!.router!.matches.find(
|
|
78
|
+
(d) => d.i === match.id,
|
|
131
79
|
)
|
|
132
|
-
|
|
133
80
|
if (!dehydratedMatch) {
|
|
134
81
|
Object.assign(match, { dehydrated: false, ssr: false })
|
|
135
82
|
return
|
|
136
83
|
}
|
|
137
84
|
|
|
138
|
-
Object.assign(match, dehydratedMatch)
|
|
85
|
+
Object.assign(match, hydrateMatch(dehydratedMatch))
|
|
139
86
|
|
|
140
87
|
if (match.ssr === false) {
|
|
141
88
|
match._dehydrated = false
|
|
@@ -153,30 +100,6 @@ export async function hydrate(router: AnyRouter): Promise<any> {
|
|
|
153
100
|
if (match.ssr === false) {
|
|
154
101
|
return
|
|
155
102
|
}
|
|
156
|
-
|
|
157
|
-
// Handle beforeLoadContext
|
|
158
|
-
if (dehydratedMatch.__beforeLoadContext) {
|
|
159
|
-
match.__beforeLoadContext = router.ssr!.serializer.parse(
|
|
160
|
-
dehydratedMatch.__beforeLoadContext,
|
|
161
|
-
) as any
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// Handle loaderData
|
|
165
|
-
if (dehydratedMatch.loaderData) {
|
|
166
|
-
match.loaderData = router.ssr!.serializer.parse(
|
|
167
|
-
dehydratedMatch.loaderData,
|
|
168
|
-
)
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
// Handle error
|
|
172
|
-
if (dehydratedMatch.error) {
|
|
173
|
-
match.error = router.ssr!.serializer.parse(dehydratedMatch.error)
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
// Handle extracted
|
|
177
|
-
;(match as unknown as SsrMatch).extracted?.forEach((ex) => {
|
|
178
|
-
deepMutableSetByPath(match, ['loaderData', ...ex.path], ex.value)
|
|
179
|
-
})
|
|
180
103
|
})
|
|
181
104
|
|
|
182
105
|
router.__store.setState((s) => {
|
|
@@ -271,21 +194,5 @@ export async function hydrate(router: AnyRouter): Promise<any> {
|
|
|
271
194
|
})
|
|
272
195
|
})
|
|
273
196
|
}
|
|
274
|
-
|
|
275
197
|
return routeChunkPromise
|
|
276
198
|
}
|
|
277
|
-
|
|
278
|
-
function deepMutableSetByPath<T>(obj: T, path: Array<string>, value: any) {
|
|
279
|
-
// mutable set by path retaining array and object references
|
|
280
|
-
if (path.length === 1) {
|
|
281
|
-
;(obj as any)[path[0]!] = value
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
const [key, ...rest] = path
|
|
285
|
-
|
|
286
|
-
if (Array.isArray(obj)) {
|
|
287
|
-
deepMutableSetByPath(obj[Number(key)], rest, value)
|
|
288
|
-
} else if (isPlainObject(obj)) {
|
|
289
|
-
deepMutableSetByPath((obj as any)[key!], rest, value)
|
|
290
|
-
}
|
|
291
|
-
}
|