@tanstack/react-start-client 1.167.4 → 1.168.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/esm/GenericHydrate.d.ts +3 -0
- package/dist/esm/GenericHydrate.js +243 -0
- package/dist/esm/GenericHydrate.js.map +1 -0
- package/dist/esm/Hydrate.d.ts +31 -0
- package/dist/esm/Hydrate.js +34 -0
- package/dist/esm/Hydrate.js.map +1 -0
- package/dist/esm/hydration/generic.d.ts +7 -0
- package/dist/esm/hydration/generic.js +20 -0
- package/dist/esm/hydration/generic.js.map +1 -0
- package/dist/esm/hydration/idle.d.ts +3 -0
- package/dist/esm/hydration/idle.js +12 -0
- package/dist/esm/hydration/idle.js.map +1 -0
- package/dist/esm/hydration/load.d.ts +5 -0
- package/dist/esm/hydration/load.js +33 -0
- package/dist/esm/hydration/load.js.map +1 -0
- package/dist/esm/hydration/never.d.ts +4 -0
- package/dist/esm/hydration/never.js +56 -0
- package/dist/esm/hydration/never.js.map +1 -0
- package/dist/esm/hydration/visible.d.ts +5 -0
- package/dist/esm/hydration/visible.js +94 -0
- package/dist/esm/hydration/visible.js.map +1 -0
- package/dist/esm/hydration.d.ts +7 -0
- package/dist/esm/hydration.js +7 -0
- package/dist/esm/index.d.ts +2 -0
- package/dist/esm/index.js +3 -1
- package/dist/esm/tests/Hydrate.test-d.d.ts +1 -0
- package/dist/esm/tests/Hydrate.test.d.ts +1 -0
- package/package.json +10 -4
- package/src/GenericHydrate.tsx +436 -0
- package/src/Hydrate.tsx +107 -0
- package/src/hydration/generic.ts +43 -0
- package/src/hydration/idle.ts +22 -0
- package/src/hydration/load.tsx +49 -0
- package/src/hydration/never.tsx +97 -0
- package/src/hydration/visible.tsx +139 -0
- package/src/hydration.ts +22 -0
- package/src/index.tsx +16 -0
- package/src/tests/Hydrate.test-d.tsx +147 -0
- package/src/tests/Hydrate.test.tsx +676 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import * as React from 'react'
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
load as coreLoad,
|
|
7
|
+
withHydrationRenderer,
|
|
8
|
+
} from '@tanstack/start-client-core/hydration'
|
|
9
|
+
import type { HydrationPrefetchStrategy } from '@tanstack/start-client-core/hydration'
|
|
10
|
+
import type { HydrateProps, ReactHydrationStrategy } from '../Hydrate'
|
|
11
|
+
|
|
12
|
+
function HydratedBoundary(props: {
|
|
13
|
+
onHydrated?: () => void
|
|
14
|
+
children: React.ReactNode
|
|
15
|
+
}) {
|
|
16
|
+
const { onHydrated, children } = props
|
|
17
|
+
const didHydrateRef = React.useRef(false)
|
|
18
|
+
|
|
19
|
+
React.useEffect(() => {
|
|
20
|
+
if (didHydrateRef.current) return
|
|
21
|
+
didHydrateRef.current = true
|
|
22
|
+
onHydrated?.()
|
|
23
|
+
}, [onHydrated])
|
|
24
|
+
|
|
25
|
+
return children as React.JSX.Element
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function LoadHydrate(props: HydrateProps): React.JSX.Element {
|
|
29
|
+
return (
|
|
30
|
+
<div>
|
|
31
|
+
<React.Suspense fallback={props.fallback ?? null}>
|
|
32
|
+
<HydratedBoundary onHydrated={props.onHydrated}>
|
|
33
|
+
{props.children}
|
|
34
|
+
</HydratedBoundary>
|
|
35
|
+
</React.Suspense>
|
|
36
|
+
</div>
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const loadStrategy = /* @__PURE__ */ withHydrationRenderer(
|
|
41
|
+
coreLoad(),
|
|
42
|
+
LoadHydrate,
|
|
43
|
+
) as ReactHydrationStrategy<'load', true> & HydrationPrefetchStrategy<'load'>
|
|
44
|
+
|
|
45
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
46
|
+
export function load(): ReactHydrationStrategy<'load', true> &
|
|
47
|
+
HydrationPrefetchStrategy<'load'> {
|
|
48
|
+
return loadStrategy
|
|
49
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import * as React from 'react'
|
|
4
|
+
|
|
5
|
+
import { reactUse, useHydrated } from '@tanstack/react-router'
|
|
6
|
+
import { isServer } from '@tanstack/router-core/isServer'
|
|
7
|
+
import {
|
|
8
|
+
never as coreNever,
|
|
9
|
+
withHydrationRenderer,
|
|
10
|
+
} from '@tanstack/start-client-core/hydration'
|
|
11
|
+
import {
|
|
12
|
+
hydrateIdAttribute,
|
|
13
|
+
hydrateWhenAttribute,
|
|
14
|
+
} from '@tanstack/start-client-core/hydration/constants'
|
|
15
|
+
import {
|
|
16
|
+
getFallbackHtml,
|
|
17
|
+
saveFallbackHtml,
|
|
18
|
+
} from '@tanstack/start-client-core/hydration/runtime'
|
|
19
|
+
import type {
|
|
20
|
+
HydrateProps,
|
|
21
|
+
InternalHydrateProps,
|
|
22
|
+
ReactHydrationStrategy,
|
|
23
|
+
} from '../Hydrate'
|
|
24
|
+
|
|
25
|
+
const neverType = 'never'
|
|
26
|
+
const neverPromise = new Promise<void>(() => {})
|
|
27
|
+
|
|
28
|
+
function NeverGate(props: { children: React.ReactNode }) {
|
|
29
|
+
if (
|
|
30
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
31
|
+
isServer ??
|
|
32
|
+
typeof window === 'undefined'
|
|
33
|
+
) {
|
|
34
|
+
return props.children as React.JSX.Element
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (!reactUse) {
|
|
38
|
+
throw neverPromise
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
reactUse(neverPromise)
|
|
42
|
+
|
|
43
|
+
return props.children as React.JSX.Element
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function NeverHydrate(props: HydrateProps): React.JSX.Element {
|
|
47
|
+
const internalProps = props as InternalHydrateProps
|
|
48
|
+
const hydrated = useHydrated()
|
|
49
|
+
const reactId = React.useId()
|
|
50
|
+
const id = internalProps.h ? `${internalProps.h}${reactId}` : reactId
|
|
51
|
+
const shouldPreserveServerHTMLRef = React.useRef<boolean | undefined>(
|
|
52
|
+
undefined,
|
|
53
|
+
)
|
|
54
|
+
shouldPreserveServerHTMLRef.current ??=
|
|
55
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
56
|
+
(isServer ?? typeof window === 'undefined') || !hydrated
|
|
57
|
+
const markerRef = React.useCallback(
|
|
58
|
+
(element: HTMLDivElement | null) => {
|
|
59
|
+
if (!element) return
|
|
60
|
+
if (!shouldPreserveServerHTMLRef.current) {
|
|
61
|
+
element.replaceChildren()
|
|
62
|
+
} else {
|
|
63
|
+
saveFallbackHtml(id, element)
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
[id],
|
|
67
|
+
)
|
|
68
|
+
const markerProps = {
|
|
69
|
+
ref: markerRef,
|
|
70
|
+
[hydrateIdAttribute]: id,
|
|
71
|
+
[hydrateWhenAttribute]: neverType,
|
|
72
|
+
}
|
|
73
|
+
const fallback = (() => {
|
|
74
|
+
const html = getFallbackHtml(id)
|
|
75
|
+
return html ? (
|
|
76
|
+
<div
|
|
77
|
+
style={{ display: 'contents' }}
|
|
78
|
+
dangerouslySetInnerHTML={{ __html: html }}
|
|
79
|
+
/>
|
|
80
|
+
) : (
|
|
81
|
+
(props.fallback ?? null)
|
|
82
|
+
)
|
|
83
|
+
})()
|
|
84
|
+
|
|
85
|
+
return (
|
|
86
|
+
<div {...markerProps}>
|
|
87
|
+
<React.Suspense fallback={fallback}>
|
|
88
|
+
<NeverGate>{props.children}</NeverGate>
|
|
89
|
+
</React.Suspense>
|
|
90
|
+
</div>
|
|
91
|
+
)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
95
|
+
export function never(): ReactHydrationStrategy<'never', false> {
|
|
96
|
+
return /* @__PURE__ */ withHydrationRenderer(coreNever(), NeverHydrate)
|
|
97
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import * as React from 'react'
|
|
4
|
+
|
|
5
|
+
import { reactUse } from '@tanstack/react-router'
|
|
6
|
+
import { isServer } from '@tanstack/router-core/isServer'
|
|
7
|
+
import type {
|
|
8
|
+
HydrationPrefetchStrategy,
|
|
9
|
+
VisibleHydrationOptions,
|
|
10
|
+
} from '@tanstack/start-client-core/hydration'
|
|
11
|
+
import type {
|
|
12
|
+
HydrateProps,
|
|
13
|
+
InternalHydrateProps,
|
|
14
|
+
ReactHydrationStrategy,
|
|
15
|
+
} from '../Hydrate'
|
|
16
|
+
|
|
17
|
+
type VisibleGate = {
|
|
18
|
+
p: Promise<void>
|
|
19
|
+
r: boolean
|
|
20
|
+
s: () => void
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
24
|
+
function HydrationBoundary(props: {
|
|
25
|
+
g: VisibleGate
|
|
26
|
+
o?: () => void
|
|
27
|
+
children?: React.ReactNode
|
|
28
|
+
}) {
|
|
29
|
+
const { g, o } = props
|
|
30
|
+
|
|
31
|
+
if (!g.r) {
|
|
32
|
+
if (!reactUse) {
|
|
33
|
+
throw g.p
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
reactUse(g.p)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
React.useEffect(() => {
|
|
40
|
+
o?.()
|
|
41
|
+
}, [o])
|
|
42
|
+
|
|
43
|
+
return props.children as React.JSX.Element
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
47
|
+
export function VisibleHydrate(
|
|
48
|
+
this: ReactHydrationStrategy,
|
|
49
|
+
props: HydrateProps,
|
|
50
|
+
): React.JSX.Element {
|
|
51
|
+
const strategy = this as ReactHydrationStrategy<'visible', true>
|
|
52
|
+
const prefetchStrategy = props.prefetch
|
|
53
|
+
const preload = (props as InternalHydrateProps).p
|
|
54
|
+
const markerRef = React.useRef<HTMLDivElement | null>(null)
|
|
55
|
+
const [gate] = React.useState<VisibleGate>(() => {
|
|
56
|
+
let resolvePromise!: () => void
|
|
57
|
+
const nextGate: VisibleGate = {
|
|
58
|
+
p: new Promise<void>((resolve) => {
|
|
59
|
+
resolvePromise = resolve
|
|
60
|
+
}),
|
|
61
|
+
r: false,
|
|
62
|
+
s: () => {
|
|
63
|
+
nextGate.r = true
|
|
64
|
+
resolvePromise()
|
|
65
|
+
},
|
|
66
|
+
}
|
|
67
|
+
if (
|
|
68
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
69
|
+
isServer ??
|
|
70
|
+
typeof window === 'undefined'
|
|
71
|
+
) {
|
|
72
|
+
nextGate.s()
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return nextGate
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
React.useEffect(() => {
|
|
79
|
+
if (!preload || typeof prefetchStrategy === 'function') {
|
|
80
|
+
return
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return prefetchStrategy?._s?.({
|
|
84
|
+
element: markerRef.current,
|
|
85
|
+
prefetch: preload,
|
|
86
|
+
})
|
|
87
|
+
}, [prefetchStrategy, preload])
|
|
88
|
+
|
|
89
|
+
React.useEffect(() => {
|
|
90
|
+
if (gate.r) return
|
|
91
|
+
|
|
92
|
+
return strategy._s?.({
|
|
93
|
+
element: markerRef.current,
|
|
94
|
+
gate: gate as never,
|
|
95
|
+
})
|
|
96
|
+
}, [gate, strategy])
|
|
97
|
+
|
|
98
|
+
return (
|
|
99
|
+
<div ref={markerRef}>
|
|
100
|
+
<React.Suspense fallback={props.fallback}>
|
|
101
|
+
<HydrationBoundary g={gate} o={props.onHydrated}>
|
|
102
|
+
{props.children}
|
|
103
|
+
</HydrationBoundary>
|
|
104
|
+
</React.Suspense>
|
|
105
|
+
</div>
|
|
106
|
+
)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
110
|
+
export function visible(
|
|
111
|
+
options?: VisibleHydrationOptions,
|
|
112
|
+
): ReactHydrationStrategy<'visible', true> &
|
|
113
|
+
HydrationPrefetchStrategy<'visible'> {
|
|
114
|
+
const rootMargin = options?.rootMargin ?? '600px'
|
|
115
|
+
const threshold = options?.threshold ?? 0
|
|
116
|
+
|
|
117
|
+
return {
|
|
118
|
+
_s: ({ element, gate, prefetch }) => {
|
|
119
|
+
const callback = prefetch || (gate as never as VisibleGate).s
|
|
120
|
+
|
|
121
|
+
if (!element) {
|
|
122
|
+
callback()
|
|
123
|
+
return
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const observer = new IntersectionObserver(
|
|
127
|
+
(entries) => {
|
|
128
|
+
if (!entries[0]!.isIntersecting) return
|
|
129
|
+
observer.disconnect()
|
|
130
|
+
callback()
|
|
131
|
+
},
|
|
132
|
+
{ rootMargin, threshold },
|
|
133
|
+
)
|
|
134
|
+
observer.observe(element)
|
|
135
|
+
return () => observer.disconnect()
|
|
136
|
+
},
|
|
137
|
+
_h: VisibleHydrate,
|
|
138
|
+
}
|
|
139
|
+
}
|
package/src/hydration.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
export { condition, interaction, media } from './hydration/generic'
|
|
4
|
+
export { idle } from './hydration/idle'
|
|
5
|
+
export { load } from './hydration/load'
|
|
6
|
+
export { never } from './hydration/never'
|
|
7
|
+
export { visible } from './hydration/visible'
|
|
8
|
+
export type {
|
|
9
|
+
HydrationCondition,
|
|
10
|
+
HydrationInteractionEvent,
|
|
11
|
+
HydrationInteractionEvents,
|
|
12
|
+
IdleHydrationOptions,
|
|
13
|
+
HydrationPrefetchContext,
|
|
14
|
+
HydrationPrefetchFunction,
|
|
15
|
+
HydrationPrefetchWhen,
|
|
16
|
+
HydrationPrefetchStrategy,
|
|
17
|
+
HydrationPrefetchWaitReason,
|
|
18
|
+
HydrationStrategyTypes,
|
|
19
|
+
HydrationWhen,
|
|
20
|
+
VisibleHydrationOptions,
|
|
21
|
+
} from '@tanstack/start-client-core/hydration'
|
|
22
|
+
export type { HydrationStrategy, ReactHydrationStrategy } from './Hydrate'
|
package/src/index.tsx
CHANGED
|
@@ -1,2 +1,18 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
1
3
|
export { StartClient } from './StartClient'
|
|
2
4
|
export { hydrateStart } from './hydrateStart'
|
|
5
|
+
export { Hydrate } from './Hydrate'
|
|
6
|
+
export type {
|
|
7
|
+
HydrateOptions,
|
|
8
|
+
HydrateProps,
|
|
9
|
+
HydrateWhen,
|
|
10
|
+
HydrationInteractionEvent,
|
|
11
|
+
HydrationInteractionEvents,
|
|
12
|
+
HydrationPrefetchContext,
|
|
13
|
+
HydrationPrefetchFunction,
|
|
14
|
+
HydrationPrefetchStrategy,
|
|
15
|
+
HydrationPrefetchWaitReason,
|
|
16
|
+
HydrationStrategy,
|
|
17
|
+
HydrationWhen,
|
|
18
|
+
} from './Hydrate'
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { expectTypeOf, test } from 'vitest'
|
|
2
|
+
import { visible } from '../hydration'
|
|
3
|
+
import { Hydrate } from '../Hydrate'
|
|
4
|
+
import type {
|
|
5
|
+
HydrateOptions,
|
|
6
|
+
HydrateProps,
|
|
7
|
+
HydrationPrefetchFunction,
|
|
8
|
+
HydrationPrefetchStrategy,
|
|
9
|
+
HydrationStrategy,
|
|
10
|
+
} from '../Hydrate'
|
|
11
|
+
import type { HydrationStrategy as CoreHydrationStrategy } from '@tanstack/start-client-core/hydration'
|
|
12
|
+
import type { ReactNode } from 'react'
|
|
13
|
+
|
|
14
|
+
type CommonHydrateProps = {
|
|
15
|
+
fallback?: ReactNode
|
|
16
|
+
onHydrated?: () => void
|
|
17
|
+
children: ReactNode
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
type SplitHydrateProps = CommonHydrateProps & {
|
|
21
|
+
when: HydrationStrategy | (() => HydrationStrategy)
|
|
22
|
+
prefetch?: never
|
|
23
|
+
split?: boolean
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
type PrefetchHydrateProps = CommonHydrateProps & {
|
|
27
|
+
when: HydrationStrategy | (() => HydrationStrategy)
|
|
28
|
+
prefetch: HydrationPrefetchStrategy
|
|
29
|
+
split?: true
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
type FunctionPrefetchHydrateProps = CommonHydrateProps & {
|
|
33
|
+
when: HydrationStrategy | (() => HydrationStrategy)
|
|
34
|
+
prefetch: HydrationPrefetchFunction
|
|
35
|
+
split?: boolean
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
test('Hydrate component accepts the public HydrateProps type', () => {
|
|
39
|
+
expectTypeOf(Hydrate).toBeFunction()
|
|
40
|
+
expectTypeOf(Hydrate).parameter(0).branded.toEqualTypeOf<HydrateProps>()
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
test('HydrateOptions supports reusable spread props', () => {
|
|
44
|
+
const belowFoldProps = {
|
|
45
|
+
when: () => visible({ rootMargin: '800px' }),
|
|
46
|
+
} satisfies HydrateOptions
|
|
47
|
+
|
|
48
|
+
expectTypeOf(belowFoldProps).toMatchTypeOf<HydrateOptions>()
|
|
49
|
+
|
|
50
|
+
const withFunctionPrefetch = {
|
|
51
|
+
when: visible(),
|
|
52
|
+
split: false,
|
|
53
|
+
prefetch: (ctx) => {
|
|
54
|
+
expectTypeOf(ctx.element).toEqualTypeOf<Element | null>()
|
|
55
|
+
expectTypeOf(ctx.signal).toEqualTypeOf<AbortSignal>()
|
|
56
|
+
expectTypeOf(ctx.preload).returns.toEqualTypeOf<Promise<void>>()
|
|
57
|
+
expectTypeOf(ctx.waitFor).returns.toEqualTypeOf<
|
|
58
|
+
Promise<'prefetch' | 'hydrate' | 'abort'>
|
|
59
|
+
>()
|
|
60
|
+
},
|
|
61
|
+
} satisfies HydrateOptions
|
|
62
|
+
|
|
63
|
+
expectTypeOf(withFunctionPrefetch).toMatchTypeOf<HydrateOptions>()
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
test('Hydrate props are exact for strategy and prefetch forms', () => {
|
|
67
|
+
expectTypeOf<
|
|
68
|
+
Extract<HydrateProps, { prefetch?: never }>
|
|
69
|
+
>().branded.toEqualTypeOf<SplitHydrateProps>()
|
|
70
|
+
expectTypeOf<
|
|
71
|
+
Extract<HydrateProps, { prefetch: HydrationPrefetchStrategy }>
|
|
72
|
+
>().branded.toEqualTypeOf<PrefetchHydrateProps>()
|
|
73
|
+
expectTypeOf<
|
|
74
|
+
Extract<HydrateProps, { prefetch: HydrationPrefetchFunction }>
|
|
75
|
+
>().branded.toEqualTypeOf<FunctionPrefetchHydrateProps>()
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
test('Hydrate requires a strategy', () => {
|
|
79
|
+
expectTypeOf<{
|
|
80
|
+
when: HydrationStrategy
|
|
81
|
+
children: ReactNode
|
|
82
|
+
}>().toMatchTypeOf<HydrateProps>()
|
|
83
|
+
|
|
84
|
+
expectTypeOf<{
|
|
85
|
+
when: () => HydrationStrategy
|
|
86
|
+
children: ReactNode
|
|
87
|
+
}>().toMatchTypeOf<HydrateProps>()
|
|
88
|
+
|
|
89
|
+
expectTypeOf<{
|
|
90
|
+
children: ReactNode
|
|
91
|
+
}>().not.toMatchTypeOf<HydrateProps>()
|
|
92
|
+
|
|
93
|
+
expectTypeOf<{
|
|
94
|
+
when: () => true
|
|
95
|
+
children: ReactNode
|
|
96
|
+
}>().not.toMatchTypeOf<HydrateProps>()
|
|
97
|
+
|
|
98
|
+
expectTypeOf<{
|
|
99
|
+
when: false
|
|
100
|
+
children: ReactNode
|
|
101
|
+
}>().not.toMatchTypeOf<HydrateProps>()
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
test('Hydrate requires a framework-renderable strategy', () => {
|
|
105
|
+
expectTypeOf<CoreHydrationStrategy>().not.toMatchTypeOf<HydrationStrategy>()
|
|
106
|
+
expectTypeOf<ReturnType<typeof visible>>().toMatchTypeOf<HydrationStrategy>()
|
|
107
|
+
|
|
108
|
+
expectTypeOf<{
|
|
109
|
+
when: CoreHydrationStrategy
|
|
110
|
+
children: ReactNode
|
|
111
|
+
}>().not.toMatchTypeOf<HydrateProps>()
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
test('Hydrate enforces prefetch only with split boundaries', () => {
|
|
115
|
+
expectTypeOf<{
|
|
116
|
+
when: HydrationStrategy
|
|
117
|
+
prefetch: HydrationPrefetchStrategy
|
|
118
|
+
children: ReactNode
|
|
119
|
+
}>().toMatchTypeOf<HydrateProps>()
|
|
120
|
+
|
|
121
|
+
expectTypeOf<{
|
|
122
|
+
when: HydrationStrategy
|
|
123
|
+
prefetch: HydrationPrefetchStrategy
|
|
124
|
+
split: true
|
|
125
|
+
children: ReactNode
|
|
126
|
+
}>().toMatchTypeOf<HydrateProps>()
|
|
127
|
+
|
|
128
|
+
expectTypeOf<{
|
|
129
|
+
when: HydrationStrategy
|
|
130
|
+
prefetch: HydrationPrefetchStrategy
|
|
131
|
+
split: false
|
|
132
|
+
children: ReactNode
|
|
133
|
+
}>().not.toMatchTypeOf<HydrateProps>()
|
|
134
|
+
|
|
135
|
+
expectTypeOf<{
|
|
136
|
+
when: HydrationStrategy
|
|
137
|
+
prefetch: HydrationPrefetchFunction
|
|
138
|
+
split: false
|
|
139
|
+
children: ReactNode
|
|
140
|
+
}>().toMatchTypeOf<HydrateProps>()
|
|
141
|
+
|
|
142
|
+
expectTypeOf<{
|
|
143
|
+
when: HydrationStrategy
|
|
144
|
+
prefetch: HydrationPrefetchFunction
|
|
145
|
+
children: ReactNode
|
|
146
|
+
}>().toMatchTypeOf<HydrateProps>()
|
|
147
|
+
})
|