Skip to content

Commit

Permalink
fix: updated typescript types for React API's
Browse files Browse the repository at this point in the history
  • Loading branch information
wyattjoh committed Sep 24, 2024
1 parent 8271e0a commit 64359df
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 39 deletions.
32 changes: 23 additions & 9 deletions packages/next/src/server/app-render/action-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,8 @@ export async function handleAction({
'Cache-Control',
'no-cache, no-store, max-age=0, must-revalidate'
)
let bound = []

let boundActionArguments: unknown[] = []

const { actionAsyncStorage } = ComponentMod

Expand Down Expand Up @@ -618,14 +619,18 @@ export async function handleAction({
// TODO-APP: Add streaming support
const formData = await req.request.formData()
if (isFetchAction) {
bound = await decodeReply(formData, serverModuleMap)
boundActionArguments = await decodeReply(formData, serverModuleMap)
} else {
const action = await decodeAction(formData, serverModuleMap)
if (typeof action === 'function') {
// Only warn if it's a server action, otherwise skip for other post requests
warnBadServerActionRequest()
const actionReturnedState = await action()
formState = decodeFormState(actionReturnedState, formData)
formState = decodeFormState(
actionReturnedState,
formData,
serverModuleMap
)
}

// Skip the fetch path
Expand Down Expand Up @@ -657,9 +662,12 @@ export async function handleAction({

if (isURLEncodedAction) {
const formData = formDataFromSearchQueryString(actionData)
bound = await decodeReply(formData, serverModuleMap)
boundActionArguments = await decodeReply(formData, serverModuleMap)
} else {
bound = await decodeReply(actionData, serverModuleMap)
boundActionArguments = await decodeReply(
actionData,
serverModuleMap
)
}
}
} else if (
Expand Down Expand Up @@ -721,7 +729,10 @@ export async function handleAction({

body.pipe(busboy)

bound = await decodeReplyFromBusboy(busboy, serverModuleMap)
boundActionArguments = await decodeReplyFromBusboy(
busboy,
serverModuleMap
)
} else {
// React doesn't yet publish a busboy version of decodeAction
// so we polyfill the parsing of FormData.
Expand Down Expand Up @@ -777,9 +788,12 @@ export async function handleAction({

if (isURLEncodedAction) {
const formData = formDataFromSearchQueryString(actionData)
bound = await decodeReply(formData, serverModuleMap)
boundActionArguments = await decodeReply(formData, serverModuleMap)
} else {
bound = await decodeReply(actionData, serverModuleMap)
boundActionArguments = await decodeReply(
actionData,
serverModuleMap
)
}
}
} else {
Expand Down Expand Up @@ -817,7 +831,7 @@ export async function handleAction({
actionId!
]

const returnVal = await actionHandler.apply(null, bound)
const returnVal = await actionHandler.apply(null, boundActionArguments)

// For form actions, we need to continue rendering the page.
if (isFetchAction) {
Expand Down
32 changes: 11 additions & 21 deletions packages/next/src/server/app-render/app-render.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import type { DeepReadonly } from '../../shared/lib/deep-readonly'
import type { BaseNextRequest, BaseNextResponse } from '../base-http'
import type { IncomingHttpHeaders } from 'http'

import React, { type ErrorInfo, type JSX } from 'react'
import React, { type JSX } from 'react'

import RenderResult, {
type AppPageRenderResultMetadata,
Expand Down Expand Up @@ -506,7 +506,6 @@ async function generateDynamicFlightRenderResult(
ctx.clientReferenceManifest.clientModules,
{
onError,
nonce: ctx.nonce,
}
)

Expand Down Expand Up @@ -1380,7 +1379,6 @@ async function renderToStream(
clientReferenceManifest.clientModules,
{
onError: serverComponentsErrorHandler,
nonce: ctx.nonce,
}
)
)
Expand Down Expand Up @@ -1588,7 +1586,6 @@ async function renderToStream(
clientReferenceManifest.clientModules,
{
onError: serverComponentsErrorHandler,
nonce: ctx.nonce,
}
)

Expand Down Expand Up @@ -1829,7 +1826,7 @@ async function prerenderToStream(
ctx,
res.statusCode === 404
)
function voidOnError() {}

;(
prerenderAsyncStorage.run(
// The store to scope
Expand All @@ -1840,9 +1837,8 @@ async function prerenderToStream(
firstAttemptRSCPayload,
clientReferenceManifest.clientModules,
{
nonce: ctx.nonce,
// This render will be thrown away so we don't need to track errors or postpones
onError: voidOnError,
onError: undefined,
onPostpone: undefined,
// we don't care to track postpones during the prospective render because we need
// to always do a final render anyway
Expand Down Expand Up @@ -1874,13 +1870,13 @@ async function prerenderToStream(
}

let reactServerIsDynamic = false
function onError(err: unknown, errorInfo: ErrorInfo) {
function onError(err: unknown) {
if (err === abortReason || isPrerenderInterruptedError(err)) {
reactServerIsDynamic = true
return
}

return serverComponentsErrorHandler(err, errorInfo)
return serverComponentsErrorHandler(err)
}

function onPostpone(reason: string) {
Expand Down Expand Up @@ -1909,7 +1905,6 @@ async function prerenderToStream(
finalAttemptRSCPayload,
clientReferenceManifest.clientModules,
{
nonce: ctx.nonce,
onError,
onPostpone,
signal: flightController.signal,
Expand Down Expand Up @@ -1938,13 +1933,13 @@ async function prerenderToStream(
dynamicTracking,
}
let SSRIsDynamic = false
function SSROnError(err: unknown, errorInfo: unknown) {
function SSROnError(err: unknown) {
if (err === abortReason || isPrerenderInterruptedError(err)) {
SSRIsDynamic = true
return
}

return htmlRendererErrorHandler(err, errorInfo)
return htmlRendererErrorHandler(err)
}

function SSROnPostpone(reason: string) {
Expand Down Expand Up @@ -2109,13 +2104,13 @@ async function prerenderToStream(
let flightController = new AbortController()

let reactServerIsDynamic = false
function onError(err: unknown, errorInfo: ErrorInfo) {
function onError(err: unknown) {
if (err === abortReason || isPrerenderInterruptedError(err)) {
reactServerIsDynamic = true
return
}

return serverComponentsErrorHandler(err, errorInfo)
return serverComponentsErrorHandler(err)
}

dynamicTracking = createDynamicTrackingState(
Expand Down Expand Up @@ -2149,7 +2144,6 @@ async function prerenderToStream(
firstAttemptRSCPayload,
clientReferenceManifest.clientModules,
{
nonce: ctx.nonce,
onError,
signal: flightController.signal,
}
Expand Down Expand Up @@ -2216,7 +2210,6 @@ async function prerenderToStream(
finalAttemptRSCPayload,
clientReferenceManifest.clientModules,
{
nonce: ctx.nonce,
onError,
signal: flightController.signal,
}
Expand Down Expand Up @@ -2254,13 +2247,13 @@ async function prerenderToStream(
dynamicTracking,
}
let SSRIsDynamic = false
function SSROnError(err: unknown, errorInfo: unknown) {
function SSROnError(err: unknown) {
if (err === abortReason || isPrerenderInterruptedError(err)) {
SSRIsDynamic = true
return
}

return htmlRendererErrorHandler(err, errorInfo)
return htmlRendererErrorHandler(err)
}
function SSROnPostpone(_: string) {
// We don't really support postponing when PPR is off but since experimental react
Expand Down Expand Up @@ -2364,7 +2357,6 @@ async function prerenderToStream(
clientReferenceManifest.clientModules,
{
onError: serverComponentsErrorHandler,
nonce: ctx.nonce,
}
)
))
Expand Down Expand Up @@ -2535,7 +2527,6 @@ async function prerenderToStream(
clientReferenceManifest.clientModules,
{
onError: serverComponentsErrorHandler,
nonce: ctx.nonce,
}
)
))
Expand Down Expand Up @@ -2678,7 +2669,6 @@ async function prerenderToStream(
clientReferenceManifest.clientModules,
{
onError: serverComponentsErrorHandler,
nonce: ctx.nonce,
}
)

Expand Down
11 changes: 8 additions & 3 deletions packages/next/src/server/app-render/create-error-handler.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,26 @@ declare global {
var __next_log_error__: undefined | ((err: unknown) => void)
}

type ErrorHandler = (err: unknown, errorInfo: unknown) => string | undefined
type ErrorHandler = (err: unknown, errorInfo?: unknown) => string | undefined

export type DigestedError = Error & { digest: string }

export function createFlightReactServerErrorHandler(
dev: boolean,
onReactServerRenderError: (err: any) => void
): ErrorHandler {
return (err: any, errorInfo: any) => {
return (err: any, errorInfo?: unknown) => {
// If the error already has a digest, respect the original digest,
// so it won't get re-generated into another new error.
if (!err.digest) {
// TODO-APP: look at using webcrypto instead. Requires a promise to be awaited.
err.digest = stringHash(
err.message + (errorInfo?.stack || err.stack || '')
err.message +
(typeof errorInfo === 'object' &&
errorInfo !== null &&
'stack' in errorInfo
? errorInfo.stack
: err.stack || '')
).toString()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ export function renderToInitialFizzStream({
}: {
ReactDOMServer: typeof import('react-dom/server.edge')
element: React.ReactElement
streamOptions?: any
streamOptions?: Parameters<typeof ReactDOMServer.renderToReadableStream>[1]
}): Promise<ReactReadableStream> {
return getTracer().trace(AppRenderSpan.renderToReadableStream, async () =>
ReactDOMServer.renderToReadableStream(element, streamOptions)
Expand Down
71 changes: 69 additions & 2 deletions packages/next/types/$$compiled.internal.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,76 @@ declare module 'next/dist/compiled/react-dom/server.edge'
declare module 'next/dist/compiled/browserslist'

declare module 'react-server-dom-webpack/client'
declare module 'react-server-dom-webpack/server.edge'
declare module 'react-server-dom-webpack/server.edge' {
export function renderToReadableStream(
model: any,
webpackMap: {
readonly [id: string]: {
readonly id: string | number
readonly chunks: readonly string[]
readonly name: string
readonly async?: boolean
}
},
options?: {
filterStackFrame?: (url: string, functionName: string) => boolean
onError?: (error: unknown) => void
onPostpone?: (reason: string) => void
signal?: AbortSignal
}
): ReadableStream<Uint8Array>

type ServerManifest = {}

export function decodeReply<T>(
body: string | FormData,
webpackMap: ServerManifest,
options?: {
temporaryReferences?: unknown
}
): Promise<T>
export function decodeAction<T>(
body: FormData,
serverManifest: ServerManifest
): Promise<() => T> | null
export function decodeFormState<S>(
actionResult: S,
body: FormData,
serverManifest: ServerManifest
): Promise<unknown | null>

export function registerServerReference<T>(
reference: T,
id: string,
exportName: string | null
): unknown

export function createClientModuleProxy(moduleId: string): unknown
}
declare module 'react-server-dom-webpack/server.node'
declare module 'react-server-dom-webpack/static.edge'
declare module 'react-server-dom-webpack/static.edge' {
export function prerender(
children: any,
webpackMap: {
readonly [id: string]: {
readonly id: string | number
readonly chunks: readonly string[]
readonly name: string
readonly async?: boolean
}
},
options?: {
environmentName?: string | (() => string)
filterStackFrame?: (url: string, functionName: string) => boolean
identifierPrefix?: string
signal?: AbortSignal
onError?: (error: unknown) => void
onPostpone?: (reason: string) => void
}
): Promise<{
prelude: ReadableStream<Uint8Array>
}>
}
declare module 'react-server-dom-webpack/client.edge'

declare module 'VAR_MODULE_GLOBAL_ERROR'
Expand Down
6 changes: 3 additions & 3 deletions packages/next/types/react-dom.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ declare module 'react-dom/server.edge' {
export type ResumeOptions = {
nonce?: string
signal?: AbortSignal
onError?: (error: unknown, errorInfo: unknown) => string | undefined
onError?: (error: unknown) => string | undefined
onPostpone?: (reason: string) => void
unstable_externalRuntimeSrc?: string | BootstrapScriptDescriptor
}
Expand All @@ -42,7 +42,7 @@ declare module 'react-dom/server.edge' {
bootstrapModules?: Array<string | BootstrapScriptDescriptor>
progressiveChunkSize?: number
signal?: AbortSignal
onError?: (error: unknown, errorInfo: unknown) => string | undefined
onError?: (error: unknown) => string | undefined
onPostpone?: (reason: string) => void
unstable_externalRuntimeSrc?: string | BootstrapScriptDescriptor
importMap?: {
Expand Down Expand Up @@ -94,7 +94,7 @@ declare module 'react-dom/static.edge' {
bootstrapModules?: Array<string | BootstrapScriptDescriptor>
progressiveChunkSize?: number
signal?: AbortSignal
onError?: (error: unknown, errorInfo: unknown) => string | undefined
onError?: (error: unknown) => string | undefined
onPostpone?: (reason: string) => void
unstable_externalRuntimeSrc?: string | BootstrapScriptDescriptor
importMap?: {
Expand Down

0 comments on commit 64359df

Please sign in to comment.