Deduplicate webcore blob, sink, and S3 helpers#32024
Conversation
|
Updated 3:16 AM PT - Jun 10th, 2026
❌ @robobun, your commit d473d99 has 1 failures in
🧪 To try this PR locally: bunx bun-pr 32024That installs a local version of the PR into your bun-32024 --bun |
|
@robobun adopt |
d257e67 to
2552851
Compare
|
Adopted and verified: full diff audit for behavioral equivalence, Final CI state (build 61719): 281 jobs passed; the only test failure is a one-off segfault of |
Pin the error contracts and type dispatch the dedup consolidated: S3 static and instance method argument validation (per-method messages, MISSING_ARGS vs INVALID_ARG_TYPE split), the Bun.file().write() and S3 writer() options.type override, and Blob construction from every ArrayBuffer-like type as both a direct body value and an array part.
s3-fd-validation.test.ts also contains a test that needs unproxied localhost egress; the validation contract tests are all synchronous rejections with no network dependency, so they get a self-contained file.
What this does
Dedupes webcore lifecycle boilerplate with zero intended behavior change:
impl_file_closer!: sharedFileCloserimpl for blobReadFile/WriteFile(the two hand-written impls were functionally identical;ReadFilegainsbun_io::intrusive_io_request!so both go through theIntrusiveIoRequesttrait)impl_js_sink_forwarders!: sharedJsSinkTypeforwarder methods forArrayBufferSink,FileSink,HTTPServerWritable, andNetworkSinkCopyFile::fallback_read_write: the read/write-loop fallback block appeared three times indo_copy_file_rangeBlob::set_content_type_from_jsandS3File::finish_s3_blob: the two write-path content-type override blocks and the two S3 constructor epilogues were byte-identical copiesS3File::parse_s3_path_or_blob/resolve_s3_blobandS3Client::blob_and_options: shared argument parsing for the S3 static and instance methods; theMissingPathErrorenum preserves the per-method split betweenMISSING_ARGSand invalid-arguments errorsJSTypematch lists in Blob construction replaced with the existingJSType::is_array_buffer_like()(same 14-type set)Net -411 lines of src.
Top of the stack, merge order: foundations → install-cli → jsc-runtime → this. Split from #31912 (whole-repo simplification pass; closing that PR in favor of module-scoped splits).
Tests
The consolidated paths had no existing coverage of their error contracts, so this adds characterization tests pinning them:
test/js/bun/s3/s3-argument-validation.test.ts: per-method static rejection messages (includingstatreusing the "get size" wording), the instance-method split betweenERR_MISSING_ARGS(no argument) andERR_INVALID_ARG_TYPE(non-path argument),unlinkalways reportingMISSING_ARGS, and the S3writer()non-stringtyperejectiontest/js/web/fetch/blob-write.test.ts:Bun.file().write()options.typecontract (non-string throws, valid types lowercased, known types resolved through the mime table, invalid types silently ignored)test/js/web/fetch/blob.test.ts: Blob construction from all 14 ArrayBuffer-like types, as a direct body value and as an array partBecause this PR is a behavior-preserving refactor, there is deliberately no test that fails without the src change: the tests pass identically on the base tree and on this branch (verified by running both), which is the equivalence proof for the refactor rather than a gap in the tests.
Verification
cargo check --workspacepasses on all 10 CI target triples (bun run rust:check-all)Bun.write(30 pass plus 5 slow-machine timeouts that reproduce identically on the base branch)