( request: Request, task: ReplayTask, keyPath: KeyNode, name: null | string, keyOrIndex: number | string, childIndex: number, type: any, props: Object, ref: any, replay: ReplaySet, )
| 3061 | } |
| 3062 | |
| 3063 | function replayElement( |
| 3064 | request: Request, |
| 3065 | task: ReplayTask, |
| 3066 | keyPath: KeyNode, |
| 3067 | name: null | string, |
| 3068 | keyOrIndex: number | string, |
| 3069 | childIndex: number, |
| 3070 | type: any, |
| 3071 | props: Object, |
| 3072 | ref: any, |
| 3073 | replay: ReplaySet, |
| 3074 | ): void { |
| 3075 | // We're replaying. Find the path to follow. |
| 3076 | const replayNodes = replay.nodes; |
| 3077 | for (let i = 0; i < replayNodes.length; i++) { |
| 3078 | // Flow doesn't support refinement on tuples so we do it manually here. |
| 3079 | const node = replayNodes[i]; |
| 3080 | if (keyOrIndex !== node[1]) { |
| 3081 | continue; |
| 3082 | } |
| 3083 | if (node.length === 4) { |
| 3084 | // Matched a replayable path. |
| 3085 | // Let's double check that the component name matches as a precaution. |
| 3086 | if (name !== null && name !== node[0]) { |
| 3087 | throw new Error( |
| 3088 | 'Expected the resume to render <' + |
| 3089 | (node[0]: any) + |
| 3090 | '> in this slot but instead it rendered <' + |
| 3091 | name + |
| 3092 | '>. ' + |
| 3093 | "The tree doesn't match so React will fallback to client rendering.", |
| 3094 | ); |
| 3095 | } |
| 3096 | const childNodes = node[2]; |
| 3097 | const childSlots = node[3]; |
| 3098 | const currentNode = task.node; |
| 3099 | task.replay = {nodes: childNodes, slots: childSlots, pendingTasks: 1}; |
| 3100 | try { |
| 3101 | renderElement(request, task, keyPath, type, props, ref); |
| 3102 | if ( |
| 3103 | task.replay.pendingTasks === 1 && |
| 3104 | task.replay.nodes.length > 0 |
| 3105 | // TODO check remaining slots |
| 3106 | ) { |
| 3107 | throw new Error( |
| 3108 | "Couldn't find all resumable slots by key/index during replaying. " + |
| 3109 | "The tree doesn't match so React will fallback to client rendering.", |
| 3110 | ); |
| 3111 | } |
| 3112 | task.replay.pendingTasks--; |
| 3113 | } catch (x) { |
| 3114 | if ( |
| 3115 | typeof x === 'object' && |
| 3116 | x !== null && |
| 3117 | (x === SuspenseException || typeof x.then === 'function') |
| 3118 | ) { |
| 3119 | // Suspend |
| 3120 | if (task.node === currentNode) { |
no test coverage detected