[19.2.x][FlightReply] Don't drop FormData entries in decodeReplyFromBusboy by eps1lon · Pull Request #36566 · react/react (original) (raw)

@unstubbable @eps1lon

…Busboy`

Fixes a regression from react#36425 where referenced FormData entries can be dropped by decodeReplyFromBusboy when files are interleaved with text fields in the payload.

decodeReplyFromBusboy queues text fields that arrive while a file is being streamed and flushes them after the last file's 'end', working around busboy emitting 'end' deferred relative to subsequent 'field' events. With multiple files interleaved with text, this loses the relative order of the affected text entries. The reorder was a long-standing but invisible issue — entries came back in the wrong order but were all present — until react#36425 tightened how referenced FormData entries are collected from the backing store to rely on them being contiguous. With that assumption violated, referenced FormDatas can now come back with some entries dropped. The pattern is most easily surfaced through useActionState actions that return the submitted FormData as part of their state.

This replaces the tail-flush with a linked list of pending files. Text fields that arrive while a file is in flight are queued on the tail file's queuedFields; fields that arrive when the list is empty resolve immediately. flush() walks from the head, resolving each completed file followed by its queued fields, and stops at the first file that hasn't ended yet. The backing FormData now matches the payload's order, restoring the contiguity assumption (and fixing the long-standing reorder as a side effect). The same change is applied to all five copies in react-server-dom-{webpack,turbopack,parcel,esm,unbundled}. Two new tests cover the multi-file interleave.