Skip to content

Make jsc::URL a re-export of bun_url with a UrlJsc extension trait - #37359

Open
robobun wants to merge 9 commits into
claude/split/install-clifrom
farm/df8b29f2/split-url
Open

Make jsc::URL a re-export of bun_url with a UrlJsc extension trait#37359
robobun wants to merge 9 commits into
claude/split/install-clifrom
farm/df8b29f2/split-url

Conversation

@robobun

@robobun robobun commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

What this does

jsc::URL duplicated the JSC-agnostic surface of bun_url::whatwg::URL (constructors, getters, destroy, whole-string conversions). It is now a pub use of that type; only the two entry points that need JSValue/JSGlobalObject (from_js, href_from_js) remain here, as the UrlJsc extension trait. fetch.rs imports the trait (this was the compile break in the original PR's first CI run).

Split 2 of 8 from #32023, which alii asked to be broken up. Pure code motion and deletion; no intended behavior change. Stacked on claude/split/install-cli (merge order: foundations → install-cli → these, in any order among themselves).

Verification

  • Compiles in isolation against the base (cargo check), and the union of all eight splits is byte-identical to Deduplicate jsc bindings, runtime api, test matchers, and shell builtins #32023's head f29ce8fe4, which CI ran at 285/286 green (the one red was the fleet-wide napi.test.ts GC-timing flake on windows x64-baseline).
  • Since this is behavior-preserving, the new tests lock in the behavior of the rewired entry points rather than failing before the change: fetch(new URL(...)), the invalid-proxy rejection (string and {url} object forms, the href_from_js Dead-tag branch), and fetch.preconnect with a URL object, an unparseable string, and a throwing toString (the JsResult propagation path). All pass identically on the release build and this branch's debug build.

no test proof · iteration 5 · Platform-specific test(s) that do not run on this machine. Deferring to CI, which covers all platforms: test/js/web/fetch/fetch-preconnect.test.ts

@robobun

robobun commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator Author
Updated 8:05 AM PT - Aug 11th, 2026

@robobun, your commit 739eb49 has some failures in Build #92113 (All Failures)


🧪   To try this PR locally:

bunx bun-pr 37359

That installs a local version of the PR into your bun-37359 executable, so you can run:

bun-37359 --bun

@github-actions

Copy link
Copy Markdown
Contributor

This PR may be a duplicate of:

  1. Deduplicate jsc bindings, runtime api, test matchers, and shell builtins #32023 - Parent PR that contains this PR's changes as a subset; both refactor src/jsc/URL.rs to deduplicate JSC URL bindings by re-exporting from bun_url

🤖 Generated with Claude Code

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — pure dedup: jsc::URL becomes a re-export of bun_url::whatwg::URL plus a UrlJsc extension trait, matching the existing StringJsc/SysErrorJsc pattern. The inline nit is doc-only.

Extended reasoning...

Overview

This PR collapses a duplicate opaque FFI type. src/jsc/URL.rs previously defined its own bun_opaque::opaque_ffi! { pub struct URL; } plus ~15 getter/constructor wrappers that were byte-for-byte equivalents of bun_url::whatwg::URL (src/url/lib.rs:48-211). It now pub uses that type and keeps only the two JSC-dependent entry points (from_js, href_from_js) as a UrlJsc extension trait — the same pattern already used for StringJsc, SysErrorJsc, ZigStringJsc, and SliceWithUnderlyingStringJsc in src/jsc/lib.rs. lib.rs re-exports the trait; fetch.rs imports it as UrlJsc as _.

Security risks

None. No parsing, validation, allocation, or FFI signature changes. Both the deleted and the retained URL are the same bun_opaque::opaque_ffi! ZST handle, so URL__fromJS(...) -> *mut URL is ABI-identical before and after.

Level of scrutiny

Low. This is code motion + deletion, split 2/8 from #32023 at a maintainer's request, with the union verified byte-identical to the CI-green parent. I checked every removed method has an equivalent on bun_url::whatwg::URL (getters, from_string/from_utf8, file_url_from_string/path_from_file_url, destroy, hash/fragment_identifier), and grepped call sites: href_from_js is only used in fetch.rs (trait now imported); URL::destroy in js_valkey.rs/SocketAddress.rs and URL::path_from_file_url/file_url_from_string in BunObject.rs/JSSourceMap.rs/fetch.rs all resolve to inherent methods on the re-exported type without needing the trait.

Other factors

The one finding is a doc-drift nit in src/CLAUDE.md (URL::href_from_string is now only a free function, not an associated fn) — no callers use that spelling, so nothing breaks. This doesn't warrant blocking a mechanical dedup.

Comment thread src/jsc/URL.rs
Comment thread src/jsc/URL.rs Outdated
Comment thread src/jsc/URL.rs Outdated
Comment thread src/jsc/lib.rs Outdated

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — pure deduplication, the deleted jsc::URL surface is byte-for-byte covered by bun_url::whatwg::URL. The one inline nit (4-line comment) is style-only and non-blocking.

Extended reasoning...

Overview

This PR replaces src/jsc/URL.rs's duplicate URL struct + inherent impl with pub use bun_url::whatwg::URL, moves the two JSC-dependent entry points (from_js, href_from_js) onto a new UrlJsc extension trait, re-exports that trait from bun_jsc's crate root, adds the trait import to the sole caller (fetch.rs), and updates src/CLAUDE.md's URL section. Net: ~130 lines deleted, ~20 added. Split 2 of 8 from #32023.

Security risks

None. No new parsing, no new FFI surface, no user-input handling changes. The two remaining extern "C" decls (URL__fromJS, URL__getHrefFromJS) and their call_check_slow wrappers are unchanged from the pre-PR bodies.

Level of scrutiny

Low-to-medium. Pure code motion/deletion with no intended behavior change. I verified:

  • Every inherent method deleted from src/jsc/URL.rs (from_string, from_utf8, destroy, protocol/href/username/password/search/host/hostname/port/pathname/hash/fragment_identifier, file_url_from_string, path_from_file_url) exists on bun_url::whatwg::URL (src/url/lib.rs:128-210) with matching signatures, so callers in SocketAddress.rs, BunObject.rs, js_valkey.rs, and JSSourceMap.rs still resolve.
  • URL::href_from_js / URL::from_js callers: only fetch.rs (4 sites), which gets the UrlJsc as _ import in this PR. No other file calls these, so no missing trait imports.
  • The *mut URL in URL__fromJS's return type now names bun_url::whatwg::URL instead of the local opaque_ffi! struct — both are opaque #[repr(C)] handles to the same C++ WTF::URL, so the ABI is unchanged.
  • href_from_string / join were dropped as associated fns (free-function-only in bun_url); grep confirms zero URL::href_from_string / URL::join call sites, and src/CLAUDE.md was updated in d912d24 to reflect this (my previous nit, now resolved).

Other factors

  • The prior review nit (stale URL::href_from_string doc reference) was addressed in d912d24 and the thread is resolved.
  • The comment-cop bot flagged three comments; the inline nit on this run clarifies that only URL.rs:6-9 is a real 3-line-max violation (the other two flags are 2-line doc comments and can be dismissed). This is style-only and doesn't affect correctness — fine to fix on merge or in a follow-up.
  • The parent PR's CI ran 285/286 green on the byte-identical union of all splits.

Comment thread src/jsc/URL.rs Outdated

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — pure code motion, both prior nits addressed.

What was reviewed:

  • Confirmed every deleted inherent method (from_string/from_utf8/destroy/getters/whole-string conversions) exists on bun_url::whatwg::URL with matching signatures.
  • Grepped all jsc::URL:: call sites: only fetch.rs uses the trait methods (href_from_js), and it imports UrlJsc as _; the rest (JSSourceMap.rs, BunObject.rs, SocketAddress.rs, js_valkey.rs) use inherent methods that resolve through the re-export.
  • Verified 9ba009a dropped the 4-line comment and d912d24 fixed the src/CLAUDE.md doc drift; comment-cop flags on the two 2-line doc comments were false positives.
Extended reasoning...

Overview

Split 2 of 8 from #32023. Replaces the duplicate impl URL in src/jsc/URL.rs with pub use bun_url::whatwg::URL; and moves the two JSC-dependent entry points (href_from_js, from_js) onto a new UrlJsc extension trait. src/jsc/lib.rs re-exports the trait alongside URL and drops a stale comment. fetch.rs gains a one-line UrlJsc as _ import (the only caller of the trait methods). src/CLAUDE.md updates the URL-parsing section to reflect the new shape.

Security risks

None. No parsing, validation, or FFI-boundary logic changed — the extern-C bodies of href_from_js/from_js are byte-identical to before (same call_check_slow wrapper, same URL__getHrefFromJS/URL__fromJS externs). All deleted methods are provably present on the re-exported type.

Level of scrutiny

Low. This is mechanical deduplication of an internal Rust type re-export, part of a maintainer-requested split of an already-reviewed parent PR. The union of splits is stated byte-identical to the parent's CI-green head. I verified via grep that every jsc::URL:: call site in the tree resolves either through the re-exported inherent methods or (for fetch.rs only) through the imported trait, so no callers are broken.

Other factors

Both nits from my earlier passes are resolved: the href_from_string doc reference now points at the free function (d912d24), and the over-length comment above the re-export was dropped entirely (9ba009a). All inline threads are marked resolved. The remaining comment-cop flags on 2-line doc comments were false positives per rule #13's 3-line limit. No outstanding reviewer feedback.

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — both earlier nits (doc drift, 4-line comment) are addressed; pure dedup with no behavior change.

What was reviewed:

  • Verified every deleted inherent method on the old jsc::URL (getters, from_string/from_utf8, file_url_from_string/path_from_file_url, destroy) exists with matching signatures on bun_url::whatwg::URL, and both types are bun_opaque::opaque_ffi! ZSTs so URL__fromJS -> *mut URL is ABI-identical.
  • Grepped for all URL::from_js/URL::href_from_js callers — only fetch.rs, which now imports UrlJsc as _.
  • New tests are additive and exercise the rewired paths (URL-object arg, invalid-proxy Dead-tag branch, preconnect toString propagation).
Extended reasoning...

Overview

Split 2 of 8 from #32023. src/jsc/URL.rs (153 → 30 lines) drops its duplicated opaque URL type and inherent impl block in favor of pub use bun_url::whatwg::URL, keeping only the two JSC-dependent entry points (href_from_js, from_js) as a new UrlJsc extension trait. src/jsc/lib.rs re-exports the trait and drops a stale comment; fetch.rs gains UrlJsc as _ in its import list; src/CLAUDE.md is updated to describe the re-export; two test files gain coverage for the rewired call sites.

Security risks

None. No parsing, validation, or auth logic changes — the same URL__fromJS / URL__getHrefFromJS C++ externs are called through identical call_check_slow wrappers. The opaque handle type is nominally different but structurally identical (bun_opaque::opaque_ffi! in both crates), so the FFI ABI is unchanged.

Level of scrutiny

Low-to-medium. This is mechanical deduplication of a duplicated FFI wrapper against its canonical definition in bun_url. I confirmed via grep that bun_url::whatwg::URL carries every method being deleted here (including destroy), and that fetch.rs is the only Rust file invoking the two methods that moved to the trait. The bodies of href_from_js/from_js are byte-identical to the pre-PR inherent impls.

Other factors

Both nits from my earlier passes are resolved: the src/CLAUDE.md URL section now points at the free bun_url:: functions and documents UrlJsc, and the 4-line explanatory comment above the re-export was dropped in 9ba009a. All inline threads (including the comment-cop flags) are marked resolved. The added tests follow existing patterns in their files and lock in the observable behavior of the rewired entry points. The parent PR's CI ran 285/286 green on the union of all splits.

@robobun
robobun force-pushed the claude/split/install-cli branch from 2f5dd36 to 9ae3ff5 Compare August 11, 2026 02:09
@robobun

robobun commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator Author

Final CI state on 739eb49: build 92113 finished with 192 jobs passed, 0 test failures, and 4 darwin jobs expired waiting for agents (mac fleet outage). Every lane that ran is green. Review is LGTM with all threads resolved; ready for a maintainer.

Comment thread src/bun_core/output.rs Outdated
Comment thread src/bun_core/string/mod.rs Outdated
Comment thread src/bun_core/string/mod.rs Outdated
Comment thread src/bun_core/string/mod.rs Outdated
Comment thread src/bun_core/string/mod.rs Outdated
Comment thread src/bun_core/string/mod.rs Outdated
Comment thread src/bun_core/string/mod.rs Outdated
Comment thread src/bun_output_tags/lib.rs Outdated
Comment thread src/bun_output_tags/lib.rs Outdated
Comment thread src/bun_output_tags/lib.rs Outdated
Comment thread src/bun_output_tags/lib.rs Outdated
Comment thread src/clap_macros/lib.rs Outdated
Comment thread src/collections/pool.rs
Comment thread src/install/PackageInstall.rs
Comment thread src/install/PackageInstall.rs
Comment thread src/install/PackageInstaller.rs
Comment thread src/install/PackageManager/install_with_manager.rs
Comment thread src/install/PackageManager/install_with_manager.rs
Comment thread src/install/PackageManager/patchPackage.rs
Comment thread src/install/PackageManager/patchPackage.rs
Comment thread src/install/PackageManager/runTasks.rs Outdated
Comment thread src/install/hosted_git_info.rs Outdated
Comment thread src/install/hosted_git_info.rs
Comment thread src/install/hosted_git_info.rs
Comment thread src/install/isolated_install.rs
Comment thread src/install/isolated_install.rs
@robobun
robobun force-pushed the farm/df8b29f2/split-url branch from a7e3331 to 03f04da Compare August 11, 2026 08:15
Comment thread src/url/lib.rs Outdated
Comment thread src/url/lib.rs Outdated
Comment thread src/url/lib.rs Outdated
Comment thread src/url/lib.rs Outdated
Comment thread src/url/lib.rs
Comment thread src/url/lib.rs Outdated
Comment thread test/js/web/fetch/fetch-args.test.ts
Comment thread src/url/lib.rs
Comment thread src/url/lib.rs

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — all three earlier findings are addressed (whatwg::URL now uses opaque_ffi! so auto-trait bounds are preserved, the dead free path_from_file_url is dropped, and the proxy tests use the describe-scoped url).

What was reviewed:

  • jsc::URLbun_url::whatwg::URL re-export: getters/constructors/destroy are byte-equivalent to the deleted jsc versions; from_string widened pub(crate)(&String)pub(String) is behaviorally identical since bun_core::String: Copy.
  • UrlJsc trait: from_js/href_from_js bodies unchanged; fetch.rs imports the trait so method resolution still finds them.
  • Duplicate URL__* extern declarations across the two crates name the same C symbols with identical signatures — harmless.
  • New tests exercise the rewired entry points (URL-object arg, invalid-proxy Dead-tag branch, preconnect toString throw) and follow sibling conventions.
Extended reasoning...

Overview

Collapses the duplicated jsc::URL opaque-FFI surface into a pub use bun_url::whatwg::URL, keeping only the two JSC-dependent entry points (from_js, href_from_js) as a UrlJsc extension trait. bun_url gains bun_opaque as a dep so whatwg::URL is declared via opaque_ffi! (restoring !Send + !Sync + !Freeze + !Unpin), and picks up the getters (username/password/host/port), destroy(), and by-value file_url_from_string/path_from_file_url that previously lived only on the jsc twin. fetch.rs gets a one-line UrlJsc as _ import; src/CLAUDE.md is updated; five small tests lock in the rewired paths. Split 2 of 8 from #32023, which a maintainer asked to be broken up.

Security risks

None. Pure code motion around an opaque WTF::URL FFI handle. No new parsing, no user-input validation changes, no auth/crypto/permissions surface. The extern "C" declarations that now appear in both crates name identical C symbols with identical signatures (Rust permits redundant extern decls; the linker resolves to one definition).

Level of scrutiny

Moderate. It touches FFI type identity and cross-crate re-exports, which merits care around auto-trait bounds and ABI — but that was the substance of my earlier review, and the fix (commit 739eb49) uses opaque_ffi! exactly as suggested, so jsc::URL is now nominally and structurally the same type it was before. Every deleted method on the jsc side has a byte-equivalent counterpart on the re-exported type; the only signature change (from_string &StringString by value, pub(crate)pub) is a no-op given bun_core::String: Copy and is required for jsc callers to reach it.

Other factors

Three prior inline findings from this reviewer were all addressed in b346c21 and 739eb49. The bug-hunting pass on the current head found nothing. The one remaining unresolved thread (the opaque_ffi! note at src/url/lib.rs:185) is fixed in code — the GitHub thread just wasn't clicked resolved. The unresolved comment-cop bot flag at line 50 targets the pre-existing extern "C" SAFETY block comment, not new code. New tests follow the sibling conventions in their files (await Bun.sleep(2) matches every neighbor in fetch-args.test.ts's "does not send a request when" block).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants