( request: Request, task: Task, iterable: $AsyncIterable<ReactClientValue, ReactClientValue, void>, iterator: $AsyncIterator<ReactClientValue, ReactClientValue, void>, )
| 1189 | } |
| 1190 | |
| 1191 | function serializeAsyncIterable( |
| 1192 | request: Request, |
| 1193 | task: Task, |
| 1194 | iterable: $AsyncIterable<ReactClientValue, ReactClientValue, void>, |
| 1195 | iterator: $AsyncIterator<ReactClientValue, ReactClientValue, void>, |
| 1196 | ): string { |
| 1197 | // Generators/Iterators are Iterables but they're also their own iterator |
| 1198 | // functions. If that's the case, we treat them as single-shot. Otherwise, |
| 1199 | // we assume that this iterable might be a multi-shot and allow it to be |
| 1200 | // iterated more than once on the client. |
| 1201 | const isIterator = iterable === iterator; |
| 1202 | |
| 1203 | // This task won't actually be retried. We just use it to attempt synchronous renders. |
| 1204 | const streamTask = createTask( |
| 1205 | request, |
| 1206 | task.model, |
| 1207 | task.keyPath, |
| 1208 | task.implicitSlot, |
| 1209 | task.formatContext, |
| 1210 | request.abortableTasks, |
| 1211 | enableProfilerTimer && |
| 1212 | (enableComponentPerformanceTrack || enableAsyncDebugInfo) |
| 1213 | ? task.time |
| 1214 | : 0, |
| 1215 | __DEV__ ? task.debugOwner : null, |
| 1216 | __DEV__ ? task.debugStack : null, |
| 1217 | __DEV__ ? task.debugTask : null, |
| 1218 | ); |
| 1219 | |
| 1220 | if (__DEV__) { |
| 1221 | const debugInfo: ?ReactDebugInfo = (iterable: any)._debugInfo; |
| 1222 | if (debugInfo) { |
| 1223 | forwardDebugInfo(request, streamTask, debugInfo); |
| 1224 | } |
| 1225 | } |
| 1226 | |
| 1227 | // The task represents the Stop row. This adds a Start row. |
| 1228 | request.pendingChunks++; |
| 1229 | const startStreamRow = |
| 1230 | streamTask.id.toString(16) + ':' + (isIterator ? 'x' : 'X') + '\n'; |
| 1231 | request.completedRegularChunks.push(stringToChunk(startStreamRow)); |
| 1232 | |
| 1233 | function progress( |
| 1234 | entry: |
| 1235 | | {done: false, +value: ReactClientValue, ...} |
| 1236 | | {done: true, +value: ReactClientValue, ...}, |
| 1237 | ) { |
| 1238 | if (streamTask.status !== PENDING) { |
| 1239 | return; |
| 1240 | } |
| 1241 | |
| 1242 | if (entry.done) { |
| 1243 | streamTask.status = COMPLETED; |
| 1244 | let endStreamRow; |
| 1245 | if (entry.value === undefined) { |
| 1246 | endStreamRow = streamTask.id.toString(16) + ':C\n'; |
| 1247 | } else { |
| 1248 | // Unlike streams, the last value may not be undefined. If it's not |
no test coverage detected