@solidjs/compiler 2.0.0-rc.2 → 2.0.0-rc.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +101 -8
- package/index.js +161 -17
- package/package.json +9 -9
- package/types.d.ts +157 -5
package/README.md
CHANGED
|
@@ -78,17 +78,43 @@ const result = transform(source, {
|
|
|
78
78
|
});
|
|
79
79
|
```
|
|
80
80
|
|
|
81
|
+
### TSRX (experimental)
|
|
82
|
+
|
|
83
|
+
TSRX (TypeScript Render Extensions) is a syntax for declarative UI whose constructs (`@if`/`@else`, `@for … @empty`, `@switch`/`@case`, `@try`/`@catch`/`@pending`, and `@{}` statement containers) desugar to the Solid control-flow components. `.tsrx` filenames route through the TSRX frontend automatically and compile to the same output as `@solidjs/babel-plugin`'s TSRX support, byte for byte.
|
|
84
|
+
|
|
85
|
+
```js
|
|
86
|
+
const result = transform(tsrxSource, { filename: "App.tsrx" });
|
|
87
|
+
// TSRX <style> blocks are extracted alongside the JavaScript:
|
|
88
|
+
result.css;
|
|
89
|
+
result.cssHash;
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Routing follows the filename by default (`syntax: "auto"`); pass `syntax: "tsrx"` or `syntax: "jsx"` to force a frontend regardless of filename. No extra install is needed — the shipped binaries include the frontend (Rust embedders can disable the default `tsrx` cargo feature).
|
|
93
|
+
|
|
94
|
+
Scoped `<style>` blocks are compile-time only. The compiler removes the style element, adds its `tsrx-<hash>` class to matching native and dynamic elements, scopes and prunes the CSS, and returns the stylesheet in `css` with its scope identifier in `cssHash`. Style expressions produce class-map objects, `<style ref={styles}>` initializes the requested class map, and `:global(...)` opts individual selectors out of scoping. A bundler integration must emit the returned CSS; the core compiler does not inject a runtime style helper.
|
|
95
|
+
|
|
96
|
+
Solid rejects authored TSRX lazy destructuring (`&{ … }` / `&[ … ]`). Keep accessor calls and reactive property reads explicit in Solid source.
|
|
97
|
+
|
|
98
|
+
Control-flow bindings pass through exactly as authored. `@for … index` and `@for … key` hand the callback the item as an accessor (and the index as an accessor under a custom key), and `@catch (err, reset)` receives Solid's `ErrorAccessor` — write `item()`, `i()`, `err()` as you would in JSX. Destructuring a binding in one of those positions is rejected with a diagnostic, since there is nothing to destructure; the default keyed `@for` item is a raw value and destructures as usual.
|
|
99
|
+
|
|
100
|
+
The frontend uses the community [oxc-tsrx](https://github.com/tsrx-org/oxc) parser at a pinned revision. Statement containers can be used as function bodies, statements, expressions (`const x = @{ … }`), and JSX children or expression containers. See `documentation/tsrx/frontend-notes.md` in the repository for the full frontend notes.
|
|
101
|
+
|
|
102
|
+
`projectTsrxForTypecheck(source, { filename })` is an experimental compiler-owned projection for editor and typecheck integrations. It returns independently typecheckable TSX without running the DOM/SSR/universal transforms, injecting collision-safe imports for generated Solid control-flow and dynamic-element helpers. The tooling-only path recovers common incomplete editor snapshots while normal compilation remains strict. The result also includes an authored `.tsrx` source map, exact equal-text `mappings`, processed `css`/`cssHash`, and parser-authored embedded CSS/raw-script regions. Mapping and embedded offsets use JavaScript UTF-16 string coordinates. The ranges deliberately omit generated-only text; host adapters such as Volar attach feature capabilities to them.
|
|
103
|
+
|
|
81
104
|
### Source maps
|
|
82
105
|
|
|
83
|
-
Pass `sourceMap: true` to receive a JSON source map string in `result.map`.
|
|
106
|
+
Pass `sourceMap: true` to receive a JSON source map string in `result.map`. For TSRX, the compiler composes Oxc's generated-JavaScript map through the internal TSX text projection, returning the original `.tsrx` filename and source in `sources` and `sourcesContent`. Authored expressions and lazy/accessor rewrites map back to their TSRX locations; projection-only scaffolding remains explicitly unmapped rather than being attributed to nearby syntax.
|
|
84
107
|
|
|
85
108
|
### Options
|
|
86
109
|
|
|
87
110
|
- `filename`
|
|
88
111
|
- `moduleName` (default `"@solidjs/web"`)
|
|
112
|
+
- `syntax`: `"auto"`, `"jsx"`, or `"tsrx"` (default `"auto"` — routes `.tsrx` filenames through the TSRX frontend)
|
|
89
113
|
- `generate`: `"dom"`, `"ssr"`, `"universal"`, or `"dynamic"` (default `"dom"`)
|
|
90
114
|
- `hydratable`
|
|
91
115
|
- `dev`
|
|
116
|
+
- `root` (`string`, default the working directory): the project root `sourceNames.locations` paths (and `transformSourceNames`'s `loc`) are made relative to — the same meaning as `transformDirectives`'s `root`.
|
|
117
|
+
- `sourceNames` (`boolean | { components?: boolean; bindings?: boolean; locations?: boolean }`, default follows `dev`): names as written in source, carried into output so dev/observe runtimes can label the reactive graph after minification. Unset, every kind is on when `dev: true` and off otherwise; `true`/`false` sets every kind (`sourceNames: false` opts a dev build out); the object form picks, and each kind it leaves unspecified follows `dev`. Production output (`dev: false`) is byte-identical with the option set or unset. Same shape and defaults as `@solidjs/babel-plugin`'s option. `components` emits the source tag name as `createComponent`'s third argument (`createComponent(Home, props, "Home")`) — DOM and SSR output (SSR keeps the `createComponent` call it otherwise inlines to `Comp(props)`); not universal or dynamic. `bindings` names every compiled binding effect by what it writes — `effect(…, { name: "span.textContent" })`, a hole `insert(el, v, undefined, undefined, { name: "div.children" })`, a spread `spread(el, props, false, undefined, "div")` (labelled `div.spread` / `div.children` by the runtime) — DOM output only. `locations` adds the source position beside each name the other two kinds emit, as `<path>:<line>:<column>` with the path relative to `root` (posix separators, `..` when the file is outside the root) and the column 1-based (the stack-trace and editor convention, so `http://localhost:5173/src/App.tsx:18:3` links to the right place): `createComponent(Home, props, "Home", "src/App.tsx:12:5")` — the start of the opening element — and `loc` right after `name` in a binding's options, `effect(…, { name: "div.class", loc: "src/App.tsx:14:7" })` — the attribute's start, a hole's `{`, a spread's `{...props}` (a spread's location rides as one more positional string after the tag). Nothing is emitted without a `filename`. The production runtimes ignore the names. These are the JSX-level kinds only: naming the primitives themselves is the separate `transformSourceNames` pass below, which the build tool runs on every module independently of the JSX compiler
|
|
92
118
|
- `sourceMap`
|
|
93
119
|
- `contextToCustomElements` (default `true`)
|
|
94
120
|
- `delegateEvents`
|
|
@@ -105,12 +131,12 @@ Pass `sourceMap: true` to receive a JSON source map string in `result.map`.
|
|
|
105
131
|
- `omitLastClosingTag`
|
|
106
132
|
- `builtIns` (default `["For", "Show", "Switch", "Match", "Loading", "Reveal", "Portal", "Repeat", "Dynamic", "Errored"]`)
|
|
107
133
|
- `requireImportSource`
|
|
108
|
-
- `
|
|
134
|
+
- `hoistProps` (default `true`; SSR only)
|
|
109
135
|
- `renderers`
|
|
110
136
|
|
|
111
137
|
### Server function directives (experimental)
|
|
112
138
|
|
|
113
|
-
`transformDirectives(code, options)` is a second pass for `"use server"`. It
|
|
139
|
+
`transformDirectives(code, options)` is a second pass for `"use server"`. It accepts ordinary JavaScript/TypeScript, including JSX/TSX. For a `.tsrx` module, run `transform()` first, then pass its generated code to `transformDirectives()` with the same original `.tsrx` filename so function IDs use the manifest path. `transformDirectives()` does not parse raw TSRX syntax itself.
|
|
114
140
|
|
|
115
141
|
```js
|
|
116
142
|
const { transformDirectives } = require("@solidjs/compiler");
|
|
@@ -126,23 +152,90 @@ result.code;
|
|
|
126
152
|
result.functions; // [{ id, name, exports }] for manifest building
|
|
127
153
|
```
|
|
128
154
|
|
|
129
|
-
|
|
155
|
+
A function-level `"use server"` function is extracted out of its lexical position, so it may only reference its own parameters and locals, module top-level bindings, and globals. Capturing anything else is a compile error. That includes `this` and `arguments` in a marked arrow, which an arrow takes from the function it was written in. Use a `function` if the server function needs its own `this` or `arguments`.
|
|
156
|
+
|
|
157
|
+
A function-level directive only works where the pass can extract the function: a function declaration (at any nesting depth), a function expression, or an arrow with a block body. Methods, getters, and setters are never extracted, so a directive on one is a compile error rather than a directive that silently does nothing. Assign a function to a property instead.
|
|
158
|
+
|
|
159
|
+
A module-level `"use server"` module can only export server functions. Its client build is rebuilt from those exports alone, so anything else would be missing from the browser bundle. Re-exports, `export *`, class and enum exports, destructured exports, and exports declared without an initializer are compile errors naming the export and its position. Type-only and `declare` exports are erased and are fine.
|
|
160
|
+
|
|
161
|
+
The runtime module defaults to `@solidjs/web/server-functions`. Function IDs are `<name>-<xxhash32(root-relative path)>`, the same in every env. The name is the function's dotted binding path, such as `handlers.save`, built from every named container on the way down (variable bindings, property keys, class names, class members, and named functions), so an id identifies a function by where it is bound rather than by its position in the file. Adding, removing, or reordering functions does not move the ids of the others. There are also experimental `transformLazy` and `transformRefresh` passes.
|
|
162
|
+
|
|
163
|
+
### Source names for primitives
|
|
164
|
+
|
|
165
|
+
`transformSourceNames(code, { filename?, locations?, root?, sourceMap? })` is the pass behind `@solidjs/vite-plugin`'s `sourceNames.primitives` option: it names reactive primitives after the identifier they are declared as, so the dev and observe runtimes label graph nodes `count` / `doubled` / `todos.title` instead of `signal` / `computed` / `store.title`. With `locations` (default `true` — the pass only runs for the dev and observe postures) and a `filename`, the options literal also carries the call's position right after the name, `createSignal(0, { name: "count", loc: "src/store.ts:3:22" })` (`filename` relative to `root`, column 1-based); an explicit `name` is kept and `loc` still added, an explicit `loc` is never overridden. It is plain JavaScript in and out (JSX passes through untouched), which is why it is its own pass rather than a `transform()` option — primitives live in `.ts`/`.js` modules as much as in components. This standalone pass is the single owner of primitive naming: the build tool runs it on every module — `.ts`, `.js`, and JSX files alike — independently of which JSX compiler (this one or `@solidjs/babel-plugin`) handles the file's JSX, so there is no Babel counterpart and `transform()`'s `sourceNames` covers only the JSX-level kinds. `@solidjs/vite-plugin` (solid-vite-plugin #371, `solid: { sourceNames }`) runs it ahead of the JSX transform for the dev and `observe` postures.
|
|
166
|
+
|
|
167
|
+
```js
|
|
168
|
+
const [count, setCount] = createSignal(0); // createSignal(0, { name: "count" })
|
|
169
|
+
const doubled = createMemo(() => count() * 2); // createMemo(…, { name: "doubled" })
|
|
170
|
+
const [todos, setTodos] = createStore({ list: [] }); // createStore(…, { name: "todos" })
|
|
171
|
+
export function createCounter() {
|
|
172
|
+
const [value, setValue] = createSignal(0); // { name: "createCounter.value" }
|
|
173
|
+
…
|
|
174
|
+
}
|
|
175
|
+
function Counter() {
|
|
176
|
+
const [n, setN] = createSignal(0); // { name: "n" } — no prefix in a component
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
The name comes from the first element of the array pattern, the variable binding, the object-literal property key, or the class field the call initialises; a call in any other position (a hole in the pattern, an argument, an assignment) is left alone. Inside a non-component function — anything not PascalCase: `createCounter`, `useTheme`, a method — the name is prefixed with that function's, so a composed primitive's nodes fold under it (`createCounter.value`, `createCounter.twice`); components contribute no prefix, and anonymous callbacks inherit the nearest named function. Only calls that resolve to imports from `solid-js` or `@solidjs/signals` are named (aliases and namespace imports included; a shadowing local or another library's `createSignal` is not). The pass never overrides an explicit `name`, leaves a spread or non-literal options argument alone, fills omitted positional arguments with `void 0`, and reaches the call through `as`/`satisfies`/`!` and type arguments. Named: `createSignal`, `createMemo`, `createOptimistic`, `createStore`, `createOptimisticStore`, `createProjection`. A two-argument `createStore(x, y)` is only named when `y` is a non-empty object literal of option keys (`shallow`/`name`) — otherwise it may be a derive passed by reference with its seed.
|
|
130
181
|
|
|
131
182
|
## Rust compiler core
|
|
132
183
|
|
|
133
184
|
The crate also exposes a host-independent Rust API. The crate name is `solidjs-compiler`; the Node `transform()` delegates to the same core.
|
|
134
185
|
|
|
135
186
|
```rust
|
|
136
|
-
use solidjs_compiler::{
|
|
187
|
+
use solidjs_compiler::{
|
|
188
|
+
compile, project_tsrx_for_typecheck, CompileOptions,
|
|
189
|
+
TsrxTypecheckProjectionOptions,
|
|
190
|
+
};
|
|
137
191
|
|
|
138
192
|
let output = compile(
|
|
139
193
|
"const view = <div>{name()}</div>;",
|
|
140
194
|
&CompileOptions::default(),
|
|
141
195
|
)?;
|
|
196
|
+
|
|
197
|
+
let tsrx_source = "export function View() @{ <div /> }";
|
|
198
|
+
let virtual_tsx =
|
|
199
|
+
project_tsrx_for_typecheck(tsrx_source, &TsrxTypecheckProjectionOptions::default())?;
|
|
142
200
|
```
|
|
143
201
|
|
|
144
202
|
`CompileOptions::default()` uses `module_name: "@solidjs/web"` and the same control-flow `built_ins` as the Babel plugin. Build with `--no-default-features` when embedding without the Node-API adapter.
|
|
145
203
|
|
|
204
|
+
A frontend that builds its own Oxc AST instead of source text hands the program to `compile_program`, which runs the same back ends `compile` reaches after parsing. The program must be allocated in the allocator passed beside it, and `source` must be its `source_text`: the authored text its spans index, so source maps and diagnostics land on authored positions (keep authored spans on carried-over nodes and leave synthesized nodes at `SPAN`). The caller must build against the same Oxc release as this crate.
|
|
205
|
+
|
|
206
|
+
```rust
|
|
207
|
+
use oxc_allocator::Allocator;
|
|
208
|
+
use solidjs_compiler::{compile_program, CompileOptions};
|
|
209
|
+
|
|
210
|
+
let allocator = Allocator::default();
|
|
211
|
+
let program = my_frontend::lower(&allocator, authored_source)?; // oxc_ast::ast::Program
|
|
212
|
+
let output = compile_program(&allocator, program, authored_source, &CompileOptions::default())?;
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
TSRX's scoped-CSS engine is exported as `solidjs_compiler::style` for other frontends, in every build (it does not need the `tsrx` feature). It has no dependency on TSRX syntax or Oxc: describe the elements a `<style>` block governs as `Element` values, and `compile_style` returns the scoped stylesheet, its hash, the class map and the ids of the elements to annotate, the same bytes a `.tsrx` file with that stylesheet at that `StyleLocation` gets.
|
|
216
|
+
|
|
217
|
+
```rust
|
|
218
|
+
use solidjs_compiler::style::{compile_style, Element, ElementKind, StyleInput, StyleKind, StyleLocation};
|
|
219
|
+
|
|
220
|
+
let elements = [Element {
|
|
221
|
+
id: 1,
|
|
222
|
+
kind: ElementKind::Native("div".into()),
|
|
223
|
+
attributes: Vec::new(),
|
|
224
|
+
has_spread: false,
|
|
225
|
+
children: Vec::new(),
|
|
226
|
+
}];
|
|
227
|
+
let output = compile_style(StyleInput {
|
|
228
|
+
css: "div { color: red }",
|
|
229
|
+
location: StyleLocation { filename: "view.rx", line: 3, column: 4 },
|
|
230
|
+
elements: &elements,
|
|
231
|
+
kind: StyleKind::Block,
|
|
232
|
+
minify: false,
|
|
233
|
+
})?;
|
|
234
|
+
// output.css, output.hash, output.class_map, output.scoped_elements
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
The unstable Rust typecheck projection reports embedded ranges in authored UTF-8 bytes. The N-API adapter converts those ranges to UTF-16 code units for JavaScript tooling.
|
|
238
|
+
|
|
146
239
|
> **Stability:** the Rust API is unstable while the compiler is pre-1.0. Options, output, and error types may change in any release — pin an exact revision when embedding it.
|
|
147
240
|
|
|
148
241
|
## Performance
|
|
@@ -151,9 +244,9 @@ Compared against `@solidjs/babel-plugin` compiling identical sources under ident
|
|
|
151
244
|
|
|
152
245
|
| Workload | babel-plugin | compiler | Speedup |
|
|
153
246
|
| ----------------------------------------------- | -----------: | -------: | ------: |
|
|
154
|
-
| Fixture corpus (88 files, 175 KB, all 10 modes) |
|
|
155
|
-
| 129 KB single module |
|
|
156
|
-
| 1 MB single module |
|
|
247
|
+
| Fixture corpus (88 files, 175 KB, all 10 modes) | 440 ms | 19 ms | 23x |
|
|
248
|
+
| 129 KB single module | 545 ms | 9.4 ms | 58x |
|
|
249
|
+
| 1 MB single module | 24,975 ms | 70 ms | 355x |
|
|
157
250
|
|
|
158
251
|
Native throughput stays roughly flat as input grows, while Babel's per-file cost grows super-linearly.
|
|
159
252
|
|
package/index.js
CHANGED
|
@@ -10,24 +10,68 @@ function transform(code, options) {
|
|
|
10
10
|
throw new TypeError("@solidjs/compiler transform() expects source code as a string");
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
const nativeOptions = validateOptions(code, options);
|
|
13
|
+
const nativeOptions = hostRoot(validateOptions(code, options));
|
|
14
14
|
const result = native.transform(code, nativeOptions);
|
|
15
|
-
|
|
15
|
+
const output = {
|
|
16
16
|
code: result.code,
|
|
17
17
|
map: result.map ?? null
|
|
18
18
|
};
|
|
19
|
+
// Preserve the established JSX result shape. Native TSRX transforms always
|
|
20
|
+
// return a CSS string (including `""` when no styles are present), which
|
|
21
|
+
// makes the sidecar fields a route-specific extension.
|
|
22
|
+
if (result.css != null) {
|
|
23
|
+
output.css = result.css;
|
|
24
|
+
output.cssHash = result.cssHash ?? null;
|
|
25
|
+
}
|
|
26
|
+
return output;
|
|
19
27
|
}
|
|
20
28
|
|
|
21
29
|
function transformAsync(code, options) {
|
|
22
30
|
return Promise.resolve().then(() => transform(code, options));
|
|
23
31
|
}
|
|
24
32
|
|
|
33
|
+
function projectTsrxForTypecheck(code, options) {
|
|
34
|
+
if (typeof code !== "string") {
|
|
35
|
+
throw new TypeError(
|
|
36
|
+
"@solidjs/compiler projectTsrxForTypecheck() expects source code as a string"
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
const nativeOptions = validateTypecheckProjectionOptions(options);
|
|
40
|
+
const result = native.projectTsrxForTypecheck(code, nativeOptions);
|
|
41
|
+
return {
|
|
42
|
+
code: result.code,
|
|
43
|
+
map: result.map,
|
|
44
|
+
mappings: result.mappings,
|
|
45
|
+
css: result.css,
|
|
46
|
+
cssHash: result.cssHash ?? null,
|
|
47
|
+
embeddedRegions: result.embeddedRegions
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function validateTypecheckProjectionOptions(options) {
|
|
52
|
+
if (options == null) return options;
|
|
53
|
+
if (typeof options !== "object" || Array.isArray(options)) {
|
|
54
|
+
throw new TypeError(
|
|
55
|
+
"@solidjs/compiler projectTsrxForTypecheck() expects options to be an object"
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
for (const key of Object.keys(options)) {
|
|
59
|
+
if (key !== "filename") {
|
|
60
|
+
throw new Error(`@solidjs/compiler received unknown option \`${key}\``);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (options.filename !== undefined && typeof options.filename !== "string") {
|
|
64
|
+
throw new TypeError("@solidjs/compiler `filename` option must be a string");
|
|
65
|
+
}
|
|
66
|
+
return options;
|
|
67
|
+
}
|
|
68
|
+
|
|
25
69
|
function transformDirectives(code, options) {
|
|
26
70
|
if (typeof code !== "string") {
|
|
27
71
|
throw new TypeError("@solidjs/compiler transformDirectives() expects source code as a string");
|
|
28
72
|
}
|
|
29
73
|
|
|
30
|
-
const nativeOptions = validateDirectivesOptions(options);
|
|
74
|
+
const nativeOptions = hostRoot(validateDirectivesOptions(options));
|
|
31
75
|
const result = native.transformDirectives(code, nativeOptions);
|
|
32
76
|
return {
|
|
33
77
|
code: result.code,
|
|
@@ -75,6 +119,47 @@ function transformRefreshAsync(code, options) {
|
|
|
75
119
|
return Promise.resolve().then(() => transformRefresh(code, options));
|
|
76
120
|
}
|
|
77
121
|
|
|
122
|
+
function transformSourceNames(code, options) {
|
|
123
|
+
if (typeof code !== "string") {
|
|
124
|
+
throw new TypeError("@solidjs/compiler transformSourceNames() expects source code as a string");
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const nativeOptions = hostRoot(validateSourceNamesOptions(options));
|
|
128
|
+
const result = native.transformSourceNames(code, nativeOptions);
|
|
129
|
+
return {
|
|
130
|
+
code: result.code,
|
|
131
|
+
map: result.map ?? null
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function transformSourceNamesAsync(code, options) {
|
|
136
|
+
return Promise.resolve().then(() => transformSourceNames(code, options));
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const sourceNamesOptionKeys = new Set(["filename", "locations", "root", "sourceMap"]);
|
|
140
|
+
|
|
141
|
+
function validateSourceNamesOptions(options) {
|
|
142
|
+
if (options == null) return options;
|
|
143
|
+
if (typeof options !== "object" || Array.isArray(options)) {
|
|
144
|
+
throw new TypeError("@solidjs/compiler transformSourceNames() expects options to be an object");
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const nativeOptions = {};
|
|
148
|
+
for (const [key, value] of Object.entries(options)) {
|
|
149
|
+
if (!sourceNamesOptionKeys.has(key)) {
|
|
150
|
+
throw new Error(`@solidjs/compiler received unknown option \`${key}\``);
|
|
151
|
+
}
|
|
152
|
+
if ((key === "filename" || key === "root") && typeof value !== "string") {
|
|
153
|
+
throw new TypeError(`@solidjs/compiler \`${key}\` option must be a string`);
|
|
154
|
+
}
|
|
155
|
+
if ((key === "sourceMap" || key === "locations") && typeof value !== "boolean") {
|
|
156
|
+
throw new TypeError(`@solidjs/compiler \`${key}\` option must be boolean`);
|
|
157
|
+
}
|
|
158
|
+
nativeOptions[key] = value;
|
|
159
|
+
}
|
|
160
|
+
return nativeOptions;
|
|
161
|
+
}
|
|
162
|
+
|
|
78
163
|
const lazyOptionKeys = new Set(["filename", "sourceMap"]);
|
|
79
164
|
|
|
80
165
|
function validateLazyOptions(options) {
|
|
@@ -109,7 +194,8 @@ const refreshOptionKeys = new Set([
|
|
|
109
194
|
"sourceMap"
|
|
110
195
|
]);
|
|
111
196
|
|
|
112
|
-
|
|
197
|
+
// The runtime modes `solid-js/refresh` knows (its `RuntimeType`).
|
|
198
|
+
const refreshBundlers = new Set(["vite", "standard"]);
|
|
113
199
|
|
|
114
200
|
function validateRefreshOptions(options) {
|
|
115
201
|
if (options == null) return options;
|
|
@@ -132,9 +218,7 @@ function validateRefreshOptions(options) {
|
|
|
132
218
|
throw new TypeError(`@solidjs/compiler \`${key}\` option must be boolean`);
|
|
133
219
|
}
|
|
134
220
|
if (key === "bundler" && !refreshBundlers.has(value)) {
|
|
135
|
-
throw new TypeError(
|
|
136
|
-
'@solidjs/compiler `bundler` option must be "esm", "vite", "webpack5", "rspack-esm" or "standard"'
|
|
137
|
-
);
|
|
221
|
+
throw new TypeError('@solidjs/compiler `bundler` option must be "vite" or "standard"');
|
|
138
222
|
}
|
|
139
223
|
if (key === "jsx") {
|
|
140
224
|
// The Babel plugin's JSX-granularity mode (its default!) is not
|
|
@@ -213,10 +297,12 @@ function validateImportDefinition(key, value) {
|
|
|
213
297
|
|
|
214
298
|
const nativeOptionKeys = new Set([
|
|
215
299
|
"filename",
|
|
300
|
+
"root",
|
|
216
301
|
"moduleName",
|
|
217
302
|
"generate",
|
|
218
303
|
"hydratable",
|
|
219
304
|
"dev",
|
|
305
|
+
"sourceNames",
|
|
220
306
|
"sourceMap",
|
|
221
307
|
"contextToCustomElements",
|
|
222
308
|
"delegateEvents",
|
|
@@ -232,7 +318,7 @@ const nativeOptionKeys = new Set([
|
|
|
232
318
|
"staticMarker",
|
|
233
319
|
"omitNestedClosingTags",
|
|
234
320
|
"omitLastClosingTag",
|
|
235
|
-
"
|
|
321
|
+
"hoistProps",
|
|
236
322
|
"builtIns",
|
|
237
323
|
"renderers"
|
|
238
324
|
]);
|
|
@@ -277,6 +363,21 @@ function validateOptions(code, options) {
|
|
|
277
363
|
nativeOptions.validate = value;
|
|
278
364
|
continue;
|
|
279
365
|
}
|
|
366
|
+
if (key === "sourceNames") {
|
|
367
|
+
validateSourceNames(value);
|
|
368
|
+
nativeOptions.sourceNames = value;
|
|
369
|
+
continue;
|
|
370
|
+
}
|
|
371
|
+
// Removed with binding slots (2026-10-16). Still accepted, and ignored,
|
|
372
|
+
// because @solidjs/vite-plugin passes it for server-component builds.
|
|
373
|
+
if (key === "serverComponents") continue;
|
|
374
|
+
if (key === "root") {
|
|
375
|
+
if (typeof value !== "string") {
|
|
376
|
+
throw new TypeError("@solidjs/compiler `root` option must be a string");
|
|
377
|
+
}
|
|
378
|
+
nativeOptions.root = value;
|
|
379
|
+
continue;
|
|
380
|
+
}
|
|
280
381
|
if (nativeOptionKeys.has(key)) {
|
|
281
382
|
if (key === "renderers") validateRenderers(value);
|
|
282
383
|
nativeOptions[key] = value;
|
|
@@ -287,6 +388,23 @@ function validateOptions(code, options) {
|
|
|
287
388
|
return nativeOptions;
|
|
288
389
|
}
|
|
289
390
|
|
|
391
|
+
const sourceNameKinds = new Set(["components", "bindings", "locations"]);
|
|
392
|
+
|
|
393
|
+
function validateSourceNames(value) {
|
|
394
|
+
if (typeof value === "boolean") return;
|
|
395
|
+
if (typeof value !== "object" || value == null || Array.isArray(value)) {
|
|
396
|
+
throw new TypeError("@solidjs/compiler `sourceNames` option must be boolean or an object");
|
|
397
|
+
}
|
|
398
|
+
for (const [kind, enabled] of Object.entries(value)) {
|
|
399
|
+
if (!sourceNameKinds.has(kind)) {
|
|
400
|
+
throw new Error(`@solidjs/compiler received unknown \`sourceNames\` kind \`${kind}\``);
|
|
401
|
+
}
|
|
402
|
+
if (typeof enabled !== "boolean") {
|
|
403
|
+
throw new TypeError(`@solidjs/compiler \`sourceNames.${kind}\` must be boolean`);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
|
|
290
408
|
function validateRenderers(renderers) {
|
|
291
409
|
if (renderers == null) return;
|
|
292
410
|
if (!Array.isArray(renderers)) {
|
|
@@ -327,6 +445,23 @@ function tryPackage(packageName) {
|
|
|
327
445
|
}
|
|
328
446
|
}
|
|
329
447
|
|
|
448
|
+
// The binding makes `filename` relative to `root` (`loc` paths, directive
|
|
449
|
+
// hashes), resolving both against its own working directory. A WASI binding
|
|
450
|
+
// cannot see the host's (it starts at `/`), so hand it a `root` that needs
|
|
451
|
+
// none: absolute beside an absolute filename (the working directory when
|
|
452
|
+
// unset), relative beside a relative one. The result is unchanged on a native
|
|
453
|
+
// binding.
|
|
454
|
+
function hostRoot(nativeOptions) {
|
|
455
|
+
if (nativeOptions == null || typeof nativeOptions.filename !== "string") return nativeOptions;
|
|
456
|
+
const { filename, root } = nativeOptions;
|
|
457
|
+
if (path.isAbsolute(filename)) {
|
|
458
|
+
nativeOptions.root = path.resolve(root ?? ".");
|
|
459
|
+
} else if (root !== undefined && path.isAbsolute(root)) {
|
|
460
|
+
nativeOptions.root = path.relative(process.cwd(), root) || ".";
|
|
461
|
+
}
|
|
462
|
+
return nativeOptions;
|
|
463
|
+
}
|
|
464
|
+
|
|
330
465
|
function requireBinding() {
|
|
331
466
|
const explicit = process.env.SOLID_COMPILER_NATIVE;
|
|
332
467
|
if (explicit) return require(explicit);
|
|
@@ -343,12 +478,10 @@ function requireBinding() {
|
|
|
343
478
|
let nativeError;
|
|
344
479
|
const suffix = platformArchSuffix();
|
|
345
480
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
}
|
|
351
|
-
|
|
481
|
+
// Local builds first: the published package ships no local binary (see
|
|
482
|
+
// "files"), so a `compiler.node` next to this file can only be a
|
|
483
|
+
// development build — which must shadow the installed platform package,
|
|
484
|
+
// or the monorepo's own tests silently run against the last release.
|
|
352
485
|
const localCandidates = [];
|
|
353
486
|
if (suffix) localCandidates.push(`compiler.${suffix}.node`);
|
|
354
487
|
localCandidates.push("compiler.node");
|
|
@@ -358,12 +491,20 @@ function requireBinding() {
|
|
|
358
491
|
try {
|
|
359
492
|
return require(full);
|
|
360
493
|
} catch (error) {
|
|
361
|
-
|
|
362
|
-
|
|
494
|
+
// A present-but-unloadable dev build is an error, not a fallback:
|
|
495
|
+
// degrading to the published binary would silently test stale code.
|
|
496
|
+
error.message += `\nA local development build (${file}) exists but could not be loaded. Rebuild with \`pnpm run build:debug\` or delete it to use the installed @solidjs/compiler-* package.`;
|
|
497
|
+
throw error;
|
|
363
498
|
}
|
|
364
499
|
}
|
|
365
500
|
}
|
|
366
501
|
|
|
502
|
+
if (suffix) {
|
|
503
|
+
const next = tryPackage(`@solidjs/compiler-${suffix}`);
|
|
504
|
+
if (next.binding) return next.binding;
|
|
505
|
+
if (next.error) nativeError = next.error;
|
|
506
|
+
}
|
|
507
|
+
|
|
367
508
|
const wasi = requireWasi();
|
|
368
509
|
if (wasi) return wasi;
|
|
369
510
|
|
|
@@ -405,10 +546,13 @@ function isMissingPackage(error, packageName) {
|
|
|
405
546
|
module.exports = {
|
|
406
547
|
transform,
|
|
407
548
|
transformAsync,
|
|
549
|
+
projectTsrxForTypecheck,
|
|
408
550
|
transformDirectives,
|
|
409
551
|
transformDirectivesAsync,
|
|
410
552
|
transformLazy,
|
|
411
553
|
transformLazyAsync,
|
|
412
554
|
transformRefresh,
|
|
413
|
-
transformRefreshAsync
|
|
555
|
+
transformRefreshAsync,
|
|
556
|
+
transformSourceNames,
|
|
557
|
+
transformSourceNamesAsync
|
|
414
558
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solidjs/compiler",
|
|
3
3
|
"description": "Solid's native Oxc JSX compiler",
|
|
4
|
-
"version": "2.0.0-rc.
|
|
4
|
+
"version": "2.0.0-rc.20",
|
|
5
5
|
"author": "Ryan Carniato",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"bench": "pnpm run build && node scripts/bench.mjs",
|
|
31
31
|
"lint": "cargo clippy --manifest-path ./Cargo.toml -- -D warnings",
|
|
32
32
|
"test": "pnpm run test:rust && pnpm run build:debug && vitest run",
|
|
33
|
-
"test:rust": "cargo test --manifest-path ./Cargo.toml && cargo test --manifest-path ./Cargo.toml --no-default-features",
|
|
33
|
+
"test:rust": "cargo test --manifest-path ./Cargo.toml && cargo test --manifest-path ./Cargo.toml --no-default-features && cargo test --manifest-path ./Cargo.toml --no-default-features --features tsrx",
|
|
34
34
|
"artifacts": "napi artifacts",
|
|
35
35
|
"napi:version": "napi version && node ./sync-optional-deps.mjs",
|
|
36
36
|
"create-npm-dirs": "napi create-npm-dirs"
|
|
@@ -57,16 +57,16 @@
|
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"@emnapi/core": "^1.11.3",
|
|
59
59
|
"@emnapi/runtime": "^1.11.3",
|
|
60
|
-
"@napi-rs/cli": "^3.
|
|
60
|
+
"@napi-rs/cli": "^3.10.6",
|
|
61
61
|
"@napi-rs/wasm-runtime": "^1.1.6",
|
|
62
62
|
"emnapi": "^1.11.3"
|
|
63
63
|
},
|
|
64
64
|
"optionalDependencies": {
|
|
65
|
-
"@solidjs/compiler-darwin-x64": "2.0.0-rc.
|
|
66
|
-
"@solidjs/compiler-darwin-arm64": "2.0.0-rc.
|
|
67
|
-
"@solidjs/compiler-linux-x64-gnu": "2.0.0-rc.
|
|
68
|
-
"@solidjs/compiler-linux-arm64-gnu": "2.0.0-rc.
|
|
69
|
-
"@solidjs/compiler-win32-x64-msvc": "2.0.0-rc.
|
|
70
|
-
"@solidjs/compiler-wasm32-wasi": "2.0.0-rc.
|
|
65
|
+
"@solidjs/compiler-darwin-x64": "2.0.0-rc.20",
|
|
66
|
+
"@solidjs/compiler-darwin-arm64": "2.0.0-rc.20",
|
|
67
|
+
"@solidjs/compiler-linux-x64-gnu": "2.0.0-rc.20",
|
|
68
|
+
"@solidjs/compiler-linux-arm64-gnu": "2.0.0-rc.20",
|
|
69
|
+
"@solidjs/compiler-win32-x64-msvc": "2.0.0-rc.20",
|
|
70
|
+
"@solidjs/compiler-wasm32-wasi": "2.0.0-rc.20"
|
|
71
71
|
}
|
|
72
72
|
}
|
package/types.d.ts
CHANGED
|
@@ -1,10 +1,60 @@
|
|
|
1
|
+
/** The object form of `sourceNames`: which kinds of source name to carry into output. */
|
|
2
|
+
export interface SourceNamesOptions {
|
|
3
|
+
/** Component owner labels: the tag as written, as `createComponent`'s third argument. */
|
|
4
|
+
components?: boolean;
|
|
5
|
+
/** Binding effect labels: the element and attribute (or hole) each compiled effect writes. */
|
|
6
|
+
bindings?: boolean;
|
|
7
|
+
/**
|
|
8
|
+
* Source locations beside each emitted name: `file:line:col` (`filename`
|
|
9
|
+
* relative to `root`, column 1-based) as `createComponent`'s fourth
|
|
10
|
+
* argument and as `loc` after `name` in a binding's options. Only where
|
|
11
|
+
* the name is emitted, and only with a `filename`.
|
|
12
|
+
*/
|
|
13
|
+
locations?: boolean;
|
|
14
|
+
}
|
|
15
|
+
|
|
1
16
|
export interface TransformOptions {
|
|
2
17
|
filename?: string;
|
|
18
|
+
/**
|
|
19
|
+
* Project root the `sourceNames.locations` paths are made relative to.
|
|
20
|
+
* Defaults to the working directory.
|
|
21
|
+
*/
|
|
22
|
+
root?: string;
|
|
3
23
|
/** Default `"@solidjs/web"`. */
|
|
4
24
|
moduleName?: string;
|
|
25
|
+
/**
|
|
26
|
+
* Source syntax frontend, matching `@solidjs/babel-plugin`: `"auto"`
|
|
27
|
+
* (default) routes `.tsrx` filenames through the TSRX frontend and
|
|
28
|
+
* everything else through standard JSX; `"tsrx"` and `"jsx"` force a
|
|
29
|
+
* frontend regardless of filename. TSRX support is experimental.
|
|
30
|
+
*/
|
|
31
|
+
syntax?: "auto" | "jsx" | "tsrx";
|
|
5
32
|
generate?: "dom" | "ssr" | "universal" | "dynamic";
|
|
6
33
|
hydratable?: boolean;
|
|
7
34
|
dev?: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Names as written in source, carried into output so the dev and observe
|
|
37
|
+
* runtimes can label the reactive graph after minification.
|
|
38
|
+
* `components`: the tag as a third `createComponent` argument
|
|
39
|
+
* (`createComponent(Home, props, "Home")`) — DOM and SSR output (SSR
|
|
40
|
+
* keeps the `createComponent` call it would otherwise inline to
|
|
41
|
+
* `Comp(props)`); not universal or dynamic. `bindings`: every compiled
|
|
42
|
+
* binding effect named by what it writes — `span.textContent`,
|
|
43
|
+
* `div.class:active`, a hole `div.children`, a spread `div.spread` — as
|
|
44
|
+
* an options argument on `effect`/`insert`/`spread`; DOM output only.
|
|
45
|
+
* `locations`: the source position (`src/App.tsx:12:5`, `filename`
|
|
46
|
+
* relative to `root`) beside each emitted name — a fourth `createComponent`
|
|
47
|
+
* argument, `loc` after `name` in a binding's options — so a console
|
|
48
|
+
* report can point at the line; nothing without a `filename`.
|
|
49
|
+
* The production runtimes ignore the names. Defaults to `dev`: unset,
|
|
50
|
+
* every kind is on in dev and off otherwise; `true`/`false` sets every
|
|
51
|
+
* kind; an object picks, and each kind it leaves unspecified follows
|
|
52
|
+
* `dev`. Primitive names (`createSignal(0, { name: "count" })`) are not a
|
|
53
|
+
* kind here — they come from the standalone `transformSourceNames` pass,
|
|
54
|
+
* which the build tool runs on every module independently of this
|
|
55
|
+
* transform.
|
|
56
|
+
*/
|
|
57
|
+
sourceNames?: boolean | SourceNamesOptions;
|
|
8
58
|
sourceMap?: boolean;
|
|
9
59
|
contextToCustomElements?: boolean;
|
|
10
60
|
delegateEvents?: boolean;
|
|
@@ -19,7 +69,10 @@ export interface TransformOptions {
|
|
|
19
69
|
validate?: boolean;
|
|
20
70
|
omitNestedClosingTags?: boolean;
|
|
21
71
|
omitLastClosingTag?: boolean;
|
|
72
|
+
/** @deprecated Ignored. Binding slots, the only thing it compiled for, are removed. */
|
|
22
73
|
serverComponents?: boolean;
|
|
74
|
+
/** SSR-only, default `true`: component props literals with getters compile to module-level constructors with shared getters (#3511). */
|
|
75
|
+
hoistProps?: boolean;
|
|
23
76
|
/** Default `["For", "Show", "Switch", "Match", "Loading", "Reveal", "Portal", "Repeat", "Dynamic", "Errored"]`. */
|
|
24
77
|
builtIns?: string[];
|
|
25
78
|
requireImportSource?: false | string;
|
|
@@ -35,6 +88,10 @@ export interface RendererOption {
|
|
|
35
88
|
export interface TransformResult {
|
|
36
89
|
code: string;
|
|
37
90
|
map?: string | null;
|
|
91
|
+
/** Extracted scoped CSS for TSRX sources. */
|
|
92
|
+
css?: string | null;
|
|
93
|
+
/** Space-separated TSRX scope hashes. */
|
|
94
|
+
cssHash?: string | null;
|
|
38
95
|
}
|
|
39
96
|
|
|
40
97
|
export function transform(code: string, options?: TransformOptions | null): TransformResult;
|
|
@@ -43,6 +100,49 @@ export function transformAsync(
|
|
|
43
100
|
options?: TransformOptions | null
|
|
44
101
|
): Promise<TransformResult>;
|
|
45
102
|
|
|
103
|
+
export interface ProjectTsrxForTypecheckOptions {
|
|
104
|
+
filename?: string;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export interface TsrxTypecheckEmbeddedRegion {
|
|
108
|
+
kind: "css" | "script";
|
|
109
|
+
/** Authored JavaScript string offset in UTF-16 code units. */
|
|
110
|
+
start: number;
|
|
111
|
+
/** Authored JavaScript string offset in UTF-16 code units. */
|
|
112
|
+
end: number;
|
|
113
|
+
content: string;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export interface TsrxTypecheckMapping {
|
|
117
|
+
/** Authored JavaScript string offset in UTF-16 code units. */
|
|
118
|
+
sourceStart: number;
|
|
119
|
+
/** Generated JavaScript string offset in UTF-16 code units. */
|
|
120
|
+
generatedStart: number;
|
|
121
|
+
sourceLength: number;
|
|
122
|
+
generatedLength: number;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export interface TsrxTypecheckProjectionResult {
|
|
126
|
+
/** Valid post-semantic-rewrite TypeScript/TSX. */
|
|
127
|
+
code: string;
|
|
128
|
+
/** JSON source map from virtual TSX back to the authored `.tsrx` source. */
|
|
129
|
+
map: string;
|
|
130
|
+
/** Exact equal-text ranges suitable for editor feature mappings. */
|
|
131
|
+
mappings: TsrxTypecheckMapping[];
|
|
132
|
+
css: string;
|
|
133
|
+
cssHash: string | null;
|
|
134
|
+
embeddedRegions: TsrxTypecheckEmbeddedRegion[];
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Experimental compiler-owned TSRX projection for typechecking and editor
|
|
139
|
+
* tooling. This API is host-independent and does not run a runtime renderer.
|
|
140
|
+
*/
|
|
141
|
+
export function projectTsrxForTypecheck(
|
|
142
|
+
code: string,
|
|
143
|
+
options?: ProjectTsrxForTypecheckOptions | null
|
|
144
|
+
): TsrxTypecheckProjectionResult;
|
|
145
|
+
|
|
46
146
|
export interface DirectiveImportDefinition {
|
|
47
147
|
kind?: "named" | "default";
|
|
48
148
|
name?: string;
|
|
@@ -77,8 +177,12 @@ export interface TransformDirectivesOptions {
|
|
|
77
177
|
|
|
78
178
|
/** One extracted server function, for building a bundler manifest. */
|
|
79
179
|
export interface ServerFunctionMeta {
|
|
80
|
-
/** The wire ID (`<hash
|
|
180
|
+
/** The wire ID (`<name>-<hash>[-<ordinal>]`). */
|
|
81
181
|
id: string;
|
|
182
|
+
/**
|
|
183
|
+
* The dotted binding path that names the function, such as
|
|
184
|
+
* `handlers.save`. `anonymous` when no enclosing binding applies.
|
|
185
|
+
*/
|
|
82
186
|
name: string;
|
|
83
187
|
/** Export names bound to this function (module-level directives only). */
|
|
84
188
|
exports: string[];
|
|
@@ -132,12 +236,12 @@ export interface TransformRefreshOptions {
|
|
|
132
236
|
*/
|
|
133
237
|
filename?: string;
|
|
134
238
|
/**
|
|
135
|
-
* Selects the HMR API
|
|
136
|
-
* `import.meta.
|
|
137
|
-
* (standard).
|
|
239
|
+
* Selects the HMR API — the runtime modes `solid-js/refresh` knows:
|
|
240
|
+
* `import.meta.hot` (vite), or `module.hot` / `import.meta.webpackHot`
|
|
241
|
+
* (standard: webpack, Rspack — the runtime probes for whichever exists).
|
|
138
242
|
* @default "standard"
|
|
139
243
|
*/
|
|
140
|
-
bundler?: "
|
|
244
|
+
bundler?: "vite" | "standard";
|
|
141
245
|
/**
|
|
142
246
|
* Wrap top-level `render()`/`hydrate()` calls (imported from
|
|
143
247
|
* `@solidjs/web`) with `hot.dispose` cleanup.
|
|
@@ -172,3 +276,51 @@ export function transformRefreshAsync(
|
|
|
172
276
|
code: string,
|
|
173
277
|
options?: TransformRefreshOptions | null
|
|
174
278
|
): Promise<TransformResult>;
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Options for the `sourceNames.primitives` pass: reactive primitives named
|
|
282
|
+
* after the identifier they are declared as. `const [count, setCount] =
|
|
283
|
+
* createSignal(0)` becomes `createSignal(0, { name: "count" })`; inside a
|
|
284
|
+
* non-component function the name is prefixed with that function's
|
|
285
|
+
* (`createCounter.count`). Only calls resolving to imports from `solid-js` /
|
|
286
|
+
* `@solidjs/signals` are named, and an explicit `name` is never overridden.
|
|
287
|
+
* Plain JavaScript in and out, so it applies to `.ts`/`.js` modules too.
|
|
288
|
+
* This standalone pass is the single owner of primitive naming: the build
|
|
289
|
+
* tool (`@solidjs/vite-plugin`) runs it on every module — `.ts`, `.js` and
|
|
290
|
+
* JSX files alike — independently of which JSX compiler (this one or
|
|
291
|
+
* `@solidjs/babel-plugin`) handles the file's JSX. `transform()`'s
|
|
292
|
+
* `sourceNames` option covers only the JSX-level kinds.
|
|
293
|
+
*/
|
|
294
|
+
export interface TransformSourceNamesOptions {
|
|
295
|
+
/**
|
|
296
|
+
* Picks the parser dialect (`.ts`, `.tsx`, `.js`, `.jsx`); TSX without
|
|
297
|
+
* one. Also the file the `loc` strings name: without one no `loc` is
|
|
298
|
+
* written.
|
|
299
|
+
*/
|
|
300
|
+
filename?: string;
|
|
301
|
+
/**
|
|
302
|
+
* Write `loc` after `name` in each options literal: the call's
|
|
303
|
+
* `file:line:col` (`filename` relative to `root`, column 1-based), so
|
|
304
|
+
* `createSignal(0, { name: "count", loc: "src/store.ts:3:22" })`. An
|
|
305
|
+
* explicit `name` is kept and `loc` still added; an explicit `loc` is
|
|
306
|
+
* never overridden. The pass only runs for the dev and observe postures,
|
|
307
|
+
* so this is on by default.
|
|
308
|
+
* @default true
|
|
309
|
+
*/
|
|
310
|
+
locations?: boolean;
|
|
311
|
+
/**
|
|
312
|
+
* Project root the `loc` paths are made relative to. Defaults to the
|
|
313
|
+
* working directory.
|
|
314
|
+
*/
|
|
315
|
+
root?: string;
|
|
316
|
+
sourceMap?: boolean;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
export function transformSourceNames(
|
|
320
|
+
code: string,
|
|
321
|
+
options?: TransformSourceNamesOptions | null
|
|
322
|
+
): TransformResult;
|
|
323
|
+
export function transformSourceNamesAsync(
|
|
324
|
+
code: string,
|
|
325
|
+
options?: TransformSourceNamesOptions | null
|
|
326
|
+
): Promise<TransformResult>;
|