Repository navigation
feat(web): send files anywhere in rich server function arguments - #4208
Conversation
With enableRichArguments(), a call whose arguments hold files or blobs used to fail before sending, unless the file was the only argument or the last one. Ports solidjs/solid-start#2359 to the core transport. - The rich-args encoder finds each file with a seroval plugin made for the call, wherever the codec meets it: arguments, arrays, objects, maps, sets and FormData entries. - A call with files sends multipart form data. The codec output goes in the `args` field and each file goes as it is in a `file<index>` part. - The new BodyFormat.SerializedFormData ("10") marks the request. - The server decodes `args` with a plugin made for that request, which turns each index back into its part. Other bodies decode without it. - A missing `args` field, a bad index or a missing part is refused with 400. bodySizeLimit bounds the whole body. - Default JSON mode is unchanged. Upload code ships only in the rich-args entry. - The version skew spec moves its unknown tag from "10" to "11". Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The codec request path no longer sets `Content-Type: text/plain` or picks a body-format tag per body. Fetch gives a string body `text/plain` and a `FormData` body its multipart boundary, so uploads keep the `Serialized` tag and the handler tells them apart by the multipart content type. That drops `BodyFormat.SerializedFormData` and the `instanceof FormData` branch, so apps that don't use rich arguments pay nothing for uploads (−21 B minified on the server-function scenarios against the PR's base). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018LY7F9czoRqdMEvk2QwPr1
🦋 Changeset detectedLatest commit: e543ec9 The changes in this PR will be included in the next version bump. This PR includes changesets to release 14 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Size (brotli, eager entry chunk)
|
Coverage Report for CI Build 39662771674Warning Build has drifted: This PR's base is out of sync with its target branch, so coverage data may include unrelated changes. Coverage remained the same at 77.662%Details
Uncovered ChangesNo uncovered changes found. Coverage RegressionsNo coverage regressions found. Coverage Stats
💛 - Coveralls |
Merging this PR will improve performance by 12.01%2 warnings
Performance Changes
Tip Curious why performance improved? Comment Comparing Footnotes
|
Summary
Before: with
enableRichArguments(), #4177 lets a server function take files anywhere in its arguments, but its core client request path gained aninstanceof FormDatabranch, a conditionalContent-Typeheader and a newBodyFormat.SerializedFormDatatag. That cost +95 B minified for every app that uses server functions, rich arguments or not.After: the same feature, with apps that don't use rich arguments paying nothing. The server-function scenarios come in at −21 B minified against
next.This carries @lxsmnsyc's commit from #4177 unchanged, plus one commit on top:
Content-Type: text/plainon the codec path. Fetch already gives a string bodytext/plainand aFormDatabody its multipart boundary.Serializedtag ("0"). The handler treats aSerializedbody with amultipart/form-datacontent type as an upload.SerializedFormData("10") is gone, and the version-skew spec's future tag is back to"10".How did you test this change?
@solidjs/webunit: 1395/1395. Hydrate: 520 passed. Server: 1745 passed, 1 failed. The failure isserver-functions-adapter-request, which also fails onnextunder local Node 22."0"tag plus the multipart content type. The malformed-body cases (noargsfield, a missing part, a non-file part, a file index in a plain codec body) still answer 400.scripts/sizeagainstnext(9f64ca9): −21 B minified on all six server-function page scenarios. Brotli moves −64 to +70 B per scenario from compression noise; none of them crosses a gate.Supersedes #4177.
Generated by Claude Code