## Feature Request: Infer runtime prop types for `keyof` operator

**Context**
When using `<script setup lang="ts">` with `defineProps`, the compiler infers runtime type strings (e.g., `String`, `Number`, `Boolean`) from the TypeScript type argument. The `keyof` type operator is currently unhandled, leading to missing or incorrect inferred types.

**Desired Behavior**
The compiler should recognize `keyof T` in prop type annotations and produce appropriate runtime type hints (`String` and/or `Number`) based on the possible keys of `T`.

**Acceptance Criteria**

1. **Object type with only string keys**
   For `keyof` of an interface, type literal, or imported type that has exclusively string-named properties (and no numeric literal keys), the inferred prop type must be `['String']`.

2. **Object type containing numeric literal keys**
   - If the target type contains at least one numeric literal property key (e.g., `{ 1: any }`), the inferred type must include `'Number'`.
   - If both string-named and numeric literal keys exist, the result must be `['String', 'Number']`.

3. **`keyof typeof` with built-in types**
   When `keyof typeof variable` is used and the variable’s type is:
   - `Array<T>`, `ReadonlyArray<T>`, or any array-like type (including `ArrayLike<T>`) → return `['String', 'Number']` (because of numeric indices).
   - `Set<T>` → return `['String']`.
   - Any other object type → follow the same rules as the object's own properties (as in criteria 1 and 2).

4. **`keyof` through type references**
   If `keyof` is applied to a type reference (e.g., `keyof SomeGeneric<U>`) that resolves to a concrete type (via import, local declaration, or global type), the inference must be performed on the resolved type. Likewise, chained `keyof` (`type A = keyof B; … props: { p: A }`) must work correctly.

5. **Cross-file and global types**
   The behavior must apply regardless of whether the target type is defined in the same file, imported from another `.ts`/`.vue` file, or provided by a global/ambient declaration. No error should be raised.

6. **Fallback for unresolved types**
   If the target of `keyof` cannot be resolved, it is acceptable to default to `['String']` rather than failing compilation or producing `'Unknown'`.

**Motivation**
Components that use `keyof` to constrain props to valid keys of another type need accurate runtime type information for prop validation and documentation. Currently, such props are either silently mishandled or lead to build failures.

