Follow-up to #25063.
tsx-in-vue was supported in #25063 with a parse-retry (ts fails → retry as tsx), chosen to keep the common ts path single-parse.
However, this leaves a hole: a `lang="tsx"` block without JSX parses fine as plain ts, so the retry never fires and the lone generic comma is removed:
```vue
<script setup lang="tsx">
const identity = <T,>(x: T) => x; // → <T>(x: T) => x, breaks as TS17008
</script>
```
Since parse failure fundamentally cannot detect this, the only fix is to scan the `lang` declaration itself.
The JS host now scans the SFC once per file and passes `_oxfmtVueScriptLang: "tsx"` down to `textToDoc()`. This makes the retry obsolete, so it is removed.
This PR also settles the comma policy: keep it only where it is load-bearing.
- JSX grammar (`<T>` would be a JSX opener)
- and `.mts/.cts` (TS7060, #18928)
and remove it everywhere else, keyed on the grammar, regardless of context.
Deliberate divergence: Prettier keys on filepath and keeps the comma in ts-in-vue/svelte (while its own ts-in-md embed uses `dummy.ts` as `filepath` and removes it). Plain-TS sources now behave identically wherever they live.
Part of #16608, closes#25046.
---
Even with a simple regexp, I don't want to impact the performance of the vast majority of ts-in-vue paths.
With this approach, only tsx-in-vue use cases will be affected, and even that will be kept to a minimum since it can be handled entirely on the Rust side. (JS <-> Rust roundtrip is also slow)
Fixes#22350
Currently, the js-in-vue process involves formatting the code on the Rust side using `oxc_formatter`, converting it into an IR, transforming that into a Prettier `Doc`, serializing it into JSON, and then sending it to the JS side, where it is finally passed to Prettier.
Some types of `Docs` include multiple variations that are selected based on the `printWidth`, and all of these variations were being included as part of the JSON payload.
As a result, deep nesting caused the payload size to grow exponentially, leading to hangs.
This PR resolves the issue by sending these variations separately as shared references.
In Oxfmt, there is only one config file, but there were multiple conversion paths to the specific options used by subsequent formatters.
For example, it would generate `FormatOptions` for `oxc_formatter`, while assembling the necessary `JSON` for `prettier`.
There was a lack of consistency here, as some paths referenced the parsed `FormatConfig` while others referenced the raw JSON of `Oxfmtrc`. This inconsistency led to issues like the one mentioned in #21919.
In this PR, I have established `FormatConfig` as the single SoT, ensuring that all options are derived from it.
### Overview
Part of #16608
This PR applies `oxc_formatter` to the js-in-vue section.
However, it is not complete and is only applied to the following parts within js-in-vue:
- `script` block
- and `generic="..."`
- `v-for` LHS
- `v-slot`
In the `script` block, `external_callback` is used like a regular JS file, but it isn't for others.
TL;DR: Now you can use sort-imports for Vue files.
### Review points
The points I'd like to ask your review are the following:
- Addition of `format_node()` to `oxc_formatter`
- Made it possible to process any type that implements `Format`, not just `Program`
- The implementation of `js-in-vue` fragment was separated as much as possible to avoid impacting existing code
- `oxc_formatter` IR to prettier `Doc`
### TODOs
- [x] Planning
- [x] Implementation
- [x] Check benchmark
- [x] Check coverage
- [x] Understand & refactor
- [x] oxfmt: JS side
- [x] oxfmt: Rust side
- [x] oxfmt: to_doc.rs
- [x] oxc_formatter: fragment_format
- [x] Check benchmark again
- [x] Check coverage again
- [x] Check ecosystem-ci
- [x] Tests 👉🏻#19563
Part of #16608
Prettier's `textToDoc()` context has special handling based on hidden flags.
Initially, for Markdown, I implemented with heuristic string manipulation.
However,
- Similar processing is needed for HTML and Vue
- There are cases that cannot be handled by string manipulation alone
- Considering adding options to the `oxc_formatter` side
For these reasons, a refactoring was performed as preparation.