Fix Turbopack worker_threads URL resolution (#93432)
Fixes #93427
## What?
This fixes Turbopack's handling of Node.js `worker_threads` entries
created with a `URL` object:
```ts
new Worker(new URL('./worker.ts', import.meta.url))
```
Turbopack was resolving this form with the same project-root context
used for string/path worker entries. That makes relative URL worker
entries fail when the relative URL should be resolved from the module
that constructs it.
This PR keeps the existing behavior for string/path Node.js workers, but
resolves relative URL worker entries from the module that creates the
URL.
## Why?
The issue reports a regression where this pattern worked in
`next@16.1.7`, but fails in `next@16.2.4` and `next@16.3.0-canary.8`:
```ts
new Worker(new URL('../../worker-entry.mjs', import.meta.url))
new Worker(new URL('../../worker-entry.mts', import.meta.url))
```
The failure happens before the app can build because Turbopack tries to
resolve the relative worker entry from the wrong context:
```text
Module not found: Can't resolve '../../worker-entry.mjs'
Module not found: Can't resolve '../../worker-entry.mts'
```
Node.js documents `Worker`'s `filename` argument as accepting either a
string path or a WHATWG `URL` object. Relative string paths are resolved
relative to the current working directory. By contrast, `new
URL(relative, import.meta.url)` constructs a URL by resolving the
relative specifier against the importing module's URL.
webpack also documents `new Worker(new URL("./worker.js",
import.meta.url))` as the supported Node.js `worker_threads` syntax.
Matching that documented pattern avoids treating URL-object workers as
if they were string-path workers.
## How?
In `turbopack-ecmascript` worker reference analysis:
- Detect relative `JsValue::Url` entries passed to the Node.js `Worker`
constructor.
- Use the importing module's parent directory as the resolution context
for those URL entries.
- Keep the existing traced project directory context for string/path
worker entries and other Node.js worker forms.
This keeps the fix scoped to the URL-object case from the issue while
preserving the existing behavior for string-path workers.
## Tests
Added an e2e regression test to the existing Turbopack-specific
`node-worker-threads` suite:
```text
test/e2e/app-dir/node-worker-threads
```
The new test covers a Route Handler that creates a worker with:
```ts
new Worker(new URL('../../worker-dir/url-worker.ts', import.meta.url))
```
Verified locally:
```text
cargo fmt --check --package turbopack-ecmascript
cargo check --package turbopack-ecmascript
pnpm build-all
pnpm test-dev-turbo test/e2e/app-dir/node-worker-threads/node-worker-threads.test.ts
pnpm test-start-turbo test/e2e/app-dir/node-worker-threads/node-worker-threads.test.ts
```
<!-- NEXT_JS_LLM_PR -->
Co-authored-by: Luke Sandberg <lukesandberg@users.noreply.github.com>