@rsvelte/compiler 0.2.0 → 0.3.1

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Yuichiro Yamashita
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,182 +1,322 @@
1
1
  # rsvelte
2
2
 
3
- A high-performance Rust implementation of the Svelte compiler. Drop-in replacement for `svelte/compiler` with up to 100x performance improvement.
3
+ > **⚠️ Early Stage Project** — rsvelte already passes the official Svelte 5 compiler test suite end-to-end, but it's still pre-1.0. APIs, output, and behaviour may change without notice. Use it in production at your own risk.
4
4
 
5
- ## Installation
5
+ **A Rust port of the official Svelte 5 compiler, built to slot natively into the [OXC](https://oxc.rs/) ecosystem.**
6
+
7
+ ## Why rsvelte exists
8
+
9
+ The end goal isn't "another Svelte compiler" — it's making Svelte a first-class citizen of OXC's Rust-native JavaScript/TypeScript toolchain.
10
+
11
+ Today, the native JS toolchain that has grown up around OXC — `oxlint`, `oxfmt`, [Rolldown](https://rolldown.rs/), and [`tsgo`](https://github.com/microsoft/typescript-go) (wired into `oxlint` via [`tsgolint`](https://github.com/oxc-project/tsgolint)) — can only see `.js` / `.ts` / `.jsx` / `.tsx` files. `.svelte` files are invisible to them because parsing Svelte requires running the JavaScript-based Svelte compiler, which native tools can't and won't link against. The result: Svelte developers don't get the order-of-magnitude speed-ups that the rest of the JS ecosystem is starting to take for granted.
12
+
13
+ rsvelte fixes that at the source. By porting the compiler — **and** the surrounding ecosystem hot paths (`svelte2tsx`, `svelte-check`, `vite-plugin-svelte`) — to Rust on top of OXC's own parser, codegen, and semantic stack, rsvelte gives OXC a Svelte surface it can call into directly. Once upstreamed, that surface unlocks:
14
+
15
+ - **`oxlint`** — lint `<script>` blocks and Svelte-specific patterns at OXC speed (a Rust path forward for `eslint-plugin-svelte`).
16
+ - **`oxfmt`** — format `.svelte` files alongside the rest of the project (a Rust path forward for `prettier-plugin-svelte`).
17
+ - **Rolldown** — native bundling of Svelte projects through OXC's parser stack, without a JS-side compiler hop.
18
+ - **`tsgo` + `tsgolint`** — type-checking and type-aware linting over `.svelte` files. Already wired into `@rsvelte/svelte-check` today as the correctness bridge.
19
+
20
+ Until we get there, the drop-in replacement story — `@rsvelte/compiler`, `@rsvelte/svelte-check`, `@rsvelte/vite-plugin-svelte` — lets you use rsvelte today and acts as the correctness bridge that proves the Rust port is byte-identical to upstream Svelte.
21
+
22
+ ## Packages
23
+
24
+ All packages ship under the `@rsvelte` scope on npm.
25
+
26
+ | Package | Drop-in for | Status |
27
+ |---|---|---|
28
+ | [`@rsvelte/compiler`](npm/compiler) | [`svelte/compiler`](https://svelte.dev/docs/svelte-compiler) (wasm) | ✅ 100% test compat ([details](#compatibility)) |
29
+ | [`@rsvelte/svelte2tsx`](npm/svelte2tsx) | [`svelte2tsx`](https://github.com/sveltejs/language-tools/tree/master/packages/svelte2tsx) | ✅ 245 / 245 fixtures |
30
+ | [`@rsvelte/svelte-check`](npm/svelte-check) | [`svelte-check`](https://github.com/sveltejs/language-tools/tree/master/packages/svelte-check) CLI | ✅ v1.0 — walker + overlay + tsgo backend + incremental + watch |
31
+ | [`@rsvelte/vite-plugin-svelte`](https://github.com/baseballyama/vite-plugin-svelte/tree/rsvelte) | [`@sveltejs/vite-plugin-svelte`](https://github.com/sveltejs/vite-plugin-svelte) | ✅ v1.0 — fork that routes through the NAPI compiler |
32
+ | [`@rsvelte/vite-plugin-svelte-native`](npm/vite-plugin-svelte-native) | — | NAPI bindings the Vite plugin and other Node tools consume |
33
+
34
+ See [`docs/ecosystem-implementation-plan.md`](docs/ecosystem-implementation-plan.md) for the full ecosystem port plan, including which upstream tools are intentionally **out of scope** (and where they're being routed instead — usually back to OXC).
35
+
36
+ ## Quick start
37
+
38
+ ### Use as `svelte/compiler` (wasm)
6
39
 
7
40
  ```bash
8
41
  npm install @rsvelte/compiler
9
42
  ```
10
43
 
11
- ## Usage
12
-
13
- ### Basic Usage
14
-
15
44
  ```js
16
- import { compile, parse, VERSION } from '@rsvelte/compiler';
45
+ import { compile, compileModule, parse, VERSION } from '@rsvelte/compiler';
17
46
 
18
- const result = compile('<h1>Hello {name}!</h1>', {
47
+ const result = compile('<h1>Hello, {name}!</h1>', {
48
+ generate: 'client', // or 'server'
19
49
  filename: 'App.svelte',
20
- generate: 'client',
21
50
  });
22
51
 
23
52
  console.log(result.js.code);
53
+ console.log(result.css?.code);
54
+
55
+ // Compile a Svelte module (.svelte.js / .svelte.ts)
56
+ const moduleResult = compileModule('export const count = $state(0);', {
57
+ filename: 'counter.svelte.js',
58
+ });
59
+
60
+ // Parse to AST
61
+ const ast = parse('<h1>Hello</h1>', { modern: true });
62
+
63
+ console.log(VERSION); // upstream Svelte version this build targets
24
64
  ```
25
65
 
26
- ### With Vite + vite-plugin-svelte
66
+ The public surface mirrors [`svelte/compiler`](https://svelte.dev/docs/svelte-compiler) — `compile`, `compileModule`, `parse`, and `VERSION` are all available. Output is byte-identical to the official compiler on every in-scope fixture (see [Compatibility](#compatibility)).
67
+
68
+ > **Heads-up:** a few function-valued options can't cross the wasm / NAPI boundary. See [Compiler option compatibility](#compiler-option-compatibility) before passing `cssHash` or `warningFilter`.
69
+
70
+ ### Use with Vite
27
71
 
28
- Use `resolve.alias` to replace the Svelte compiler:
72
+ [`@rsvelte/vite-plugin-svelte`](https://github.com/baseballyama/vite-plugin-svelte/tree/rsvelte) is a fork of `@sveltejs/vite-plugin-svelte` that swaps in the rsvelte compiler. The public API matches upstream exactly — your `vite.config.js` doesn't need to change.
73
+
74
+ ```bash
75
+ npm install -D @rsvelte/vite-plugin-svelte
76
+ ```
29
77
 
30
78
  ```js
31
79
  // vite.config.js
80
+ import { svelte } from '@rsvelte/vite-plugin-svelte';
32
81
  import { defineConfig } from 'vite';
33
- import { svelte } from '@sveltejs/vite-plugin-svelte';
34
82
 
35
83
  export default defineConfig({
36
- resolve: {
37
- alias: {
38
- 'svelte/compiler': '@rsvelte/compiler',
39
- },
40
- },
41
84
  plugins: [svelte()],
42
85
  });
43
86
  ```
44
87
 
45
- ## API
88
+ ### Use with SvelteKit
46
89
 
47
- ### `compile(source, options?)`
90
+ SvelteKit pulls in `@sveltejs/vite-plugin-svelte` internally, so the cleanest swap is a package-manager override that redirects the upstream plugin to the rsvelte fork. With pnpm:
48
91
 
49
- Compile a Svelte component to JavaScript.
50
-
51
- ```js
52
- const result = compile(source, {
53
- dev: false,
54
- generate: 'client', // 'client' | 'server'
55
- filename: 'Component.svelte',
56
- css: 'external', // 'injected' | 'external'
57
- // ... see CompileOptions for all options
58
- });
92
+ ```bash
93
+ pnpm add -D @rsvelte/vite-plugin-svelte
94
+ ```
59
95
 
60
- // result.js.code - Generated JavaScript
61
- // result.js.map - Source map
62
- // result.css?.code - Generated CSS (if css: 'external')
63
- // result.css?.map - CSS source map
64
- // result.warnings - Compiler warnings
65
- // result.metadata.runes - Whether component uses runes
96
+ ```jsonc
97
+ // package.json
98
+ {
99
+ "pnpm": {
100
+ "overrides": {
101
+ "@sveltejs/vite-plugin-svelte": "npm:@rsvelte/vite-plugin-svelte@^0.1.0"
102
+ }
103
+ }
104
+ }
66
105
  ```
67
106
 
68
- ### `compileModule(source, options?)`
107
+ Then `pnpm install`. No changes to `vite.config.js` or `svelte.config.js` are needed. (npm and yarn ship equivalent `overrides` / `resolutions` fields if you prefer those.)
69
108
 
70
- Compile a Svelte module (`.svelte.js` / `.svelte.ts`).
109
+ ### Type-check with `svelte-check`
71
110
 
72
- ```js
73
- const result = compileModule(source, {
74
- dev: false,
75
- generate: 'client',
76
- filename: 'utils.svelte.js',
77
- });
111
+ `@rsvelte/svelte-check` is a drop-in CLI replacement for `svelte-check`, backed by a Rust walker plus a tsgo overlay for `<script lang="ts">` diagnostics.
112
+
113
+ ```bash
114
+ npm install -D @rsvelte/svelte-check
115
+ npx svelte-check
78
116
  ```
79
117
 
80
- ### `parse(source, options?)`
118
+ Common flags:
119
+
120
+ ```bash
121
+ npx svelte-check --workspace . # type-check the current workspace
122
+ npx svelte-check --tsgo # run tsgo against the .svelte overlay (recommended)
123
+ npx svelte-check --watch # re-check on file changes
124
+ npx svelte-check --incremental # reuse cached overlay between runs
125
+ npx svelte-check --output machine # JSON-friendly output for CI
126
+ npx svelte-check --fail-on-warnings # treat warnings as errors
127
+ npx svelte-check --compiler-warnings "css-unused-selector:ignore"
128
+ ```
81
129
 
82
- Parse a Svelte component into an AST.
130
+ See `npx svelte-check --help` for the full list. The CLI flag set is a superset of upstream's — every upstream flag works, plus a few rsvelte-specific ones (`--tsgo`, `--emit-overlay`).
131
+
132
+ ### Convert `.svelte` to `.tsx` (`svelte2tsx`)
133
+
134
+ ```bash
135
+ npm install @rsvelte/svelte2tsx
136
+ ```
83
137
 
84
138
  ```js
85
- const ast = parse('<h1>Hello</h1>', {
86
- modern: true, // Use modern AST format
139
+ import { svelte2tsx } from '@rsvelte/svelte2tsx';
140
+
141
+ const result = await svelte2tsx('<h1>Hello, {name}!</h1>', {
142
+ filename: 'App.svelte',
143
+ isTsFile: true,
144
+ mode: 'ts', // or 'dts' to emit a declaration file
145
+ version: '5',
87
146
  });
147
+
148
+ console.log(result.code); // the synthesised .tsx
149
+ console.log(result.exportedNames); // { props, all }
88
150
  ```
89
151
 
90
- ### `preprocess(source, preprocessors, options?)`
152
+ Useful if you're building your own language tooling on top of the same surface `svelte-check`, the Svelte language server, and `tsc` all rely on.
91
153
 
92
- Preprocess a Svelte component (async).
154
+ ### Embed in a Rust crate
93
155
 
94
- ```js
95
- const processed = await preprocess(source, [
96
- {
97
- markup({ content, filename }) {
98
- return { code: transformedContent };
99
- },
100
- script({ content, filename }) {
101
- return { code: transformedContent };
102
- },
103
- style({ content, filename }) {
104
- return { code: transformedContent };
105
- },
106
- },
107
- ], { filename: 'App.svelte' });
156
+ ```toml
157
+ [dependencies]
158
+ svelte-compiler-rust = { git = "https://github.com/baseballyama/rsvelte" }
159
+ ```
160
+
161
+ ```rust
162
+ use svelte_compiler_rust::{compile, CompileOptions};
163
+
164
+ let source = r#"<h1>Hello, {name}!</h1>"#;
165
+ let result = compile(source, CompileOptions::default()).unwrap();
166
+ println!("{}", result.js.code);
108
167
  ```
109
168
 
110
- ### `print(ast, options?)`
169
+ The Rust API is the same surface OXC will eventually wire `oxlint` / `oxfmt` into. Unlike the JS surface, the Rust `CompileOptions` honours **every** field — including `css_hash` and `warning_filter` as real Rust closures.
111
170
 
112
- Print an AST back to source code.
171
+ ## Compiler option compatibility
113
172
 
114
- ```js
115
- const ast = parse(source, { modern: true });
116
- const { code } = print(ast);
173
+ The JS-facing surfaces (`@rsvelte/compiler` wasm bundle, `@rsvelte/vite-plugin-svelte-native` NAPI bindings) accept the full `svelte/compiler#CompileOptions` shape, but **function-valued** options can't currently cross the language boundary. The Rust core has no way to call back into JavaScript, so callback-shaped fields are accepted (so the TypeScript types stay drop-in compatible with upstream Svelte) and then **silently ignored**.
174
+
175
+ If your build relies on any of these, the value won't take effect. Use the workarounds below.
176
+
177
+ | Option | Behaviour in rsvelte (JS surface) | Workaround |
178
+ |---|---|---|
179
+ | `cssHash({ hash, name, filename, css }) => string` | Ignored. CSS scope classes fall back to the default `svelte-<base36hash>` scheme — identical to upstream Svelte's default `cssHash`. | Pre-compute the hash on the JS side and pass it as `cssHashOverride: '<hash>'` — an rsvelte-specific extension that injects a deterministic string. |
180
+ | `warningFilter(warning) => boolean` | Ignored. All compiler warnings are returned unfiltered. | Filter `result.warnings` yourself after compilation. |
181
+
182
+ Everything else (`generate`, `css`, `dev`, `hmr`, `sourcemap`, `runes`, `compatibility`, `experimental.async`, `preserveComments`, `preserveWhitespace`, `customElement`, `accessors`, `namespace`, `immutable`, `modernAst`, `discloseVersion`, `outputFilename`, `cssOutputFilename`, …) matches upstream exactly. The full list of accepted fields is mirrored in [`npm/vite-plugin-svelte-native/index.d.ts`](npm/vite-plugin-svelte-native/index.d.ts).
183
+
184
+ The Rust API (`svelte_compiler_rust::compile`) has no such restriction — `css_hash: Option<CssHashFn>` and `warning_filter: Option<WarningFilterFn>` work as real `Arc<dyn Fn>` closures.
185
+
186
+ ## Performance
187
+
188
+ Per-task benchmark across 3,637 real `.svelte` files, 10 iterations (3 warmup), against the official `svelte/compiler`:
189
+
190
+ | Task | JS (`svelte/compiler`) | Rust (single-threaded) | Rust (multi-threaded) | Multi vs JS |
191
+ |---|---:|---:|---:|---:|
192
+ | **Full pipeline** — parse / analyze / codegen | 864.8 ms | 381.1 ms | 50.1 ms | **17.3×** |
193
+ | **Parser only** — phase 1, isolated | 187.5 ms | 8.7 ms | 1.9 ms | **99.5×** |
194
+ | **`svelte2tsx`** — `.svelte` → `.tsx` generation | 306.1 ms | 115.3 ms | 16.0 ms | **19.1×** |
195
+ | **`svelte-check`** — CLI, 500-file workspace | 2,088.0 ms | 46.9 ms | 13.8 ms | **151.5×** |
196
+
197
+ > Apple M1 Pro · 10-core arm64 · 3,637 `.svelte` files · 10 iterations (3 warmup). Recorded 2026-05-24 at commit `da6b3c8`. Live numbers, charts, and reproduction steps live on the [benchmark page](https://baseballyama.github.io/rsvelte/benchmark) (or run `node scripts/run-benchmark.mjs > docs/static/benchmark-results.json` locally).
198
+
199
+ A single-threaded **100× speedup** over the JS compiler is one of this project's explicit goals — the parser is already at multi-threaded `99.5×` and `svelte-check` at `151.5×`, but the full pipeline is still climbing. Current numbers are a snapshot, not a ceiling.
200
+
201
+ ## Compatibility
202
+
203
+ <!-- svelte-target-version -->
204
+ **Targeting Svelte `v5.51.5`** ([`8ea33bf7fe86`](https://github.com/sveltejs/svelte/commit/8ea33bf7fe86)) — automatically maintained by `pnpm run update-docs`.
205
+ <!-- /svelte-target-version -->
206
+
207
+ Current compatibility with the official Svelte compiler test suite:
208
+
209
+ | Test Suite | Pass | Total | Status | Notes |
210
+ |---|---:|---:|---|---|
211
+ | Parser Modern | 22 | 22 | 100% | |
212
+ | Parser Legacy | 82 | 83 | 100% | 1 skipped (acorn vs OXC comment attachment) |
213
+ | Compiler Snapshot | 28 | 28 | 100% | |
214
+ | CSS | 179 | 179 | 100% | |
215
+ | Validator | 324 | 325 | 100% | 1 skipped (`error-mode-warn`) |
216
+ | Compiler Errors | 144 | 144 | 100% | |
217
+ | Runtime Runes | 865 | 865 | 100% | |
218
+ | Runtime Legacy | 1,202 | 1,202 | 100% | |
219
+ | Runtime Browser | 31 | 31 | 100% | |
220
+ | Hydration | 78 | 78 | 100% | |
221
+ | SSR | 82 | 82 | 100% | |
222
+ | Preprocess | 19 | 19 | 100% | |
223
+ | Print | 40 | 40 | 100% | |
224
+ | svelte2tsx | 245 | 245 | 100% | 2 skipped (`expected.error.json` error fixtures) |
225
+ | **Total (in-scope)** | **3,341** | **3,341** | **100%** | |
226
+ | Migrate | 0 | 76 | — | **Out of scope** — rsvelte is a Svelte 5 compiler port, not a 4→5 migrator |
227
+ | Sourcemaps | 0 | 0 | — | No fixtures yet |
228
+
229
+ Re-run `pnpm run test-and-update` to refresh these numbers.
230
+
231
+ ## Goals
232
+
233
+ 1. **OXC ecosystem integration** — be the Svelte surface that `oxlint`, `oxfmt`, Rolldown, and `tsgo` (via `tsgolint`) all link against. This is the project's reason for existing; everything else is a step toward it.
234
+ 2. **100% test compatibility** with the official `svelte/compiler` test suite — keeps the Rust port provably equivalent to upstream while OXC integration lands.
235
+ 3. **100× single-threaded speedup** over the JS compiler via Rust + OXC.
236
+ 4. **Drop-in replacements** for the ecosystem hot paths (`svelte/compiler`, `svelte-check`, `vite-plugin-svelte`, `svelte2tsx`) so you can adopt rsvelte today without touching the rest of your build.
237
+ 5. **Ecosystem port** — see [`docs/ecosystem-implementation-plan.md`](docs/ecosystem-implementation-plan.md) for the multi-wave plan.
238
+
239
+ ## Architecture
240
+
241
+ The directory structure mirrors `submodules/svelte/packages/svelte/src/compiler/`:
242
+
243
+ ```
244
+ src/compiler/phases/
245
+ ├── 1_parse/ # Parsing (Svelte syntax → AST)
246
+ ├── 2_analyze/ # Analysis (scope tree, bindings, rune detection)
247
+ └── 3_transform/ # Code generation (AST → JS/CSS, client + SSR)
117
248
  ```
118
249
 
119
- ### `parseCss(source)`
250
+ Key design decisions:
120
251
 
121
- Parse CSS into an AST.
252
+ - JavaScript parsing, semantic analysis, and codegen all run on OXC — the same crates `oxlint` / `oxfmt` use, so the OXC integration target stays cheap.
253
+ - Memory-efficient AST (u32 positions, `compact_str`, `bumpalo`-arena allocation on hot paths).
254
+ - Direct AST passing between phases — no re-parsing.
255
+ - Parallel processing with `rayon`.
256
+ - No backward-compat shims for internal APIs — refactor freely.
122
257
 
123
- ### `VERSION`
258
+ ## Development
124
259
 
125
- The compiler version string.
260
+ ### Setup
126
261
 
127
- ```js
128
- import { VERSION } from '@rsvelte/compiler';
129
- console.log(VERSION); // "0.1.0"
262
+ ```bash
263
+ git submodule update --init --recursive
264
+ git config core.hooksPath .githooks
265
+ pnpm install
266
+ pnpm run generate-fixtures # required before running tests
130
267
  ```
131
268
 
132
- ## Limitations
269
+ ### Build & test
133
270
 
134
- ### Callback Options Not Supported
271
+ ```bash
272
+ cargo build
273
+ cargo test # all tests
274
+ cargo test --release # recommended for full runs
275
+ cargo test --test parser_fixtures -- --nocapture # single suite
276
+ pnpm run compatibility-report # generate compatibility JSON
277
+ pnpm run test-and-update # refresh report + docs
278
+ ./scripts/bench.sh # JS vs Rust benchmark
279
+ ```
135
280
 
136
- The following options accept JavaScript callback functions and are **not currently supported** in rsvelte. These options will be silently ignored, and the default behavior will be used instead:
281
+ The pre-commit hook (`.githooks/pre-commit`) runs `cargo fmt` and `cargo clippy` automatically.
137
282
 
138
- | Option | Description | Default Behavior |
139
- |--------|-------------|-----------------|
140
- | `cssHash` | Custom function to generate CSS hash for scoping | Uses the built-in hash function (same algorithm as the official Svelte compiler default) |
141
- | `warningFilter` | Function to filter compiler warnings | All warnings are included in the result |
283
+ ### Docker (optional)
142
284
 
143
- **Why?** rsvelte is implemented in Rust and compiled to a native binary. JavaScript callback functions cannot be directly executed inside the Rust runtime. Supporting these would require crossing the Rust-JavaScript boundary for each invocation, which would negate the performance benefits.
285
+ A `Dockerfile` and `docker-compose.yml` provide a reproducible toolchain (Rust nightly + Node 22 + pnpm):
144
286
 
145
- **Workaround for `warningFilter`:** Filter warnings from the result after compilation:
287
+ ```bash
288
+ docker compose up -d
289
+ docker compose exec dev bash
290
+ docker compose exec dev cargo test
291
+ ```
146
292
 
147
- ```js
148
- const result = compile(source, options);
149
- const filteredWarnings = result.warnings.filter(
150
- (w) => w.code !== 'a11y-missing-attribute'
151
- );
293
+ VS Code Dev Containers ("Reopen in Container") also works.
294
+
295
+ ### Upgrading Svelte
296
+
297
+ ```bash
298
+ ./scripts/upgrade-svelte.sh 5.52.0
152
299
  ```
153
300
 
154
- **Workaround for `cssHash`:** Currently no workaround. The default hash function is used. If you require a custom hash, please open an issue.
301
+ Updates the Svelte submodule, rebuilds, regenerates fixtures, and refreshes the compatibility report.
302
+
303
+ ## Known incompatibilities
155
304
 
156
- ### Not Yet Implemented
305
+ ### Parser Legacy: `javascript-comments` (1 test skipped)
157
306
 
158
- | API | Status |
159
- |-----|--------|
160
- | `migrate()` | Not implemented - throws error |
161
- | `walk()` | Deprecated in Svelte 5 - throws error directing to estree-walker |
307
+ The official compiler uses acorn and attaches comments to AST nodes as `leadingComments` / `trailingComments`. rsvelte uses OXC, where comments are provided as a separate list. This only affects the legacy AST format (Svelte 4 compatibility mode) and does **not** impact compiled output or runtime behavior.
162
308
 
163
- ## Platform Support
309
+ ### Validator: `error-mode-warn` (1 test skipped)
164
310
 
165
- rsvelte ships native binaries for the following platforms:
311
+ Tests an error-mode option not yet wired through rsvelte's diagnostic pipeline. Compiled output is unaffected.
166
312
 
167
- | Platform | Architecture | Package |
168
- |----------|-------------|---------|
169
- | macOS | ARM64 (Apple Silicon) | `@rsvelte/binding-darwin-arm64` |
170
- | macOS | x64 (Intel) | `@rsvelte/binding-darwin-x64` |
171
- | Linux | x64 | `@rsvelte/binding-linux-x64-gnu` |
172
- | Linux | ARM64 | `@rsvelte/binding-linux-arm64-gnu` |
173
- | Windows | x64 | `@rsvelte/binding-win32-x64-msvc` |
313
+ ### svelte2tsx: 2 error-fixture skips
174
314
 
175
- Native binaries are installed automatically via `optionalDependencies`. If no native binary is available for your platform, an error will be thrown at runtime.
315
+ Two svelte2tsx fixtures shaped around `expected.error.json` (error-path assertions) are skipped pending a structured error-fixture runner.
176
316
 
177
- ## Svelte Compatibility
317
+ ### Function-valued compiler options (JS surface)
178
318
 
179
- rsvelte targets compatibility with **Svelte 5** (`svelte/compiler`). It passes 100% of the official Svelte compiler test suite (3028/3028 tests).
319
+ See [Compiler option compatibility](#compiler-option-compatibility). The Rust API is unaffected.
180
320
 
181
321
  ## License
182
322
 
package/package.json CHANGED
@@ -1,45 +1,31 @@
1
1
  {
2
2
  "name": "@rsvelte/compiler",
3
- "version": "0.2.0",
4
- "description": "A high-performance Rust implementation of the Svelte compiler - drop-in replacement",
5
- "author": "baseballyama",
6
3
  "type": "module",
7
- "main": "index.cjs",
8
- "module": "index.js",
9
- "types": "index.d.ts",
10
- "exports": {
11
- ".": {
12
- "types": "./index.d.ts",
13
- "import": "./index.js",
14
- "require": "./index.cjs"
15
- }
4
+ "description": "A high-performance Rust implementation of the Svelte compiler",
5
+ "version": "0.3.1",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/baseballyama/rsvelte.git"
16
10
  },
17
11
  "files": [
18
- "index.js",
19
- "index.cjs",
20
- "index.d.ts",
21
- "README.md"
12
+ "svelte_compiler_rust_bg.wasm",
13
+ "svelte_compiler_rust.js",
14
+ "svelte_compiler_rust.d.ts"
15
+ ],
16
+ "main": "svelte_compiler_rust.js",
17
+ "homepage": "https://github.com/baseballyama/rsvelte#readme",
18
+ "types": "svelte_compiler_rust.d.ts",
19
+ "sideEffects": [
20
+ "./snippets/*"
22
21
  ],
23
- "optionalDependencies": {
24
- "@rsvelte/binding-darwin-arm64": "0.2.0",
25
- "@rsvelte/binding-darwin-x64": "0.1.0",
26
- "@rsvelte/binding-linux-x64-gnu": "0.1.0",
27
- "@rsvelte/binding-linux-arm64-gnu": "0.1.0",
28
- "@rsvelte/binding-win32-x64-msvc": "0.1.0"
29
- },
30
22
  "keywords": [
31
23
  "svelte",
32
24
  "compiler",
33
25
  "rust",
34
- "napi",
35
- "performance"
26
+ "wasm"
36
27
  ],
37
- "license": "MIT",
38
- "repository": {
39
- "type": "git",
40
- "url": "https://github.com/baseballyama/svelte-compiler-rust"
41
- },
42
- "engines": {
43
- "node": ">= 18"
28
+ "bugs": {
29
+ "url": "https://github.com/baseballyama/rsvelte/issues"
44
30
  }
45
- }
31
+ }
@@ -0,0 +1,108 @@
1
+ /* tslint:disable */
2
+ /* eslint-disable */
3
+
4
+ /**
5
+ * Result of compiling a Svelte component.
6
+ */
7
+ export class CompileResultWasm {
8
+ private constructor();
9
+ free(): void;
10
+ [Symbol.dispose](): void;
11
+ readonly css: string;
12
+ readonly error: string | undefined;
13
+ readonly js: string;
14
+ readonly success: boolean;
15
+ }
16
+
17
+ /**
18
+ * Result of parsing a Svelte component.
19
+ */
20
+ export class ParseResultWasm {
21
+ private constructor();
22
+ free(): void;
23
+ [Symbol.dispose](): void;
24
+ readonly ast: string;
25
+ readonly error: string | undefined;
26
+ readonly success: boolean;
27
+ }
28
+
29
+ /**
30
+ * Compile a Svelte component to client-side JavaScript.
31
+ */
32
+ export function compile_client(source: string, name: string): CompileResultWasm;
33
+
34
+ /**
35
+ * Compile a Svelte component to server-side JavaScript.
36
+ */
37
+ export function compile_server(source: string, name: string): CompileResultWasm;
38
+
39
+ /**
40
+ * Initialize panic hook for better error messages in the browser console.
41
+ */
42
+ export function init(): void;
43
+
44
+ /**
45
+ * Parse a Svelte component and return the AST as JSON.
46
+ */
47
+ export function parse_svelte(source: string): ParseResultWasm;
48
+
49
+ /**
50
+ * Convert a Svelte component to TypeScript/TSX. Mirrors the napi `svelte2tsx`
51
+ * shape — `options_json` and the return value are JSON strings so the wasm
52
+ * boundary stays at primitive types and no bespoke `wasm_bindgen` struct is
53
+ * needed for every field of `Svelte2TsxResult`.
54
+ */
55
+ export function svelte2tsx(source: string, options_json: string): string;
56
+
57
+ /**
58
+ * Get the version of the compiler.
59
+ */
60
+ export function version(): string;
61
+
62
+ export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
63
+
64
+ export interface InitOutput {
65
+ readonly memory: WebAssembly.Memory;
66
+ readonly __wbg_compileresultwasm_free: (a: number, b: number) => void;
67
+ readonly __wbg_parseresultwasm_free: (a: number, b: number) => void;
68
+ readonly compile_client: (a: number, b: number, c: number, d: number) => number;
69
+ readonly compile_server: (a: number, b: number, c: number, d: number) => number;
70
+ readonly compileresultwasm_css: (a: number) => [number, number];
71
+ readonly compileresultwasm_error: (a: number) => [number, number];
72
+ readonly compileresultwasm_js: (a: number) => [number, number];
73
+ readonly compileresultwasm_success: (a: number) => number;
74
+ readonly parse_svelte: (a: number, b: number) => number;
75
+ readonly parseresultwasm_ast: (a: number) => [number, number];
76
+ readonly parseresultwasm_error: (a: number) => [number, number];
77
+ readonly parseresultwasm_success: (a: number) => number;
78
+ readonly svelte2tsx: (a: number, b: number, c: number, d: number) => [number, number];
79
+ readonly version: () => [number, number];
80
+ readonly init: () => void;
81
+ readonly __wbindgen_free: (a: number, b: number, c: number) => void;
82
+ readonly __wbindgen_malloc: (a: number, b: number) => number;
83
+ readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
84
+ readonly __wbindgen_externrefs: WebAssembly.Table;
85
+ readonly __wbindgen_start: () => void;
86
+ }
87
+
88
+ export type SyncInitInput = BufferSource | WebAssembly.Module;
89
+
90
+ /**
91
+ * Instantiates the given `module`, which can either be bytes or
92
+ * a precompiled `WebAssembly.Module`.
93
+ *
94
+ * @param {{ module: SyncInitInput }} module - Passing `SyncInitInput` directly is deprecated.
95
+ *
96
+ * @returns {InitOutput}
97
+ */
98
+ export function initSync(module: { module: SyncInitInput } | SyncInitInput): InitOutput;
99
+
100
+ /**
101
+ * If `module_or_path` is {RequestInfo} or {URL}, makes a request and
102
+ * for everything else, calls `WebAssembly.instantiate` directly.
103
+ *
104
+ * @param {{ module_or_path: InitInput | Promise<InitInput> }} module_or_path - Passing `InitInput` directly is deprecated.
105
+ *
106
+ * @returns {Promise<InitOutput>}
107
+ */
108
+ export default function __wbg_init (module_or_path?: { module_or_path: InitInput | Promise<InitInput> } | InitInput | Promise<InitInput>): Promise<InitOutput>;