Skip to content

Commit

Permalink
Merge branch 'canary' into nabsul/typo/fetchType
Browse files Browse the repository at this point in the history
  • Loading branch information
nabsul authored Apr 21, 2023
2 parents 6c531b9 + 658c600 commit c7c35e2
Show file tree
Hide file tree
Showing 60 changed files with 1,055 additions and 358 deletions.
10 changes: 6 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,13 @@
"@types/jest": "24.0.13",
"@types/node": "14.14.31",
"@types/node-fetch": "2.6.1",
"@types/react": "16.9.17",
"@types/react-dom": "16.9.4",
"@types/react": "18.0.37",
"@types/react-dom": "18.0.11",
"@types/relay-runtime": "13.0.0",
"@types/selenium-webdriver": "4.0.15",
"@types/sharp": "0.29.3",
"@types/string-hash": "1.1.1",
"@types/trusted-types": "2.0.2",
"@types/trusted-types": "2.0.3",
"@typescript-eslint/eslint-plugin": "4.29.1",
"@typescript-eslint/parser": "4.29.1",
"@vercel/fetch": "6.1.1",
Expand Down Expand Up @@ -240,7 +240,9 @@
"@babel/core": "7.18.0",
"@babel/parser": "7.18.0",
"@babel/types": "7.18.0",
"@babel/traverse": "7.18.0"
"@babel/traverse": "7.18.0",
"@types/react": "18.0.37",
"@types/react-dom": "18.0.11"
},
"engines": {
"node": ">=14.18.0"
Expand Down
6 changes: 3 additions & 3 deletions packages/next/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -174,9 +174,9 @@
"@types/node-fetch": "2.6.1",
"@types/path-to-regexp": "1.7.0",
"@types/platform": "1.3.4",
"@types/react": "16.9.17",
"@types/react-dom": "16.9.4",
"@types/react-is": "16.7.1",
"@types/react": "18.0.37",
"@types/react-dom": "18.0.11",
"@types/react-is": "17.0.3",
"@types/semver": "7.3.1",
"@types/send": "0.14.4",
"@types/shell-quote": "1.7.1",
Expand Down
5 changes: 3 additions & 2 deletions packages/next/src/client/components/app-router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
ACTION_REFRESH,
ACTION_RESTORE,
ACTION_SERVER_PATCH,
PrefetchKind,
} from './router-reducer/router-reducer-types'
import { createHrefFromUrl } from './router-reducer/create-href-from-url'
import {
Expand Down Expand Up @@ -234,7 +235,7 @@ function Router({
const routerInstance: AppRouterInstance = {
back: () => window.history.back(),
forward: () => window.history.forward(),
prefetch: async (href) => {
prefetch: async (href, options) => {
// If prefetch has already been triggered, don't trigger it again.
if (isBot(window.navigator.userAgent)) {
return
Expand All @@ -244,12 +245,12 @@ function Router({
if (isExternalURL(url)) {
return
}

// @ts-ignore startTransition exists
React.startTransition(() => {
dispatch({
type: ACTION_PREFETCH,
url,
kind: options?.kind ?? PrefetchKind.FULL,
})
})
},
Expand Down
1 change: 1 addition & 0 deletions packages/next/src/client/components/error-boundary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export type ErrorComponent = React.ComponentType<{
}>

export interface ErrorBoundaryProps {
children?: React.ReactNode
errorComponent: ErrorComponent
errorStyles?: React.ReactNode | undefined
}
Expand Down
20 changes: 8 additions & 12 deletions packages/next/src/client/components/layout-router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -277,16 +277,7 @@ function InnerLayoutRouter({
// TODO-APP: verify if this can be null based on user code
childProp.current !== null
) {
if (childNode) {
if (childNode.status === CacheStates.LAZY_INITIALIZED) {
// @ts-expect-error we're changing it's type!
childNode.status = CacheStates.READY
// @ts-expect-error
childNode.subTreeData = childProp.current
// Mutates the prop in order to clean up the memory associated with the subTreeData as it is now part of the cache.
childProp.current = null
}
} else {
if (!childNode) {
// Add the segment's subTreeData to the cache.
// This writes to the cache when there is no item in the cache yet. It never *overwrites* existing cache items which is why it's safe in concurrent mode.
childNodes.set(cacheKey, {
Expand All @@ -295,10 +286,15 @@ function InnerLayoutRouter({
subTreeData: childProp.current,
parallelRoutes: new Map(),
})
// Mutates the prop in order to clean up the memory associated with the subTreeData as it is now part of the cache.
childProp.current = null
// In the above case childNode was set on childNodes, so we have to get it from the cacheNodes again.
childNode = childNodes.get(cacheKey)
} else {
if (childNode.status === CacheStates.LAZY_INITIALIZED) {
// @ts-expect-error we're changing it's type!
childNode.status = CacheStates.READY
// @ts-expect-error
childNode.subTreeData = childProp.current
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import React, {
useEffect,
useReducer,
useMemo,
// @ts-expect-error TODO-APP: startTransition exists
startTransition,
} from 'react'
import stripAnsi from 'next/dist/compiled/strip-ansi'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as React from 'react'
import { useOnClickOutside } from '../../hooks/use-on-click-outside'

export type DialogProps = {
children?: React.ReactNode
type: 'error' | 'warning'
'aria-labelledby': string
'aria-describedby': string
Expand All @@ -15,7 +16,7 @@ const Dialog: React.FC<DialogProps> = function Dialog({
...props
}) {
const [dialog, setDialog] = React.useState<HTMLDivElement | null>(null)
const onDialog = React.useCallback((node) => {
const onDialog = React.useCallback((node: HTMLDivElement | null) => {
setDialog(node)
}, [])
useOnClickOutside(dialog, onClose)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as React from 'react'

export type DialogBodyProps = {
children?: React.ReactNode
className?: string
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as React from 'react'

export type DialogContentProps = {
children?: React.ReactNode
className?: string
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as React from 'react'

export type DialogHeaderProps = {
children?: React.ReactNode
className?: string
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as React from 'react'
import { CloseIcon } from '../../icons/CloseIcon'

export type LeftRightDialogHeaderProps = {
children?: React.ReactNode
className?: string
previous: (() => void) | null
next: (() => void) | null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ import allyTrap from './maintain--tab-focus'
import * as React from 'react'
import { lock, unlock } from './body-locker'

export type OverlayProps = { className?: string; fixed?: boolean }
export type OverlayProps = {
children?: React.ReactNode
className?: string
fixed?: boolean
}

const Overlay: React.FC<OverlayProps> = function Overlay({
className,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as React from 'react'

export type ToastProps = {
children?: React.ReactNode
onClick?: (ev: React.MouseEvent<HTMLDivElement, MouseEvent>) => void
className?: string
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export function useWebsocket(assetPrefix: string) {

export function useSendMessage(webSocketRef: ReturnType<typeof useWebsocket>) {
const sendMessage = useCallback(
(data) => {
(data: string) => {
const socket = webSocketRef.current
if (!socket || socket.readyState !== socket.OPEN) {
return
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export function applyFlightData(
existingCache: CacheNode,
cache: CacheNode,
flightDataPath: FlightDataPath,
wasPrefetched?: boolean
wasPrefetched: boolean = false
): boolean {
// The one before last item is the router state tree patch
const [treePatch, subTreeData, head] = flightDataPath.slice(-3)
Expand All @@ -33,7 +33,12 @@ export function applyFlightData(
cache.subTreeData = existingCache.subTreeData
cache.parallelRoutes = new Map(existingCache.parallelRoutes)
// Create a copy of the existing cache with the subTreeData applied.
fillCacheWithNewSubTreeData(cache, existingCache, flightDataPath)
fillCacheWithNewSubTreeData(
cache,
existingCache,
flightDataPath,
wasPrefetched
)
}

return true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
} from '../app-router-headers'
import { urlToUrlWithoutFlightMarker } from '../app-router'
import { callServer } from '../../app-call-server'
import { PrefetchKind } from './router-reducer-types'

/**
* Fetch the flight data for the provided url. Takes in the current router state to decide what to render server-side.
Expand All @@ -23,7 +24,7 @@ export async function fetchServerResponse(
url: URL,
flightRouterState: FlightRouterState,
nextUrl: string | null,
prefetch?: true
prefetchKind?: PrefetchKind
): Promise<[FlightData: FlightData, canonicalUrlOverride: URL | undefined]> {
const headers: {
[RSC]: '1'
Expand All @@ -36,8 +37,14 @@ export async function fetchServerResponse(
// Provide the current router state
[NEXT_ROUTER_STATE_TREE]: JSON.stringify(flightRouterState),
}
if (prefetch) {
// Enable prefetch response

/**
* Three cases:
* - `prefetchKind` is `undefined`, it means it's a normal navigation, so we want to prefetch the page data fully
* - `prefetchKind` is `full` - we want to prefetch the whole page so same as above
* - `prefetchKind` is `auto` - if the page is dynamic, prefetch the page data partially, if static prefetch the page data fully
*/
if (prefetchKind === PrefetchKind.AUTO) {
headers[NEXT_ROUTER_PREFETCH] = '1'
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { FlightSegmentPath } from '../../../server/app-render/types'
import { CacheNode, CacheStates } from '../../../shared/lib/app-router-context'
import { createRouterCacheKey } from './create-router-cache-key'
import { fetchServerResponse } from './fetch-server-response'

/**
Expand All @@ -7,19 +9,24 @@ import { fetchServerResponse } from './fetch-server-response'
export function fillCacheWithDataProperty(
newCache: CacheNode,
existingCache: CacheNode,
segments: string[],
fetchResponse: () => ReturnType<typeof fetchServerResponse>
flightSegmentPath: FlightSegmentPath,
fetchResponse: () => ReturnType<typeof fetchServerResponse>,
bailOnParallelRoutes: boolean = false
): { bailOptimistic: boolean } | undefined {
const isLastEntry = segments.length === 1
const isLastEntry = flightSegmentPath.length <= 2

const parallelRouteKey = 'children'
const [segment] = segments
const [parallelRouteKey, segment] = flightSegmentPath
const cacheKey = createRouterCacheKey(segment)

const existingChildSegmentMap =
existingCache.parallelRoutes.get(parallelRouteKey)

if (!existingChildSegmentMap) {
if (
!existingChildSegmentMap ||
(bailOnParallelRoutes && existingCache.parallelRoutes.size > 1)
) {
// Bailout because the existing cache does not have the path to the leaf node
// or the existing cache has multiple parallel routes
// Will trigger lazy fetch in layout-router because of missing segment
return { bailOptimistic: true }
}
Expand All @@ -31,8 +38,8 @@ export function fillCacheWithDataProperty(
newCache.parallelRoutes.set(parallelRouteKey, childSegmentMap)
}

const existingChildCacheNode = existingChildSegmentMap.get(segment)
let childCacheNode = childSegmentMap.get(segment)
const existingChildCacheNode = existingChildSegmentMap.get(cacheKey)
let childCacheNode = childSegmentMap.get(cacheKey)

// In case of last segment start off the fetch at this level and don't copy further down.
if (isLastEntry) {
Expand All @@ -41,7 +48,7 @@ export function fillCacheWithDataProperty(
!childCacheNode.data ||
childCacheNode === existingChildCacheNode
) {
childSegmentMap.set(segment, {
childSegmentMap.set(cacheKey, {
status: CacheStates.DATA_FETCH,
data: fetchResponse(),
subTreeData: null,
Expand All @@ -54,7 +61,7 @@ export function fillCacheWithDataProperty(
if (!childCacheNode || !existingChildCacheNode) {
// Start fetch in the place where the existing cache doesn't have the data yet.
if (!childCacheNode) {
childSegmentMap.set(segment, {
childSegmentMap.set(cacheKey, {
status: CacheStates.DATA_FETCH,
data: fetchResponse(),
subTreeData: null,
Expand All @@ -71,13 +78,13 @@ export function fillCacheWithDataProperty(
subTreeData: childCacheNode.subTreeData,
parallelRoutes: new Map(childCacheNode.parallelRoutes),
} as CacheNode
childSegmentMap.set(segment, childCacheNode)
childSegmentMap.set(cacheKey, childCacheNode)
}

return fillCacheWithDataProperty(
childCacheNode,
existingChildCacheNode,
segments.slice(1),
flightSegmentPath.slice(2),
fetchResponse
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ describe('fillCacheWithNewSubtreeData', () => {
// Mirrors the way router-reducer values are passed in.
const flightDataPath = flightData[0]

fillCacheWithNewSubTreeData(cache, existingCache, flightDataPath)
fillCacheWithNewSubTreeData(cache, existingCache, flightDataPath, false)

const expectedCache: CacheNode = {
data: null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import { createRouterCacheKey } from './create-router-cache-key'
export function fillCacheWithNewSubTreeData(
newCache: CacheNode,
existingCache: CacheNode,
flightDataPath: FlightDataPath
flightDataPath: FlightDataPath,
wasPrefetched?: boolean
): void {
const isLastEntry = flightDataPath.length <= 5
const [parallelRouteKey, segment] = flightDataPath
Expand Down Expand Up @@ -63,7 +64,8 @@ export function fillCacheWithNewSubTreeData(
childCacheNode,
existingChildCacheNode,
flightDataPath[2],
flightDataPath[4]
flightDataPath[4],
wasPrefetched
)

childSegmentMap.set(cacheKey, childCacheNode)
Expand All @@ -90,6 +92,7 @@ export function fillCacheWithNewSubTreeData(
fillCacheWithNewSubTreeData(
childCacheNode,
existingChildCacheNode,
flightDataPath.slice(2)
flightDataPath.slice(2),
wasPrefetched
)
}
Loading

0 comments on commit c7c35e2

Please sign in to comment.