fix(compiler-sfc): handle keyof operator (#10874)


**Title:** `reactivity-transform`: `$ref` identifiers should not be rewritten when shadowed by `for…in` / `for…of` loop variables

**Package:** `packages/reactivity-transform`

**Current behavior**
When a `$ref` variable is shadowed inside a `for…in` or `for…of` loop (via a variable declaration on the left side), the transform still rewrites references to the loop variable as if they were the ref, appending `.value`.

**Example (simplified)**
```ts
let x = $ref(1)
for (const x of arr) {
  console.log(x)  // ❌ incorrectly rewritten to x.value
}
```

**Expected behavior**
The loop variable `x` creates a new binding that lives only within the loop body. References to that binding should never be rewritten. The same should apply when the loop left side is a destructuring pattern (`const [x] of …`, `const { x } in …`).

**Context**
This pattern is analogous to how function arguments with the same name shadow an outer `$ref`. The existing walk already handles function parameters and top-level variable declarations (excluding the ref itself). The fix should extend `walkScope` to inspect `ForInStatement` and `ForOfStatement` nodes: when the left side is a `VariableDeclaration`, its declared identifiers should be registered as bindings (and therefore excluded from `.value` rewriting) in the same way as a normal var declaration.

**Constraints / Safety**
- Only affect loops that declare a variable (e.g. `const`, `let`). Loop variables introduced without a declaration (e.g. `for (x of arr)`) are already handled because the identifier is not re-bound.
- The logic should not interfere with ref rewriting when a ref is used in the `for…of` right-hand side or loop initializer, only within the loop body shadow scope.
- Destructuring patterns in the loop left must be walked with `extractIdentifiers` to handle all bound names (e.g., `for (const { a: b } of …)`).
- Keep the same treatment as for any other variable declaration: if the loop variable happens to be a `$ref` call itself (extremely unusual), it should still be processed as a ref declaration.

fix(reactivity-transform): should not rewrite for...in / for...of scope variables


Add an `--output-js FILE` flag to the `wasm-bindgen` CLI that writes vanilla JavaScript bindings, analogous to the existing `--output-ts` for TypeScript. The generated JS must drop all TypeScript-specific syntax (type annotations, `interface` blocks, `as` casts, `public`/`private` keywords, etc.) while preserving the same runtime behavior as the TS output. The flag should be compatible with `--debug` and other existing options, and the default stdout fallback when no output flag is given must remain TypeScript. Also expose a corresponding `generate_js` method on the library’s public result object so that callers can obtain the JS string programmatically.


Currently `JsValue` does not implement `PartialEq`, so users cannot write `a == b` in Rust when both sides are `JsValue`. We want to add that trait impl and make it behave like JavaScript's strict equality (`===`):

- Two `JsValue`s should be considered equal iff `getObject(a) === getObject(b)` in JS (i.e., same primitive value, same object reference).
- In particular, `NaN === NaN` must be `false`, and distinct objects with the same shape must be `false`.
- The Rust side needs an intrinsic that compares two internal `u32` indices, similar to how we already expose intrinsics like `__wbindgen_json_parse` and `__wbindgen_json_serialize`. That intrinsic will call `getObject(a) === getObject(b)` and return `0` or `1`.
- The `PartialEq` impl should call that intrinsic and interpret the result as a `bool`.

Add the necessary glue in the JS generation layer using the existing helper that resolves objects (`expose_get_object`), and ensure the new intrinsic is registered in the same place where other similar helpers are wired up (e.g., near the existing `__wbindgen_json_*` bindings). The Rust side should declare the FFI function in the `externs!` block (where `__wbindgen_json_parse` etc. are declared) and implement `PartialEq` for `JsValue`.

The final behavior must match what users expect from `===`: equality for primitives, reference identity for objects, and `NaN !== NaN`.

Implement `PartialEq` for `JsValue` (#217)


## Bug Report: Immutable slices needed for texImage2D and other WebGL APIs

**Component:** `web-sys` (WebGL bindings)

**Summary:**
Certain WebGL functions that take typed‑array arguments (such as `texImage2D`, `texSubImage2D`, `compressedTexImage2D`, `bufferData`, and their WebGL2 3D counterparts) currently require mutable slices (`&mut [T]`) even though WebGL does not mutate the provided data. This makes it impossible to pass data from an immutable reference, forcing unnecessary copies or unsafe transmutes.

**Background:**
The `web-sys` crate already supports immutable slices for some WebGL functions that accept `Float32Array` arguments (e.g., `uniform1fv`, `vertexAttrib2fv`). However, the same treatment was not extended to:

- `Uint8Array`
- `ArrayBufferView`
- `BufferSource`

As a consequence, APIs like `texImage2D` (which can accept `Uint8Array` or other buffer sources) and `bufferData` are still bound with `&mut` slice parameters, while their `Float32Array` counterparts (e.g., `uniform1fv`) correctly use immutable slices. This inconsistency is confusing and restrictive.

**Expected Behavior:**
All WebGL functions that read from a typed‑array parameter and do not mutate it should accept immutable slices (`&[T]`), regardless of the element type. Specifically, the following operations should work with `&[u8]`, `&[f32]`, or other appropriate immutable slices:

**For `WebGlRenderingContext`:**
- `bufferData` (with an `ArrayBufferView` source)
- `texImage2D` (with an `ArrayBufferView` source)
- `texSubImage2D` (with an `ArrayBufferView` source)
- `compressedTexImage2D` (with an `ArrayBufferView` source)

**For `WebGl2RenderingContext`:**
- `texImage3D` (with an `ArrayBufferView` source)
- `texSubImage3D` (with an `ArrayBufferView` source)
- `compressedTexImage3D` (with an `ArrayBufferView` source)

These should join the existing set of immutable‑slice functions (like `uniform*fv` and `vertexAttrib*fv`).

**Additional Requirement:**
The current `Uint8ArrayMut` special case should be removed. Instead, `Uint8Array` should behave like `Float32Array`: by default accept mutable slices, but become immutable when the function is on the whitelist. The same “immutable‑slice whitelist” pattern should be applied to `ArrayBufferView` and `BufferSource` so that all array‑buffer types support immutable slices when appropriate.

**Impact:**
Without this change, users working with textures, buffers, or other WebGL pixel/uniform data must create mutable bindings or copy data just to satisfy the type system, even though the JavaScript side never mutates the buffer. This is a safety and ergonomics regression compared to the already‑supported functions that accept immutable slices.

Make the slice argument of texImage2D and related functions immutable


We want to replace `docopt` with `clap` across the `wasm-bindgen-cli` crate, with no change to user-facing flag names or behaviour except where noted. Specifically:

- In the `wasm-bindgen` and `wasm2es6js` binaries, migrate their argument structs from `docopt`-derived deserialization to `clap` `Parser` derive macros. All existing long flags and positional arguments must be preserved, including `--typescript`/`--no-typescript` (TypeScript output enabled by default unless `--no-typescript` is given). The `--version` output will naturally show the package name (`wasm-bindgen-cli`) rather than the binary name—this is acceptable.
- For `wasm2es6js`, add `-o` as a short alias for `--output`.
- The `wasm-bindgen-test-runner` currently forwards raw command-line arguments to node/deno/browser, where the test harness runtime parses them via `cx.args(…)`. Replace this with a `clap`-based argument parser on the Rust side that extracts `--include-ignored`, `--skip`, and the optional filter string, then passes the structured configuration directly to the test runtime. Add separate methods on the test `Context` (`include_ignored`, `skip`, `filter`) to receive these values, and remove the generic `args` method. Update the node, deno, and browser server code to embed the configuration directly into generated JavaScript rather than forwarding raw argv. The test runner’s positional arguments (file to test, optional filter) must remain unchanged.
- Keep the migration confined to the CLI crate (`crates/cli`) for the argument parsing changes, with only the necessary additions to the test runtime (`crates/test`) to support the new context methods. Ensure all previously supported arguments continue to work identically.

Migrate `wasm-bindgen-cli` to `clap` (#4354)


```
title: Extern types with lifetime parameters generate invalid Rust code
labels: bug, extern-types, proc-macro, generics

### Summary
Defining an `extern "C" { type Foo<'a>; }` with a lifetime parameter currently causes compilation
errors in the expanded code produced by the `#[wasm_bindgen]` proc macro. Lifetime-only
generics as well as mixed lifetime + type generics are affected. The same extern type definitions
work correctly when only type parameters are used.

### Steps to reproduce
```rust
#[wasm_bindgen]
extern "C" {
    pub type LifetimeOnly<'a>;
    pub type LifetimeAndType<'a, T>;
}
```
This expands to code that fails with mis-matched generics and missing `PhantomData` usage,
resulting in errors such as:
- `impl From<JsValue> for TypeName` missing required lifetime parameters on the impl block and the
  type name.
- `UpcastFrom` identity impls (for non-generic / lifetime-only types) not forwarding the
  lifetime via `ty_generics`, so the type is used without its lifetime parameter.
- Structural covariance impls for generic types that contain lifetimes omit the lifetime from the
  target type’s generic arguments.
- The internal `PhantomData` field only accounts for type parameters, not for lifetime parameters.

### Expected behavior
Extern types with lifetime parameters should be usable just like those with only type parameters.
Specifically:

1. **`From<JsValue>` implementation** – The impl block must include the lifetime parameters so that
   the trait implementation is well-formed.  The existing behaviour for type parameters (where
   default type parameters are used to avoid forcing turbofish on callers) should be preserved for
   type parameters, while lifetimes are always forwarded.

2. **`UpcastFrom` identity impls** – When the type has no type parameters but does have lifetime
   parameters, the generated identity impls (`UpcastFrom<T> for T` and
   `UpcastFrom<T> for JsOption<T>`) must use `ty_generics` so that the lifetime is included in
   both the `From` and target type.

3. **Structural covariance impls** – When constructing the target type’s generic arguments for
   structural covariance, lifetimes from the original definition must be forwarded alongside the
   replaced type parameter names.  Currently only the computed type parameter names are emitted,
   dropping any lifetime parameters.

4. **`PhantomData` field** – The generated `PhantomData` field must also capture lifetime
   parameters so that the compiler is aware of the lifetime relationship.  One common approach is
   to include references `&'a ()` for every lifetime parameter.

### Additional context
The `wasm-bindgen` macro already handles imported types with generic type parameters, but the
code paths that generate the trait implementations and internal bookkeeping fields never consider
lifetime parameters.  The helper `generics::lifetime_params` already exists and can be used to
retrieve the lifetimes from an `ImportType`’s generics.

No changes to the public API or to the JavaScript side are required – this is purely a Rust
codegen fix that should make the expanded code valid when lifetimes are present, without affecting
existing behaviour for non-generic types or purely type-generic types.
```

fix: handle lifetime params in codegen for generic extern types (#5096)


**Title:** `wasm-bindgen` should support `Into<JsValue>` for exported structs

**Status:** backlog
**Labels:** feature, interop

### Problem
When a Rust struct is annotated with `#[wasm_bindgen]` and exported as a JS class, there is currently no way to convert an instance of that struct into a `wasm_bindgen::JsValue`. This prevents users from passing owned instances of their exported classes to imported JS functions that accept `JsValue` (e.g. to store an arbitrary object in a JS collection).
The workaround of passing the raw pointer manually is unsafe and bypasses the lifetime/ownership tracking provided by the bindings.

### Desired behavior
A generic `From` implementation should be added so that any struct marked `#[wasm_bindgen]` can be converted into `JsValue` via `.into()`. For example:

```rust
#[wasm_bindgen]
pub struct MyClass { ... }

#[wasm_bindgen(module = "./js")]
extern {
    fn register_object(obj: JsValue);
}

#[wasm_bindgen]
pub fn run() {
    let inst = MyClass::new();
    register_object(inst.into());
}
```

On the JavaScript side, the conversion should produce a genuine instance of the corresponding JS class (i.e. `obj instanceof MyClass` should be `true`), and the instance must be tracked in the internal heap-object table so that methods, properties, and `free` work as usual.

### Requirements / invariants
- The conversion must work for **all** exported structs, including those that use a `constructor` attribute with a static token (`Symbol`) for private instantiation.
- The generated JS glue must reliably set up the prototype chain and add the object to the heap table via `addHeapObject`, mirroring what happens when a class constructor is called from JS directly.
- The ownership semantics should be the same as with any other `JsValue`: the Rust side transfers ownership to JS, and the JS side receives an index that can later be freed.
- The implementation must not break existing class exports or change the layout/contract of `JsValue`.

### Non-goals
- This feature does **not** cover automatically implementing `Into<JsValue>` for types that are **not** `#[wasm_bindgen]` structs (e.g. enums).
- It does not need to add any new public API methods to `JsValue` beyond what already exists.

Add support for constructing JsValue instances generically


# Bug report: Static attributes in WebIDL are unsupported

When I define a WebIDL interface containing a `static attribute` (e.g., `static attribute double value;`), the `wasm-bindgen` WebIDL parser prints the warning `Unsupported WebIDL attribute` and generates no bindings for that attribute. The Rust code cannot access or modify the static property.

The project already supports regular (instance) attributes (through `attribute`) and static methods (`static …` operations) in WebIDL. Static attributes should be handled similarly:
- A non-readonly static attribute should produce both a getter and a setter.
- A `readonly` static attribute should produce only a getter.
- The getter/setter should be associated functions on the Rust struct representing the interface (no `&self` receiver), consistent with how static methods are already exposed.
- The generated JavaScript shims must access the property directly on the class constructor (e.g., `Foo.value` or `Object.getOwnPropertyDescriptor(Foo, 'value')`) rather than on the prototype.

Example WebIDL:

```
interface Foo {
    static attribute double value;
};
```

I expect to be able to call `Foo::value()` to read and `Foo::set_value(2.0)` to write from Rust after `wasm-bindgen` processing.

webidl: add support for static attributes


```
Title: Support `Option<char>` in wasm-bindgen bindings
Type: feature request
Priority: medium

### Summary
`wasm-bindgen` already supports optional primitive types such as `Option<i32>`, `Option<f64>`, and `Option<bool>`. However, `Option<char>` is currently not handled, and using it in `#[wasm_bindgen]`-annotated functions leads to unsupported-type errors. We should add support for `Option<char>` following the existing optional-type conventions.

### Desired behavior
- A Rust function parameter or return type of `Option<char>` should be usable in both exported Rust functions (Rust → JS) and imported JS functions (JS → Rust).
- `None` must map to JavaScript `undefined`.
- `Some(c)` must map to a JavaScript string containing exactly one Unicode code point, including supplementary-plane characters (e.g., `'😀'` → `"😀"`). The conversion should round-trip correctly for any valid `char`.
- The ABI representation should be a pair of `u32` values (present flag and code point), analogous to how other optional primitives are represented (e.g., `WasmOptionalU32`). The presence flag uses `0` for absent (`None`) and `1` for present, with code point computed via `codePointAt(0)` in JavaScript and `as u32` / `from_u32_unchecked` in Rust.

### Additional constraints
- The implementation must handle both directions: calling a Rust function from JS, and calling a JS function from Rust.
- The existing helper `isLikeNone` (already used for `Option<bool>`) should be used on the JS side to detect `undefined`/`null` when converting argument values.
- String-to-char conversion must use `String.fromCodePoint` (JS) and `char::from_u32_unchecked` (Rust) to preserve full Unicode range; do not assume BMP-only strings or use `.charCodeAt(0)`.

### Acceptance criteria
Rust code like the following should work:
```rust
#[wasm_bindgen]
pub fn char_identity(a: Option<char>) -> Option<char> { a }
```
…and be callable from JavaScript with `undefined`, `"a"`, and `"😀"`, returning the correct corresponding values.
```


```
Title: Imported JS functions with `String` parameter/return types do not work

When using `wasm_bindgen!` to import a JS function that accepts or returns
an owned `String`, the generated glue code is incorrect or missing.
For example:

    #[wasm_module = "./foo"]
    extern "JS" {
        fn process(a: String) -> String;
    }

This fails either at compile time or at runtime (typically with a panic
or a TypeError in the JS shim).  In contrast, importing a function that
uses `&str` (borrowed string) works fine, and exporting a Rust function
that uses `String` also works correctly.

Expected behavior:
- A `String` argument should be deserialized from the wasm linear memory
  (pointer + length) into a JavaScript string, and the original buffer
  should be freed after conversion since the value is owned.
- A `String` return value should be serialized into a freshly-allocated
  wasm buffer, with the length stored at a caller-provided out-pointer,
  matching the protocol that the “export” side already implements for
  owned strings.
- The generated TypeScript bindings should continue to map `String` to
  the JS `string` type just as `&str` does today.

I believe the missing piece is in the import-shim generator and in the
Rust-side ABI that the proc macro emits for imported functions — the
`TYPE_STRING` case (as opposed to `TYPE_BORROWED_STR`) simply isn't
handled there yet.  Without this, any realistic interaction where JS
passes or receives owned strings will be broken.
```


Currently, closures passed to `Closure::wrap` or `Closure::once` cannot take arguments by reference. For example, `Closure::wrap(Box::new(|x: &JsValue| { ... }))` fails to compile because the closure conversion system only has implementations for owned arguments (via `FromWasmAbi`) and lacks support for reference arguments (via `RefFromWasmAbi`).

Add support for closures with exactly one argument that is a reference. This includes `Fn(&A) -> R`, `FnMut(&A) -> R`, and `FnOnce(&A) -> R`. The necessary implementations should be added for:

- The runtime closure handling (`WasmClosure` trait and its describe machinery)
- The ABI conversion layer (`IntoWasmAbi` and `WasmDescribe` for `&Fn(&A) -> R` and `&mut FnMut(&A) -> R`)
- The `WasmClosureFnOnce` trait for the single-reference-argument case

The existing `WasmClosure` trait requires a `'static` bound that would prevent implementing it for these closure types, so that bound must be relaxed (e.g., moved onto the individual macro-generated impls instead).

Multi-argument closures and closures mixing reference and owned arguments are out of scope.


**Title:** Broken `Pipe` example and missing shared handle for WASI stdio pipes

The `Pipe` type that used to be available from `wasmer_wasi` has been removed. This breaks the `examples/wasi_pipes.rs` example and any code that relies on a single pipe handle that can be used for both reading and writing in `WasiStateBuilder::stdin()` / `::stdout()`.

With the current `WasiPipePair` API, pipes are split into separate `send` and `recv` halves, but the WASI builder expects a single `VirtualFile + Send + Sync + 'static` for each of stdin/stdout. In many testing and integration scenarios (like capturing child process I/O) we need a single pipe object that can be cloned, with one clone given as stdin and another as stdout, so that data written to the sink clone can be read from the source clone.

**Required behavior:**

* Provide a shared pipe handle built on top of `WasiPipePair` that implements `Read`, `Write`, `Seek`, and `VirtualFile`.
* The handle must be `Clone` and `Send + Sync` so that it can be passed to `Box<dyn VirtualFile + Send + Sync + 'static>` and used from multiple threads.
* Concurrent reads and writes on different clones must be safe (the underlying `WasiPipePair` should be locked appropriately).
* The `examples/wasi_pipes.rs` example should be updated to use this new shared pipe in place of the former `Pipe::new()` calls, restoring the example to a working state.

**Constraints and edge cases:**

* The shared handle’s `Read` and `Write` implementations must delegate to the underlying `WasiPipePair`’s corresponding methods **on the appropriate channel** so that data flow corresponds to the pipe’s send/recv direction (writing goes to the send side, reading comes from the recv side).
* Lock poisoning (e.g., a mutex poisoned by a panicking thread) should not cause panics; the handle should gracefully return empty/zero results or errors as appropriate.
* The `VirtualFile` trait methods (`last_accessed`, `last_modified`, `created_time`, `size`, `set_len`, `unlink`, `bytes_available_read`) must be implemented in a way consistent with the underlying `WasiPipePair`, delegating to its implementations when possible.
* The shared handle must not change the existing `WasiPipePair` contract (other callers that destructure the pair into `send`/`recv` should continue to work).

The goal is to restore the ability to create an in-memory bidirectional channel using the wasi pipe primitives and attach both ends to a `WasiState`, matching the patterns that existed before the pipe refactor.


**Request: Support nested mount points in the virtual filesystem union**

The union filesystem (`UnionFileSystem`) currently cannot handle mount points that are nested inside one another.  For example, after mounting one filesystem at `/app` and a second at `/app/sub`, directory listings, metadata queries, and file opens under `/app/sub` do not reach the second filesystem – they either fail or return data from the outer mount.

We need the following behavior:

1. **Deepest-match routing**
   Every filesystem operation (`read_dir`, `metadata`, `symlink_metadata`, `create_dir`, `remove_dir`, `rename`, `remove_file`, `open`) must traverse the mount hierarchy and dispatch to the filesystem at the longest matching mount prefix.  Operations under a nested mount must be handled by the inner filesystem, and the return values (directory entries, metadata, etc.) must reflect paths relative to that mount.

2. **Nested `mount` semantics**
   The `mount` method must accept a `PathBuf` for the mount path and a `String` for the name (instead of `&str`).  When mounting a path like `/a/b` while `/a` is already occupied by a filesystem, the implementation must either place the new filesystem into an existing nested union structure or create intermediate union filesystems as needed, so that the new mount is correctly positioned at the right depth.

3. **Overlapping mount paths**
   Mounting at `/` and later at `/top-level/nested` (or similar overlapping layouts) must work.  For a path like `/top-level/nested/file`, operations should be resolved by the `/top-level/nested` mount; paths not covered by the nested mount should still be served by the outer mount.  The old limitation tracked by issue #3678 should be addressed.

4. **Operational invariants**
   - Directory listings for a path that is itself a nested union must include the mount points of the nested union (i.e., its immediate children should appear as directories).
   - Direct manipulations on a mount point directory (create/remove/rename) should be prevented or produce appropriate errors (e.g., `AlreadyExists`, `PermissionDenied`) rather than `BaseNotDirectory`.
   - `rename` must correctly compute the destination path relative to the mount that owns the source, and must fail if the destination is outside that mount.

5. **Internal representation**
   The old weak-reference/`Arc`-based flat mount storage should be replaced with a design that naturally represents the tree of mount points, so that path resolution is correct and no manual reference-counting or `solidify` steps are needed.

These changes should be backwards-compatible for any callers that are updated to use the new `mount` signature (`PathBuf`/`String`).  The previously ignored test for overlapping mounts can be enabled to validate the new behavior.

implement nested mounted paths via nested union fs


**Bug report: `wasmer gen-c-header` does not support ``.wasmer`` files**

When I run `wasmer gen-c-header` on a pirita (``.wasmer``) package file, the command either fails or produces an incorrect header that seems to be based on the raw container bytes instead of a contained WebAssembly module. I can successfully use `wasmer create-exe` with the same ``.wasmer`` file and select atoms via its `--precompiled-atom` flag, but `gen-c-header` has no equivalent mechanism. This makes it impossible to generate C headers for packages distributed in the pirita format.

Expected behavior:
- Running `wasmer gen-c-header mypackage.wasmer` should detect that the input is a pirita container.
- If the container contains exactly one atom, the command should extract and process that atom automatically (no extra flags needed).
- If the container contains multiple atoms, the command should require the user to specify which atom to generate the header for, via a flag such as `--atom`. When that flag is omitted, it should print a helpful error listing the available atom names.
- The resulting header should reflect the exports of the selected atom, just as if a standalone ``.wasm`` file had been passed.

This would bring `gen-c-header` in line with `create-exe`’s existing support for pirita containers, and allow users to embed any atom’s interface in C/C++ projects directly from a ``.wasmer`` package.

Add support for gen-c-header on pirita files


**Title:** `create-exe` multi-command executables mishandle `--command` flag and library tarball filenames

**Description:**
When building a native executable from a WebAssembly package that contains multiple commands (atoms), the resulting executable does not handle the `--command` flag correctly, especially in the presence of guest arguments.

1. **`--command` parsing in generated executables**
   - Using `--command <name>` (or `-c <name>`) before a `--` separator should select the named command and pass any arguments after `--` to the guest as-is. Instead, the flag may be ignored, forwarded to the guest, or otherwise misinterpreted.
   - The `--command`/`-c` flag and its value should never be forwarded to the WASI guest program; they must be consumed by the runtime stub and used only for atom selection. This is particularly important when the guest program itself accepts flags like `--version`.
   - In the generated C entrypoint, the variable that tracks the number of available commands appears to be left uninitialised (or stuck at a default of 1), which may prevent the multi-command selection logic from even being active.

2. **Library tarball name matching for `x86_64` targets**
   - When `wasmer create-exe` searches for cross-compilation library tarballs or system libraries, it fails to recognise tarballs whose filenames contain `amd64` as valid for `x86_64` Linux targets. This causes avoidable download failures or missing libraries even when a matching tarball exists.

**Expected behaviour:**
- For any generated multi-command executable:
  - `./exe --command cmd1 -- guest-flag` selects `cmd1` and invokes it with `guest-flag`.
  - `./exe -c cmd1 -- guest-flag` behaves equivalently.
  - The `--command`/`-c` option and its argument are stripped from the argv that is passed to the WASI guest.
  - When only a single command is available, `--command` should still be handled gracefully (not break execution).
- `wasmer create-exe` should accept `amd64` as an alias for `x86_64` in tarball filenames so that the correct library is located on such targets.

**Impact:**
Multi-command executables are effectively broken for any package with more than one atom; users cannot reliably select a command via the `--command` flag. Additionally, cross-compilation setups that rely on `amd64`-named tarballs fail unnecessarily, blocking builds.


**Title:** WASI async deep‑sleep resume re‑uses wrong store / instance

**Description**
When a WASI program with async deep‑sleep support is suspended and later resumed (rewound), the resume path incorrectly re‑uses a stale reference to the original `_start` function and its associated store. After a rewind the runtime may have swapped in a different instance – for example because the environment was serialised and restored, or because the program was forked – yet the execution logic continues to call the entry point that was captured before the first suspension.

This causes undefined behaviour ranging from panics (store/instance mismatch) to silent corruption, depending on how the underlying Wasmer store and instance handles interact.

**Acceptance criteria**

1. **Correct instance on every resume**
   - When `run_with_deep_sleep` (or any equivalent resume path) is invoked after a rewind, it must obtain the **current** instance from the WASI environment (`WasiFunctionEnv` → `WasiEnv` → instance handles) rather than relying on a `_start` function that was passed in from the initial call.
   - If the current environment does not contain a valid instance (e.g. `try_clone_instance` returns `None`), the runtime must clean up and send an appropriate error (`WasiRuntimeError` with `Errno::Noexec`) instead of panicking or hanging.

2. **No stale `_start` in the re‑dispatching callback**
   - The closure that re‑spawns execution after a deep sleep trigger (inside `handle_result`) must not capture a `_start` function from a previous invocation. It must re‑enter the main execution loop in a way that the function will be freshly resolved from the environment’s instance.

3. **CLI `run` command correctness**
   - The store should not be passed to code paths that do not need it (e.g., running a `.webc` package). This avoids confusion about which store is alive and prevents accidental reuse of a store that was moved.

4. **Error handling**
   - If for any reason the `_start` function cannot be obtained from the instance (export missing, instance unavailable), the error must be caught, the environment cleaned up, and a clear `WasiRuntimeError` sent back through the channel so the caller receives a proper exit code instead of a crash.

**Additional context**
- The deep‑sleep / async‑rewind logic lives in `lib/wasi/src/state/builder.rs` inside `run_with_deep_sleep` and `handle_result`.
- The CLI entry point that dispatches WASM execution is in `lib/cli/src/commands/run.rs` (`execute_inner`, `execute_target`, `execute_wasm`, `execute_webc`).
- The `WasiEnv` type provides `try_clone_instance()` which can be used to obtain a fresh copy of the current instance.

Fixed a bug where we reuse the wrong store when resuming


Feature Request: Allow middleware implementations to return detailed errors from `FunctionMiddleware::feed`

At present, the `FunctionMiddleware` trait’s `feed` method returns
`WasmResult<()>` (i.e. `Result<(), WasmError>`).  The `WasmError` enum
only has generic variants such as `InvalidWebAssembly`, `Unsupported`,
or `Generic(String)`; none of them convey which middleware produced
the error or any middleware-specific context.  This means that when a
custom middleware detects a problem – for example an opcode it cannot
process – it has no way to attach a human-readable name or an
explanatory message to the error, making debugging and user-facing
diagnostics painful.

Desired behavior:

* Introduce a dedicated error type that carries both the name of the
  middleware and a descriptive message, and make that type the error
  side of the `Result` returned by `FunctionMiddleware::feed`.
* Ensure the new error type is convertible to `WasmError` so that
  callers who already expect `WasmResult` can propagate it without
  extra conversions.
* Expose the new error type publicly (including re‑exporting it in the
  main `wasmer` crate) so downstream middleware authors can reference
  it in their own code.
* Update all existing `FunctionMiddleware` implementations to return
  the new error type instead of `WasmResult<()>` (the Metering
  middleware and any compiler tests that supply a middleware need
  their signatures adjusted; they currently never return an error, so
  a simple signature change should suffice for them).

Impact:

Without this change, middleware that needs to report errors must either
panic or shoe‑horn information into a generic `WasmError::Generic`,
losing the source identity of the error.  With the change, every
middleware gets a first‑class way to signal failure that includes its
name and a human-readable explanation, improving debuggability and
making it practical to write robust middlewares that can fail safely.


**Title:** Implement `run2` for pure WebAssembly (non-WASI/non-Emscripten) modules

**Background**
The new `run2` command can already handle WASI and Emscripten modules, but the fallback path for pure `wasm32-unknown-unknown` modules (`execute_pure_wasm_module`) is still a `todo!()`. We need to complete this so that users can run arbitrary Wasm functions directly from the CLI.

**Request**
Implement the missing behavior in `Run2::execute_pure_wasm_module` so that a plain `.wasm` file can be executed with `wasmer run2`.

Specific requirements:

1. **Instantiation** – Create an instance with an empty import object (no file, network, or environment access, matching the “secure by default” principle).
2. **Entrypoint resolution** – If the user passes `--entrypoint <name>`, call that exported function. Otherwise, call the default `_start` function. If the chosen function is not exported, produce a clear error message.
3. **Argument passing** – The positional CLI arguments (`self.args`) must be converted to WebAssembly `Value`s according to the function’s parameter types. Supported types are the common numeric Wasm types (`i32`, `i64`, `f32`, `f64`, `v128`). A string argument should be parsed as the target numeric type; if parsing fails, error with an indication of which argument and type failed.
4. **Argument count validation** – If the number of provided arguments does not match the function’s parameter count, error out immediately with a descriptive message.
5. **Return values** – After the call, print any returned values, separated by spaces. If the function returns nothing, nothing is printed.
6. **Error handling** – All error paths should use proper context messages (e.g., “Unable to instantiate”, “The module doesn't contain a … function”, “Function expected X arguments but received Y”).

**Verification**
The integration tests for `run2` already include cases for pure Wasm modules that are currently marked as skipped/ignored. Once the implementation is in place, those tests should pass and can be re‑enabled.

**Non-goals**
- Do not add WASI or Emscripten support in this task; those paths are already handled elsewhere.
- The output format for return values can simply be space‑separated `Debug`/`Display` strings – no structured output needed now.

---

*Let me know if any clarification is needed.*


When a vfork child process does not call `exec` before returning or trapping, the file descriptors it opened (e.g., the write end of a pipe) are not closed before control is handed back to the parent. This causes two problems:

1. **Leaked file descriptors**: If the child creates pipes and then exits (via normal return or `proc_exit`) without performing an `exec`, the parent will not see the child’s end of the pipe as closed. Reads on the corresponding parent-side pipe fd block indefinitely or never return EOF, even after the child has terminated. This breaks the expected cleanup semantics of vfork.

2. **Swallowed traps**: When the child traps – for example, by jumping to an invalid address – the trap error is silently discarded. The parent receives only a generic non-zero exit code and no indication that a runtime trap occurred. This makes diagnosing faults in child processes very difficult, especially in the so-called “no-exec” vfork pattern.

**Expected behavior**

- When a vfork child terminates without calling `exec` (whether by a normal exit or because of a runtime trap), all file descriptors that are open in the child should be closed *before* the WASI environment is restored to the parent’s pre-vfork state. The parent should then observe the child’s side of any shared pipe as closed.
- If the child traps, the error should be surfaced – ideally by printing it to stderr and including it in the error path – so that the parent or the runtime can log it appropriately.

**Context**

The issue is observed in the WASIX implementation of `vfork`. The existing path that handles child termination (both via `proc_exit` and via the vfork resume logic) does not perform FD cleanup for the no-exec case, and does not capture the error value when the child fails with a `RuntimeError` that is not a known `WasiError`. The missing cleanup only affects children that do **not** call `exec`; children that successfully `exec` are unaffected because the new process replaces the file descriptor table.

Properly close vfork FDs if exec is not called, report subprocess traps


**Title:** Extend `WasmerEnv` derive to support optional exports and export aliases; apply to emscripten host env

**Background**
The `#[derive(WasmerEnv)]` proc-macro currently treats every `#[wasmer(export)]` field as mandatory: `init_with_instance` looks up the named export and, if the lookup fails, propagates the error.  In practice, Emscripten‑compiled `.wasm` modules do not always export every function the host environment struct declares.  Functions like `malloc`, `free`, or various `dynCall_*` variants may be absent depending on Emscripten version, flags, or dead‑code elimination.  Moreover, the same function may appear under different names (e.g., `_malloc` vs `malloc`), so a single name is sometimes insufficient.

**Desired behaviour**
1. **`optional = true` attribute** – when set on an `export` field, the generated code should treat the export as optional: attempt to obtain the export, but if it is missing, *do not* call `LazyInit::initialize` on that field and do **not** return an error.  The field simply stays uninitialized.

2. **`alias = "..."` attribute** (repeatable) – when looking up an export, the derive should first try the primary name (either the field name or the explicit `name = "..."` override).  If that fails, it should try each declared alias in order.  The first successful lookup should be used; if all fail and the field is not optional, an error should be returned.

3. **Combined usage** – `optional = true` together with one or more aliases must work: try all names, and if none succeed, silently skip initialization.

4. **No change for existing users** – fields without the new attributes must keep the current behaviour: export is required, and a missing export causes `init_with_instance` to fail.

**Where this is needed concretely**
Apply the new attributes to the `EmscriptenData` struct in `wasmer-emscripten`:
- Mark `malloc`, `free`, `memalign`, `memset` as `optional` and add an alias with a leading underscore (e.g., `alias = "_malloc"`) because different Emscripten versions use one or the other naming convention.
- Mark `stackAlloc` / `stack_alloc`, all `dynCall_*` fields, `stackSave` / `stack_save`, and `stackRestore` / `stack_restore` as `optional` (they may not be exported by every module).
- Mark `setThrew` / `set_threw` as `optional` with `alias = "_setThrew"`.

**How to verify**
- Existing tests for `wasmer-derive` must pass.
- The new derive features must compile and work correctly; unit tests (in `wasmer-derive/tests/`) should be added to cover:
  - optional field that is missing → no error.
  - field with aliases that picks up the export via an alias.
  - combination of optional + aliases where export is found or not found.
  - mandatory field with aliases where export is not found under any name → error.
- Emscripten integration tests (existing ones) should continue to work without regressions and ideally pass with modules that lack some of the optional exports.

Improve `WasmerEnv`, fix emscripten with new features


```
Improve number conversion in the JSC backend so that host functions can receive negative i64 values and large numbers that cannot be represented exactly by JavaScript's Number type. Apply the same logic for V128 parameters.

Currently, when a host function is called from JS with an i64 argument, the conversion uses only `to_number`, which loses precision for large integers and cannot handle BigInt-like values. Since JSC does not expose a BigInt interface, fall back to parsing the string representation of the value when it is not a plain number.

Additionally, the Global and Table externals in the JSC backend are now `unimplemented!()`, which causes panics. Implement basic Global `get`/`set` by reading/writing the underlying JS global's `value` property using the existing param/JSValue conversion helpers, and implement Table `new`, `size`, and `grow` by constructing and manipulating a `WebAssembly.Table` through the engine's JSC context. These operations must use the same number-parsing fallback for any large-integer table sizes/growth values.

The changes must ensure that the existing negative-value host-function test passes and that the JSC backend no longer panics when modules use globals or tables.
```


The `wasmer init` command's integration with `cargo wapm` is broken in several ways. When a `Cargo.toml` is present and `cargo wapm` is installed, `wasmer init` should embed the generated WAPM/Wasmer manifest metadata directly into the Cargo manifest under a `[metadata.package.wapm]` section, rather than creating a separate `wasmer.toml`. Currently this does not work correctly.

Specific issues to address:

1. **Detection of `cargo wapm`**: The check for the `cargo wapm` subcommand only matches the exact string `"cargo wapm"` in the output of `cargo --list`. Some installations report the binary as `"cargo-wapm"`. The detection must accept both forms so the integration path is entered reliably.

2. **Metadata error handling**: When loading the Cargo manifest with `cargo metadata`, any error is silently swallowed and no package information is used. The command should instead surface a clear error if `cargo metadata` fails or if no root package is found, rather than silently falling back to a basic scaffold that ignores the existing Cargo project.

3. **Manifest placement inside `Cargo.toml`**: When `cargo wapm` is available, the generated TOML should be written under the `[metadata.package.wapm]` section header in the existing `Cargo.toml`. The current output format does not include this section header, so `cargo wapm` cannot find the metadata.

4. **Spurious debug output**: A debug print of the metadata structure must be removed from the normal output path.

5. **Suggested publish command**: The hint printed after generating the metadata should suggest `cargo wapm` rather than the outdated `cargo wapm publish`.

Debug cargo wapm integration not working


**Title:** `path_open` allows creating a regular file with a trailing slash, missing mandatory error

**Component:** WASI `path_open` syscall (`lib/wasix`)

**Description**
When calling `path_open` with `oflags` containing `O_CREAT` (or the equivalent `creat` flag) and a path that ends in `/` (e.g., `"dir/new-file/"`), the runtime incorrectly creates a regular file named `new-file` instead of returning an error. The trailing slash is semantically significant: it indicates that the target is expected to be a directory. Currently the underlying opener normalizes the trailing slash away, so the distinction is lost and a regular file is created.

Other WebAssembly runtimes (Wasmtime, WasmEdge, Wazero, WAMR, Node) treat this as an error—typically `EISDIR` (`errno::Isdir`). The existing error path for *opening* an already-existent regular file with a trailing slash correctly returns an error. The missing case is when the file does not yet exist and `path_open` is asked to create it.

**Expected behavior**
When `path_open` receives a path that ends with `/` and the call would otherwise create a new regular file (because the path does not exist and `O_CREAT` is present), it should fail with the WASI error `errno::Isdir` (`__WASI_ERRNO_ISDIR`). The check must happen before any path normalization that strips the trailing slash.

**Notes**
- The fix should not alter behavior for paths that do not include `O_CREAT`, or for paths that refer to an existing directory or regular file (those cases already have appropriate error handling).
- Ensure the error is returned early, before the trailing slash is removed by the internal opener or path resolution routines.

Fix `path_open` trailing slash edge case


Fix `epoll_wait` to coalesce all readiness bits for a given fd into a single event, so each fd appears at most once per `epoll_wait` call.

The current implementation can split a single fd's readiness (e.g. simultaneous `EPOLLIN` and `EPOLLOUT`) across multiple events. This violates POSIX semantics and creates a data‑corruption race: after the application handles the first event and closes the fd, the fd number may be immediately reused for a regular file; a later event still references that number as a socket, causing socket‑intended data to land in the wrong file.

Adjust `drain_ready_events` (or the helper that converts pending bits to caller‑visible events) so that for each fd, all applicable readiness bits in the subscription's event mask are collapsed into one event. When multiple fds are ready, respect `maxevents` in the usual way—one event per distinct fd—but never deliver multiple events for the same fd within one call. The helper previously returned a `Vec` of events per fd; it should instead return a single combined `EpollType`.

This also removes the need for the `epoll_mask_to_pending_bits` path and the logic that re‑queues undispatched bits when the event budget is exhausted, because a single fd no longer generates a partial dispatch. Ensure that `EPOLLHUP` and `EPOLLERR` are still included in the coalesced event when present, even if the subscription mask does not explicitly request them (the existing always‑report behavior must be preserved).

fix(wasix): Fix epoll to deliver multiple events per FD at the same time to avoid race conditions


**Title:** Metering middleware does not actually inject any metering instructions

**Description:**
The `Metering` module middleware (in `wasmer-middlewares`) sets up a global for remaining points in `transform_module_info` but leaves `generate_function_middleware` as `unimplemented!()`. Consequently, passing `Metering` during module compilation has no effect – no operator costs are tracked and the point limit is never enforced.

Implement the missing function middleware so that:

* During module compilation, each WebAssembly operator is assigned a cost via the user-provided cost function, and the total cost is accumulated within each basic block.
* At the end of every basic block (i.e., at branch targets like `loop`, `else`, `end`, and at branch / call / return sources), the accumulated cost is checked against the remaining points global and, if insufficient, a trap is emitted; otherwise the global is decremented by the accumulated cost and the accumulator reset.
* The original operator is emitted after the metering logic, not before, so the instruction stream remains valid.

The function middleware must obtain the global index for remaining points from `Metering::remaining_points_index` (which is already set during `transform_module_info`).

Add a test that compiles a minimal WebAssembly function (e.g., `(i32.add (local.get 0) (local.get 1))`) with a limit larger than the total operator cost (e.g., limit 4, cost function returns 1 for every operator) and confirms the function executes without trapping and returns the correct result.


```
Bug: WASIX fd operations can consume unbounded memory when given large target fd values

Certain WASIX syscalls accept explicit file descriptor numbers (e.g., as the target of
`dup2`, the `to` argument of `fd_renumber`, or the `fd` field in `ProcSpawnFdOp` operations
such as `Dup2` and `Open`). Currently, these fd values are allowed to be arbitrarily large
(e.g., near `UINT32_MAX`) and can cause the internal file descriptor table to be resized
to accommodate them. This leads to massive memory allocations and potential denial-of-service.

Related WASI/WASIX public-facing operations:
* `__wasi_fd_dup2(fd, target_fd, ...)` — `target_fd` can be huge.
* `fd_renumber(from, to)` — `to` can be huge.
* `__wasi_proc_spawn2` with fd-op `Dup2` or `Open` — the specified fd number can be huge.

POSIX systems bound file descriptors by per-process limits (`OPEN_MAX` / `RLIMIT_NOFILE`).
WASIX does not yet have a formal per-process fd limit, but the runtime should nevertheless
enforce a reasonable ceiling (e.g., at least `64*1024 - 1`) to prevent trivial resource
exhaustion. When an operation targets an fd equal to or above this ceiling, the runtime
must return an appropriate error and **must not** grow the fd table.

Expected behavior:
* `dup2(fd, huge)` → `EBADF` (or `EINVAL` for the ‘minimum result fd’ use‑case)
* `fd_renumber(from, huge)` → `EBADF`
* `proc_spawn2` fd-op with `fd` ≥ ceiling → `EBADF`

Implementation considerations:
* The check should happen early, before any state mutation or table growth.
* The same ceiling should be used uniformly across the affected syscalls.
* The exact ceiling value should be chosen to be practical for real-world workloads
  while protecting against obviously malicious values (a `64k` upper bound is a sensible
  starting point).
* Error codes: `EBADF` is appropriate when an explicit target fd is out of bounds;
  `EINVAL` may be used when the “minimum result fd” argument in `dup2` exceeds the limit.

Impact: Without this guard, any WebAssembly module can cause memory exhaustion in the host
runtime by using regular WASIX fd operations with crafted large fd numbers.
```

fix(wasix): Guard WASIX fd operations against huge fd targets


```
wasmer-js: Instance::new panics when a module's start function traps. It should return an error instead.

Currently, if a module has a start function that triggers a runtime trap (e.g., division by zero), `Instance::new` panics because it unwraps the result of internal instantiation. The method must propagate the error as an `InstantiationError` so callers can handle it gracefully.

Additionally, host environment initialization (`WasmerEnv::init_with_instance`) is also forced with `unwrap` after instance creation. Any error from that step must also be returned to the caller rather than panicking.

Make sure that errors from the underlying `WebAssembly::Instance::new` call are converted into `RuntimeError` using the existing `JsValue`→`RuntimeError` conversion path.
```

Fixed RuntimeError start when instantiating wasmer-js


We need a new top-level CLI subcommand, `wasmer gen-c-header`, that generates a C header declaration file (the same `static_defs.h` format produced by `wasmer create-exe`) directly from a single `.wasm` input, without requiring a full `create-exe` build.

### Acceptance criteria

1. **Command invocation**
   `wasmer gen-c-header <FILE> -o <OUTPUT> [--prefix <PREFIX>]`

   - `<FILE>` is a path to a `.wasm` module.
   - `-o <OUTPUT>` is the path where the generated header will be written.
   - `--prefix <PREFIX>` is optional; when omitted, the prefix is the SHA‑256 hash of the file contents (matching the hash used by `create-exe`’s prefix mapping).

2. **Header format**
   The generated header must be identical in structure, naming conventions, and symbol declarations to the `static_defs.h` file that `wasmer create-exe` creates for the same module. In particular:
   - Function symbols are named `wasmer_function_<prefix>_<index>`.
   - The header contains all necessary declarations for linking the module into a C program.

3. **Error handling**
   - If the input file does not exist or is not valid WebAssembly, the command exits with a non-zero status and a descriptive error message.
   - Any error from the compiler or metadata extraction pipeline is surfaced to the user.

4. **Stability and compatibility**
   - The command works with the default compiler and target (no special flags required).
   - The generated header is deterministic: given the same input file and prefix, the output is byte-for-byte identical.

5. **Integration**
   - The subcommand is listed in `wasmer help` alongside the existing subcommands.
   - It does not require any extra feature flags beyond what the current `create-exe` workflow already needs for metadata and C generation.


**Title:** Vendor-prefixed `animation`/`animation-name` properties and `@keyframes` rules are ignored by CSS Modules

**Description:**
When using CSS Modules (e.g., `*.module.css` with webpack’s CSS handling), animation names defined inside vendor-prefixed properties or keyframe rules are not extracted as local identifiers. This breaks modular scoping and causes undefined references in JavaScript, as well as unexpected global animation name leakage.

**Steps to reproduce:**
1. Create a CSS module file containing:
   ```css
   .box {
     -webkit-animation: fadeIn 1s;
            -moz-animation: fadeIn 1s;
                animation: fadeIn 1s;
   }

   .box2 {
     -webkit-animation-name: slide;
            -moz-animation-name: slide;
                animation-name: slide;
   }

   @-webkit-keyframes fadeIn { … }
   @-moz-keyframes fadeIn { … }
   @keyframes fadeIn { … }
   ```
2. Import the module in JavaScript and inspect the exports.
3. Only the unprefixed `animation` and `animation-name` declarations (and `@keyframes`) produce a local export for the animation name.
   The vendor-prefixed versions (`-webkit-animation`, `-moz-animation-name`, `@-webkit-keyframes`, etc.) are silently skipped.

**Expected behavior:**
Any CSS property matching the pattern `(-\w+-)?animation(-name)?` (case‑insensitive) should be treated as an animation property, extracting and scoping the animation name exactly like the unprefixed form.
Similarly, any at‑rule matching `@(-\w+-)?keyframes` should be recognised as a local keyframe definition, exposing the animation name as a module export.
For example, `-webkit-animation: fadeIn` should yield a local export `fadeIn` in the module, identical to how `animation: fadeIn` works.

**Actual behavior:**
Only `animation` and `animation-name` (and `@keyframes`) are handled. Vendor‑prefixed declarations are completely ignored, leading to missing CSS module exports (`undefined`) and global animation names that may collide with other code.

**Impact:**
- Cannot safely use vendor‑prefixed animations inside CSS Modules (a common practice for broader browser support).
- Forces developers to abandon modular scoping or use workarounds (e.g., duplicating unprefixed versions).
- May cause subtle runtime errors when the animation name is expected to be a module export but evaluates to `undefined`.

**Additional notes:**
- Custom properties (`--animation-name: …`) should **not** be treated as animation declarations and should not produce local exports.
- Common vendor prefixes include `-webkit-`, `-moz-`, `-o-`, and `-ms-`. The matching should be permissive enough to cover all valid CSS vendor prefixes (`-\w+-`).

**Environment:**
Webpack 5 with `css-loader` (CSS modules mode enabled).

fix: handle vendor prefixed keyframes and animation in CSS modules


**Title:** Improve error messages for missing namespace exports with available export hints

**Request:**
When webpack reports a `HarmonyLinkingError` for a missing export accessed via a namespace import (e.g. `export 'A' (imported as 'm') was not found in './a'`), the error message should include the **list of known exports** from the module at which the access failed. For nested namespace accesses (e.g. `m.x.B` where `x` exists but `B` does not), the error should pinpoint the exact access path step that failed and show the exports of **the module that `x` refers to**, not the top-level module.

**Specific behaviors:**
- For a top-level missing export like `m.A`, the error should append `(possible exports: a, b, c)` if that information is available; if the module’s exports are not statically known (e.g. dynamic CommonJS), append `(possible exports unknown)`.
- For a nested path `m.x.y.B` where both `x` and `y` exist but `B` is missing, the error should show the exports of the module bound to `y`, and similarly for any depth.
- If webpack can determine that an intermediate property is **definitely not provided** (e.g. `x` itself is missing), the error should reflect that and output the exports of the parent module at that point.
- The detection should use the existing `ExportsInfo` / `ExportInfo` infrastructure (especially `getReadOnlyExportInfo` and `getProvidedExports`) to walk the exact access path and stop as soon as a missing export is confirmed.

This applies only to **namespace** imports (not default or named imports where the static analysis already works differently).

provide better error message when a export name was not found


**Title:** `sourceMap.file` should respect module ID type in eval source maps

**Problem**
When using `eval-source-map` or `eval-nosources-source-map`, `EvalSourceMapDevToolPlugin` always sets `sourceMap.file` to `${moduleId}.js`. For named or deterministic module IDs (e.g., `./src/index.ts`, `./lib/utils?foo=bar`), this adds a spurious `.js` suffix that overwrites the real extension and corrupts query strings. The resulting source map file field no longer matches the actual module, breaking debugger resolution.

**Expected behavior**
- If `moduleId` is a **number** (no inherent file extension), keep the old behavior: `sourceMap.file = ${moduleId}.js`.
- If `moduleId` is a **string** (named or deterministic ID), use it verbatim: `sourceMap.file = moduleId`. This preserves the file extension and any query parameters already present in the ID.

**Affected code**
`lib/EvalSourceMapDevToolPlugin.js` — the assignment to `sourceMap.file` in the module processing loop.

**Additional constraints**
- Must not alter any other source map fields.
- Must be safe for all `optimization.moduleIds` modes, including `named`, `deterministic`, `natural`, `size`, and the default incremental numeric IDs.
- Should correctly handle IDs that contain query strings (e.g., `index.ts?foo=bar`).

fix: do not add `js` extension for eval source maps


**Title:** HotModuleReplacementPlugin produces invalid hot update manifest for numeric chunk IDs

**Context**
When webpack is configured to emit numeric chunk IDs (e.g., `optimization.chunkIds: 'deterministic'` or `'natural'`, or production mode defaults), the HMR runtime expects the `c` (updated chunks) and `r` (removed chunks) arrays in the hot update manifest to contain values of the same type as the original chunk IDs. The current `HotModuleReplacementPlugin` unconditionally uses the string keys from `records.chunkHashs`, which causes type mismatches for numeric IDs. As a result, HMR breaks with runtime errors even for simple code changes.

**Desired Behavior**
When constructing the hot update manifest inside `HotModuleReplacementPlugin` (the section that builds `hotUpdateMainContent`), the plugin must:

- For chunks that still exist in the compilation, push the chunk’s actual `id` (which may be a number) into the `c` array, **not** the string-form key from records.
- For chunks that have been removed (no longer present in `compilation.chunks`), examine the key from records: if it represents a numeric value (i.e., `+key` produces a number equal to the string representation), push that numeric value into the `r` array; otherwise push the key as-is (string).
- The logic for removed chunks must not introduce false negatives when numeric chunk IDs are used—i.e., a record key like `"10"` must become `10` in the manifest, while a key like `"chunk-name"` remains a string.

**Acceptance Criteria**
- After a hot update in a build that uses numeric chunk IDs, the hot update manifest’s `c` and `r` lists contain numbers (not strings) when the corresponding chunk IDs are numeric.
- HMR updates involving chunk addition/removal work correctly regardless of whether chunk IDs are numeric or string.
- The fix does not regress existing behaviour for projects that use string chunk IDs.

use correct string or number form of chunk id in HMR


**Title:** Scope-hoisting breaks renamed references that appear in an inner scope of the variable itself

**Description:**
When the `ModuleConcatenationPlugin` concatenates modules, it renames variables to avoid collisions. If a variable is referenced from within a child scope of that variable (e.g., a class referencing itself inside a method, or a function referencing itself inside a nested function), the renaming logic can miss that reference.

This leads to runtime misbehavior: after concatenation, the reference may keep the original (un-renamed) identifier, which now resolves to a different variable from another module with the same original name.

**Acceptance criteria:**
- When two or more concatenated modules export variables with identical names (such as classes `Foo`), and those variables are referenced inside their own inner scopes (e.g., `class Foo { test() { return Foo.value; } }`), each inner reference should resolve to the correctly renamed variable.
- The behavior should hold for any block-scoped variable (`let`, `const`, `class`, etc.) that is referenced from within a child scope where the same variable is visible without shadowing.
- The fix must not cause false positives by collecting references from inner scopes that do not resolve to the same variable (e.g., when the variable’s identifier is shadowed by a different binding in the inner scope).

**Context:**
This manifests in scope-hoisting builds (e.g., production mode with webpack 2.x/3.x) where concatenation is active. Without the correction, internal class references can accidentally point to the wrong class instance, leading to incorrect property values or method calls.


## Implementation Request: Tree-shaking should eliminate ignored modules when `sideEffects` is enabled

### Problem
When a module is explicitly ignored (via `resolve.alias` set to `false` or via `IgnorePlugin`), webpack replaces the import with a placeholder “ignored” module. These placeholders are effectively empty and have no runtime behaviour, but with `optimization.sideEffects: true` they are **not** removed from the output bundle. This causes unnecessary modules to appear in the build, even when the ignored imports are only side-effect-only (`import "ignored-thing"`).

### Desired behaviour
- **Side-effect-free treatment:** Any module that is the result of an “ignore” decision must be treated as having **no side effects** by webpack’s tree-shaking, so it can be pruned by the `sideEffects` optimisation.
- **Elimination from the output:** When an import resolves to an ignored module and that import is *only* for side effects, the ignored module should not appear in the final bundle at all.
- **Consistent application:** This holds for:
  - Direct aliases to `false` (`resolve.alias: { 'foo': false }`).
  - Ignored modules created by `IgnorePlugin` (both resource and entry ignores).
  - Context-based dynamic imports where some of the resolved requests match an `IgnorePlugin` pattern – the ignored files must not become modules, while the non-ignored files still load normally.
- **No regression for value-imports:** If an ignored module were imported for its exports (unlikely in practice), normal module inclusion rules still apply; the change only affects side-effect-only analysis.

### Acceptance criteria
1. With `optimization.sideEffects: true`, a static `import "ignored-module"` (where the module is resolved to `false` or ignored by a plugin) **must not** result in an extra module in the output chunk list. The bundle should only contain the modules that were actually needed.
2. In a dynamic import like `import("./locales/" + lang)`, if some files inside `locales/` match an `IgnorePlugin` pattern and are imported only for side effects, only the **non-ignored** locale modules appear in the final output after the dynamic import is performed. No placeholder modules for the ignored locales remain.
3. The behaviour must still respect the standard `sideEffects` configuration in `package.json` – this request is specifically about the placeholder ignored modules (which are known to be empty), not about user-provided modules.
4. When the entry module itself is caught by an ignore rule and becomes an ignored module, that placeholder must also be side-effect-free and excluded from the output.

### Constraints / edge cases
- The ignored module placeholders are created in several places (e.g., when an alias is resolved to `false`, inside `IgnorePlugin`, and inside `ModuleDependency.createIgnoredModule`). Any code path that produces such a placeholder must mark it as side-effect-free.
- The tree-shaking decision must be based on a method that the placeholder module responds to; existing module graph analysis should not need to change beyond correctly recognising that these modules have no side effects.

fix: tree-shaking unused `RawModule` (#19671)


**Feature Request: Improve webpack configuration error messages with “did you mean?” hints**

### Problem
When users mistype a configuration property or use an option that has moved between major versions, webpack’s schema validation reports “unknown property” but does not guide the user toward the correct location. This leads to confusion and unnecessary debugging.

### Desired Behavior
1. **“Did you mean?” for common property misplacements**
   If a top-level or nested unknown property corresponds to a well-known misplaced key, append `Did you mean <correct path>?` to the existing `Invalid configuration object` message.
   *Example*: Using `rules` at the root should produce:
   `Did you mean module.rules?`
   Similarly, `noParse` → `module.noParse`, `splitChunks` → `optimization.splitChunks`, etc.

2. **Breaking‑change hints for deprecated options**
   When an unknown property is a removed or relocated option from a previous major version, include the correct configuration and a `(BREAKING CHANGE since webpack 5)` note.
   *Example*: `hashedModuleIds` inside `optimization` →
   `Did you mean optimization.moduleIds: "hashed" (BREAKING CHANGE since webpack 5)?`

3. **Devtool strict‑pattern enforcement**
   If the `devtool` value does not match the accepted pattern `^(inline-|hidden-|eval-)?(nosources-)?(cheap-(module-)?)?source-map$`, the error must additionally explain:
   `BREAKING CHANGE since webpack 5: The devtool option is more strict. Please strictly follow the order of the keywords in the pattern.`

### Acceptance Criteria
- All unknown property errors that match a fixed mapping (table of common typos/relocations) are augmented with a “did you mean?” suggestion.
- The suggestion text is appended directly to the existing schema validation message, preserving the original error structure.
- The mapping covers at least:
  - Top‑level `rules` → `module.rules`
  - Top‑level `loaders` → `module.rules or module.rules.*.use`
  - Top‑level `noParse` → `module.noParse`
  - `filename` → `output.filename or module.rules.*.generator.filename`
  - `file` → `output.filename`
  - `chunkFilename` / `chunkfilename` → `output.chunkFilename`
  - `ecmaVersion` / `ecmaversion` / `ecma` → `output.ecmaVersion`
  - `path` → `output.path`
  - `pathinfo` / `pathInfo` → `output.pathinfo`
  - `splitChunks` → `optimization.splitChunks`
  - `hashedModuleIds` → `'optimization.moduleIds: "hashed" (BREAKING CHANGE since webpack 5)'`
  - `namedChunks` → `'optimization.chunkIds: "named" (BREAKING CHANGE since webpack 5)'`
  - `occurrenceOrder` → `'optimization.chunkIds: "size" and optimization.moduleIds: "size" (BREAKING CHANGE since webpack 5)'`
  - `automaticNamePrefix` → `'optimization.splitChunks.[cacheGroups.*].idHint (BREAKING CHANGE since webpack 5)'`
- The existing special handing for `debug` and generic “unknown property” advice for loader options remains unchanged.
- The devtool pattern validation always appends the breaking‑change notice when the pattern fails, regardless of any other validation errors.
- No changes to the underlying schema‑validation library’s output format; hints are added only by webpack’s wrapper.

Add "did you mean" to schema validation for common errors


When multiple compilers are used (via an array config, multicompiler mode) with filesystem caching enabled (`cache: { type: "filesystem" }`) but no explicit `cache.name`, every compiler receives the same default cache name `"default"`. This means they all share the same cache directory, which can lead to cache corruption, eviction of unrelated entries, and untraceable build failures.

We should automatically assign distinct default cache names for each compiler in the array, so that the first compiler keeps the name `"default"` and each subsequent compiler receives a unique name like `default__compiler2__`, `default__compiler3__`, etc. This prevents cache collisions without requiring every multicompiler user to manually set names.

Additionally, we should warn when a compiler lacks an explicit `cache.name` and is relying on an auto-generated name. The warning should be emitted for any compiler whose cache name matches the generated pattern (i.e., ends with `__compiler<number>__`). If the compiler has a user-facing name set via the top-level `name` configuration, the warning should mention that compiler name, e.g.: `Compiler with name "3rd compiler" doesn't use cache name. Please set "cache.name" option.` The existing warning about duplicate cache names when two compilers have the same explicit name should be removed, because the new auto-generation logic eliminates the most common cause of collisions.

**Acceptance criteria:**

- When no `cache.name` is given in a multicompiler filesystem cache setup, each compiler ends up with a unique cache name (e.g., `"default"`, `"default__compiler2__"`, …).
- Compilers that provide an explicit `cache.name` use that name unchanged.
- A compiler whose cache name was not explicitly provided (i.e., was auto-generated) triggers a build warning suggesting the user set `cache.name` explicitly.
- The warning correctly includes the compiler’s configured name when available.
- The old “cache name already defined” warning is removed.

add default cache names in multicompiler mode


**Title:** `SourceMapDevToolPlugin` cannot coexist with `devtool`-generated maps or with another `SourceMapDevToolPlugin` on the same asset

---

When a build uses `devtool: 'source-map'` (or any variant that emits a source map) alongside an explicit `new webpack.SourceMapDevToolPlugin({ filename: '[file].custom.map', noSources: true })`, only the first map is generated correctly. The second instance either silently skips the asset because `asset.info.related.sourceMap` is already set, or – if forced to run – produces an empty `.map` file because the asset has been rewrapped as a `RawSource`, erasing the internal source map.

The same limitation applies when two or more `SourceMapDevToolPlugin` configurations target the same asset (e.g. one with `sourcesContent` and another without, or with different `sourceRoot`/`debugIds` settings). Only one plugin runs fully; the others are short-circuited.

**Expected behaviour:**

- Multiple source map producers operating on the same asset should all complete successfully, each generating a distinct `.map` file according to its own options (filename, `noSources`, `sourceRoot`, `debugIds`, `ignoreList`, etc.).
- The asset’s `info.related.sourceMap` must accumulate the filenames of every map that was emitted for that asset (e.g. as an array), rather than holding only the first value written.
- The plugin must be able to retrieve the original source map of the asset even after a previous plugin instance has replaced the asset’s inner source with a `RawSource`.
- Persistent cache keys for `SourceMapDevToolPlugin` should be scoped to the options that influence the generated map output (filename, `append`, module/columns flags, `noSources`, `debugIds`, `sourceRoot`, `ignoreList`, `publicPath`, `fileContext`). Without this, different plugin configurations that target the same asset path will collide in the cache, causing cross-contamination or cache misses.
- The `append` option and `debugId` comments must not interfere with one another across plugin instances. When `append` is a function, a later plugin’s `debugId` comment must still be prepended correctly at call time.

The classic use case is `devtool: 'hidden-source-map'` (no sourceMappingURL comment appended) combined with a `new webpack.SourceMapDevToolPlugin({ filename: '[file].secondary.map', noSources: true })` that produces a stripped map and appends its URL. Both maps should appear in the output and be correctly recorded in asset info. More generally, any combination of `devtool`‑implied maps and/or multiple `SourceMapDevToolPlugin` instances must be able to run on the same asset without skipping, broken output, or cache collisions.

fix: allow devtool and SourceMapDevToolPlugin to coexist on the same asset (#21001)


When generating source maps (devtool `source-map`, `eval-source-map`, etc.), the `ignoreList` property should be omitted entirely from the output when the list of ignored sources is empty. Currently, an empty array `"ignoreList":[]` is always emitted when the `ignoreList` option is not configured, and also when the configured ignore rules match no sources. This wastes space and is unnecessary—the Source Map spec treats `ignoreList` as optional.

The fix should ensure that the `SourceMapDevToolPlugin` and `EvalSourceMapDevToolPlugin` only add `ignoreList` when the resulting array has at least one entry. When the `ignoreList` option is not set or yields no matches, the property must not appear in the generated source map.

fix: omit empty ignoreList property from source maps (#20319)


### `CommonsChunkPlugin`: duplicate chunk entries in `block.chunks` after moving extracted blocks

When multiple `CommonsChunkPlugin` instances with the `async` option are configured and their `chunks` lists overlap, the same target chunk can be added to a block’s chunk list multiple times in `moveExtractedChunkBlocksToTargetChunk`. This leads to duplicate entries in `block.chunks`, which in turn can cause `__webpack_require__.e` to load the same chunk redundantly and potentially break other expectations (e.g. chunk loading counts, caching, or order guarantees).

The problematic code is the unconditional `block.chunks.unshift(targetChunk)` inside `moveExtractedChunkBlocksToTargetChunk`. It should be guarded so that `targetChunk` is inserted only when it is not already present in `block.chunks`.

**Acceptance criteria**
- In `moveExtractedChunkBlocksToTargetChunk`, before adding `targetChunk` to a block’s chunks, check whether `targetChunk` already exists in `block.chunks`. Only insert it if absent.
- No other logic in the plugin should be altered; the fix should be minimal and local to that loop.
- All existing behavior for non-overlapping configurations must remain unchanged.

CommonsChunkPlugin: Don't allow blocks to contain duplicate chunks


**Issue: Unsafe cache leads to stale source-type/size data and incomplete error messages for asset rendering**

**Observed behavior**
When using the persistent (unsafe) cache, normal modules can end up in a broken state after cache restore:
- After `updateCacheModule` copies properties from a cached module into a fresh module, it also copies the internal `_sourceTypes` and `_sourceSizes` caches. This can cause incorrect results when those properties are later accessed (e.g. during stats collection), because the restored module’s actual build data may differ from the cache.
- `cleanupForCache` unconditionally pre-computes `sourceTypes` and `size(type)` for every module, even when the module has **not** been built yet (for example, modules freshly restored from unsafe cache). This can lead to runtime errors or misleading data, because the required build information (`buildInfo`) is not available.

Additionally, when an asset module fails during code generation, the error message does not identify which module caused the failure, making debugging difficult.

**Expected behavior / invariants**
- `updateCacheModule` should **not** propagate stale `_sourceTypes` / `_sourceSizes` into the new module. Only properties that are safe to share across builds should be copied; runtime-computed caches should be left undefined.
- `cleanupForCache` should only precompute and cache source types plus sizes **after** a module has been built. If `buildInfo` is missing, it should skip that step entirely to avoid operating on partially constructed state.
- Any error thrown during asset module rendering should include the module’s identifier in the message so that the problematic asset can be easily located in the build.

**Acceptance criteria**
1. Restoring a normal module from unsafe cache does **not** carry over `_sourceTypes` or `_sourceSizes` from the cache entry; subsequent `getSourceTypes()` / `size()` calls behave correctly based on the actual restored module data.
2. `cleanupForCache` on a module that has never been built (no `buildInfo`) does **not** attempt to compute source types or sizes, avoiding crashes or false data.
3. When `AssetModulesPlugin` fails while adding rendered asset info, the thrown error includes the module identifier in its message (e.g., `\nduring rendering of asset {module.identifier()}`).

avoid copying source types and sizes cache from unsafe cache to cached module


## Feature Request: Expose the System.register context object as `__system_context__` for system library output

### Background
When webpack is configured with `output.libraryTarget: "system"` (or `library: { type: "system" }`), it emits a `System.register` call. According to the [System.register specification](https://github.com/systemjs/systemjs/blob/main/docs/system-register.md), the factory function receives a second argument—the **context object**—which provides:
- `context.meta.url`: the URL of the module
- `context.import()`: a function for dynamic imports

Currently webpack’s `System.register` wrapper only passes the `export` function to the factory; it completely ignores the context parameter. This makes it impossible for bundled code to access `import.meta`–like information or to use the System-provided `import()` primitive through the global `__system_context__` identifier that users expect (analogous to how `__webpack_require__`, `__dirname`, `__filename`, etc. are replaced).

### Request
We need to:

1. **Plumb the context argument through**
   Modify the `System.register` wrapper emitted by the system library plugin so that it calls the factory function with **both** `dynamicExport` **and** the system context (`(dynamicExport, __system_context__) => { … }`).

2. **Make `__system_context__` available to bundle code**
   Add `__system_context__` to the list of global identifiers that webpack replaces during compilation (the `REPLACEMENTS` in `APIPlugin`). The replacement should refer to a new runtime global that holds the context object provided by the host SystemJS.

3. **Emit runtime code that captures and stores the context**
   Create a runtime module that, when required, emits the assignment `${RuntimeGlobals.systemContext} = __system_context__;`. This runtime module should only be included when the library type is `"system"` and the system context runtime requirement is detected. It must be added both for the initial chunk **and** for any runtime chunks produced by code splitting, so that `__system_context__` is always correctly set in each execution context.

4. **Preserve the System.register context API**
   In the resulting bundle, `__system_context__.meta` should exist and have a `.url` property, and `__system_context__.import()` should be a function returning a `Promise`. The exact values are provided by the SystemJS host, not by webpack.

### Acceptance criteria (behavioral)
- When `library.target` is `"system"`, the top-level `System.register` factory function receives the context object as its second parameter.
- Inside the bundle, `__system_context__` is a valid reference to that context, with the properties defined by the SystemJS specification.
- Code splits (dynamically loaded chunks) also have `__system_context__` assigned to their respective module context.
- No effect on non-system library targets (no extra runtime code, no broken replacements).

### Out of scope
- Polyfilling or shimming the context when SystemJS is not the host. The runtime should simply preserve whatever the host passes; if it is missing, behavior is determined by the host environment.

Exposing System.register _context variable to bundled code.


**Feature Request: `overrides` support for `ContainerReferencePlugin` to provide custom module implementations within a remote container**

As a consumer of a remote container using `ContainerReferencePlugin`, I want to replace specific modules inside the remote with local implementations so that I can customize behavior without forking or modifying the remote itself.

Currently, the plugin accepts only `remotes` (and a non-functional `override` option that appears to be a stub). There is no way to tell the consumer-side plugin to call the remote container's `override` method with locally loaded modules when the remote is first accessed. This forces me to manually override after loading the remote, which is fragile and cannot be done synchronously before dependent code executes.

**Expected behavior:**

1. `ContainerReferencePlugin` should accept an `overrides` option (type `Record<string, string>`), analogous to `remotes`, where each key is the module path within the remote’s scope, and each value is a local module path (relative to the webpack build) that provides a function returning the override implementation.
2. When any module inside the remote container is first imported, the plugin should:
   - Load the remote container as usual.
   - Asynchronously load each override module specified in `overrides` (each overridden module becomes an async chunk).
   - Once all overrides are loaded, call the remote container’s `override(overrides)` function with an object mapping keys to the loaded factory functions.
   - Then return the remote module (or the overridden module) as the resolved export.
3. The overridden modules should be loaded in parallel with the remote initialization so there is no unnecessary delay.
4. The remote container must expose an `override` method on its public API (for example, via a promise‑based `get`/`override` pattern like the test helper). If the remote does not support overriding, the consumer should be able to fall back gracefully (the call is simply a no‑op).

This would enable micro‑frontend architectures where the shell can override specific shared libraries or services inside a remote, while the remote’s other modules remain untouched. The `overrides` map should support any number of overrides, each loaded independently.

**Use case:**

I have a remote container `ABC` that exposes `abc/hello-world` and `abc/other`. I want to override the `test` function used internally by those modules. With the new `overrides` option I could write:

```js
new ContainerReferencePlugin({
  remoteType: "var",
  remotes: { abc: "ABC" },
  overrides: { test: "./new-test" }
});
```

and in `new-test.js`:

```js
module.exports = x => `ok ${x}`;
```

The remote container’s runtime would call `ABC.override({ test: loadedOverride })` after the override async chunk loads, and subsequent `import("abc/hello-world")` would see the overridden `test` function.

add overrides feature to ContainerReferencePlugin


**Title:** `export *` in circular re-export chains may cause infinite recurrence or incorrect provided exports

**Description:**
When modules form a circular dependency chain that uses `export * from …` (star re-exports), webpack’s export discovery can enter an infinite loop or produce incorrect `providedExports`. The root cause is twofold: (1) `export *` may incorrectly provide symbols that are already provided by the module’s own direct exports or by other star-exports that have already been processed, and (2) dependent modules are re-processed even when the set of provided exports has not actually changed.

**Acceptance criteria:**
1. Given a cycle of modules that each use `export *` from the next module and also define their own named exports, the final resolved exports for any module in the cycle must equal the union of all direct named exports in the cycle (no missing symbols, no extra symbols).
2. Processing of such a cycle must terminate deterministically without exceeding reasonable recursion limits or causing a performance degradation.
3. An `export *` declaration must never present an export name as provided if that name is already provided by:
   - The module’s own local `export` declarations, or
   - An `export *` from another module that has already been included in the same dependent graph (duplicate star-export handling).
4. Re-flagging of dependent modules should only occur when the set of provided exports for a module actually differs from its previously known set. If the exports have not changed, no further work should be queued.

**Non-goals / edge cases:**
- This request only addresses circular star re-export chains; no other circular patterns (e.g., `import` + cyclic usage) are in scope.
- The fix must not break existing behaviour for non-circular or non-star re-exports.
- Performance must not regress for large dependency graphs: the new checks should be cheap and avoid unnecessary traversal.

only retrigger flagging exports in dependencies when exports really changed


**Bug: Deterministic chunk names from `splitChunks.maxSize` can collide case‑insensitively**

### Description
When `optimization.splitChunks.maxSize` is active and chunks are named (e.g. `chunkIds: "named"` or any configuration that relies on the deterministic grouping naming heuristic), the generated chunk filenames may differ only in letter casing. On case‑insensitive file systems (Windows, macOS) this leads to file collisions, causing build failures or wrong assets served in the browser.

### Steps to Reproduce
1. Use `splitChunks.maxSize` with a low threshold.
2. Have modules whose keys differ only in letter case at the same position (e.g. `file-a1` and `file-A2`).
3. Configure the build to output files directly (no content hash that would mask the collision).
4. Run the build on a case‑insensitive filesystem.

### Acceptance Criteria
- **Case‑insensitive uniqueness:** No two output chunk files may have names that are equal when compared case‑insensitively, regardless of the module key set.
- **Stable names:** For a group containing a single module, the chunk name must equal that module’s key exactly (no truncation or common‑prefix logic applied).
- **Fallback length extension:** When the initial common prefix of the first and last module keys in a group would conflict with an already‑used name (case‑insensitively), the algorithm must extend the prefix until the generated name is unique, still preferring the minimal distinguishing prefix.
- **No regression for existing unique names:** Groups that already produce case‑insensitively unique names without conflict must continue to produce the same names.
- **Performance:** The tracking of used names should not change the overall deterministic grouping complexity class.

### Expected Behavior
With modules like:
- `file-a1`
- `file-b1`
- `file-A2`
- `file-B2`

the generated chunks should get distinct filenames that are robust on all file systems, e.g. `file-a1`, `file-b1`, `file-A2`, `file-B2` (or longer but still case‑insensitively distinct). No two files should end up as `file-` (which would collide).

### Actual Behavior
Currently the naming may produce identical‑when‑lowercased chunk names (e.g. `file-a` and `file-A`), leading to overwritten files on Windows/macOS.

### Additional Context
The problem is located in the deterministic grouping helper (`deterministicGrouping.js`) which computes a common prefix of the first and last module keys. The naming must be made case‑insensitively aware by keeping a set of already‑used names (lowercased) and advancing the cut point when a collision is detected. Single‑module groups are a special case that can bypass the heuristic altogether.


**Title:** `mangleExports` incorrectly renames properties destructured from re‑exported namespace objects

**Environment:**
Webpack with `optimization.mangleExports: true` (and usually `usedExports: true` / `providedExports: true`).

**Steps to reproduce:**
1. Create a module that re‑exports a namespace, e.g.:
   ```js
   export * as obj3 from "./module2";
   ```
   where `module2.js` exports `aaa` and `bbb`.
2. In another file, import that namespace and destructure its properties:
   ```js
   import { obj3 } from "./reexport";
   const { aaa, bbb } = obj3;
   ```
3. Build with `optimization.mangleExports` enabled.

**Actual behavior:**
The destructured names (`aaa`, `bbb`) are mangled to shorter identifiers (e.g., `A`, `B`), but the runtime still expects the original export names because the namespace object comes from a re‑exported module. This results in `undefined` values or runtime errors like `Cannot read properties of undefined`.

**Expected behavior:**
When destructuring a value that is a re‑exported namespace object (as identified by the `canMangle` flag of the corresponding export info), the mangler **must not** rename the destructured property names. They must stay identical to the original exports of the re‑exported module, because the namespace’s shape is defined by that foreign module.

The same constraint applies to nested destructuring patterns that eventually reach a re‑exported namespace, e.g.:
```js
import { obj4 } from "./reexport";
// obj4.nested is a re‑exported namespace
const { nested: { obj5, obj5CanMangle } } = obj4;
```
Here `obj5` (and any deeper names that originate from a re‑export) must not be mangled, while `obj4` itself (if not a re‑export) may be mangled.

**Impact:**
This is a correctness bug: code that uses destructuring on re‑exported namespaces breaks silently after mangling, making the `mangleExports` optimization unusable for projects that rely on `export * as` patterns.

**Non‑obvious edge cases / safety constraints:**
- The fix must consult the module graph to check whether the first identifier in the destructuring chain corresponds to an export info with `isReexport() === true`.
- If the destructuring does not reference a re‑exported namespace (e.g., destructuring a property of a module whose exports are defined locally), mangling should still be allowed.
- The logic must correctly handle both top‑level destructuring (`const { a } = reexportedNs`) and nested cases (`const { outer: { inner } } = obj` where `inner` is re‑exported).
- The existing behavior for regular dot‑property access (e.g., `module.aaa`) should remain unchanged; those cases are not affected by this bug.

fix: should not mangle when destructuring a reexport


When a module’s source ends with a single-line comment (e.g. a `//# sourceMappingURL=…` comment), the code generation for library exports can append an additional statement directly after it on the same logical line, turning that statement into part of the comment. This causes a runtime error (missing exports) in output with `output.library.type: "module"` and similar situations.

The same problem can occur in concatenated modules where the generated `factoryExportsBinding` is placed immediately after the source.

Ensure that any inserted code that follows the module source cannot be consumed by a trailing line comment. For places that currently unconditionally append after the source (like `ModuleLibraryPlugin.renderModuleContent`), consider prepending instead, or guarantee that a newline separates the addition from the source. For concatenated modules, prepend a newline to the generated exports binding. The invariant is: generated code that follows the module source must always start on a new line, so that a preceding single-line comment does not swallow it.

fix: syntax error when comment is on the last line (#19805)