(
request: Request,
task: Task,
parent:
| {+[key: string | number]: ReactClientValue}
| $ReadOnlyArray<ReactClientValue>,
key: string,
value: ReactClientValue,
)
| 3196 | let modelRoot: null | ReactClientValue = false; |
| 3197 | |
| 3198 | function renderModel( |
| 3199 | request: Request, |
| 3200 | task: Task, |
| 3201 | parent: |
| 3202 | | {+[key: string | number]: ReactClientValue} |
| 3203 | | $ReadOnlyArray<ReactClientValue>, |
| 3204 | key: string, |
| 3205 | value: ReactClientValue, |
| 3206 | ): ReactJSONValue { |
| 3207 | // First time we're serializing the key, we should add it to the size. |
| 3208 | serializedSize += key.length; |
| 3209 | |
| 3210 | const prevKeyPath = task.keyPath; |
| 3211 | const prevImplicitSlot = task.implicitSlot; |
| 3212 | try { |
| 3213 | return renderModelDestructive(request, task, parent, key, value); |
| 3214 | } catch (thrownValue) { |
| 3215 | // If the suspended/errored value was an element or lazy it can be reduced |
| 3216 | // to a lazy reference, so that it doesn't error the parent. |
| 3217 | const model = task.model; |
| 3218 | const wasReactNode = |
| 3219 | typeof model === 'object' && |
| 3220 | model !== null && |
| 3221 | ((model: any).$$typeof === REACT_ELEMENT_TYPE || |
| 3222 | (model: any).$$typeof === REACT_LAZY_TYPE); |
| 3223 | |
| 3224 | if (request.status === ABORTING) { |
| 3225 | task.status = ABORTED; |
| 3226 | if (enableHalt && request.type === PRERENDER) { |
| 3227 | // This will create a new task and refer to it in this slot |
| 3228 | // the new task won't be retried because we are aborting |
| 3229 | return outlineHaltedTask(request, task, wasReactNode); |
| 3230 | } |
| 3231 | const errorId = (request.fatalError: any); |
| 3232 | if (wasReactNode) { |
| 3233 | return serializeLazyID(errorId); |
| 3234 | } |
| 3235 | return serializeByValueID(errorId); |
| 3236 | } |
| 3237 | |
| 3238 | const x = |
| 3239 | thrownValue === SuspenseException |
| 3240 | ? // This is a special type of exception used for Suspense. For historical |
| 3241 | // reasons, the rest of the Suspense implementation expects the thrown |
| 3242 | // value to be a thenable, because before `use` existed that was the |
| 3243 | // (unstable) API for suspending. This implementation detail can change |
| 3244 | // later, once we deprecate the old API in favor of `use`. |
| 3245 | getSuspendedThenable() |
| 3246 | : thrownValue; |
| 3247 | |
| 3248 | if (typeof x === 'object' && x !== null) { |
| 3249 | // $FlowFixMe[method-unbinding] |
| 3250 | if (typeof x.then === 'function') { |
| 3251 | // Something suspended, we'll need to create a new task and resolve it later. |
| 3252 | const newTask = createTask( |
| 3253 | request, |
| 3254 | task.model, |
| 3255 | task.keyPath, |
no test coverage detected