Repository navigation
Rust crate: front half, resolved model (CP-6), lowering through compile_program, and @reactivescript/compiler - #6
Merged
Conversation
Starts the Rust port (spec/11 CP-1a) with its front half, per issue #1: compiler/ is the `reactivescript` crate (binary `rxc`), a port of ref/src/{parse,modules,content,signature,check}.ts, plus the resolved model between check and lower (new CP-6): per module its regions, symbols and computations, each with reads (tracked / snapshot / pre, with probes and fields), writes and calls. ref/ records the same model during the checker's walk (src/model.ts, model.ts CLI). ref/crate.ts diffs the crate against ref/ on every program in scenarios/ and examples/ (280 programs, 343 modules): AST, diagnostics with messages, printed signatures and models all agree. spec/11 gains CP-6 (the model) and CP-7 (the crate today), with two decisions taken by default. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0117BoWMdD4K7882vob4J9vq
compiler/ now lowers as ref/compile/emit.ts does (emit.rs, awaits.rs) into a JS tree (js.rs), builds it as an oxc_ast::Program (oxc.rs) and hands it to solidjs-compiler's compile_program (CP-1c), styles to compile_style (CP-1d). Solid is pinned to ref/SOLID_NEXT. ref/crate.ts --lower diffs both lowerings for universal, dom and ssr: 162/162 programs (210 modules) give the same JavaScript. RX_CRATE=1 runs compile/run.ts on the crate's output: 97 pass, 0 fail, 9 divergences, as ref. Solid's SSR props hoisting orders declarations and elements by span, so the program carries the lowered module's layout rather than .rx positions (spec/11 CP-1c note, decision 5, vetoable). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0117BoWMdD4K7882vob4J9vq
ref/compile/lowered.ts compiles a scenario program for the runners, by ref (emit.ts + Solid's transform) or, with RX_CRATE=1, by `rxc lower`. compile/run.ts and ssr/run.ts both go through it. On the crate's output: compiled 97 pass, 0 fail, 9 divergences; ssr 90 pass, 0 fail, 7 skip — the same as ref. The "use server" extraction stays Solid's transformDirectives, a bundler pass applied to either output (spec/11 CP-7). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0117BoWMdD4K7882vob4J9vq
Each lowered statement, JSX element and attribute records the .rx line it was lowered from (S::At, a markup's line) at its layout position, so Solid's source map is rewritten onto the .rx file and an error's (1:N) position is reported as file.rx:line (spec/11 CP-1c, decision 6: lines, vetoable). `rxc compile app.rx --out dir [--target]` writes modules, maps and the stylesheet; `rxc lower` returns maps with `maps: true`. ref/crate.ts --lower checks all 630 maps (declarations and elements land on their lines); an off-by-one map fails 160 of 162 programs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0117BoWMdD4K7882vob4J9vq
vite-plugin-rx/ compiles .rx through the crate (`rxc app`: the program checked and compiled whole from its entry, imports by .rx path) and hands Solid's Vite plugin plain JavaScript per environment (ssr or hydratable dom), with the source map onto .rx and the stylesheet as a CSS module. `node vite-plugin-rx/test.mjs` builds every example app with Vite 8 and @solidjs/vite-plugin 3.0.0-next.50 and drives it in Chromium (todo also under the dev server): 13 pass. Solid's plugin has no front-end hook (.tsrx is routed by name; custom extensions are parsed as JSX text), so spec/11 CP-7 notes one as an upstream ask. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0117BoWMdD4K7882vob4J9vq
rx() is now a Frontend for @solidjs/vite-plugin's proposed `frontends` option instead of a pre-plugin, so .rx takes the lowered .tsrx route (lazy, refresh, server functions, CSS module). test.mjs runs against a built plugin checkout (SOLID_VITE_PLUGIN): 13 pass. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0117BoWMdD4K7882vob4J9vq
JavaScript imports only a program's entry (a dependency is a factory over the app, MO-1b), so a plainly imported .rx is an entry; the crate output's .rx imports are tagged ?rx-dep and served from a program build containing them. `rxc app` (by source) keys __rt.module by the factory, so a module two programs share is one module. Test: two programs sharing shop/catalog.rx (14 pass). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0117BoWMdD4K7882vob4J9vq
This was referenced Oct 27, 2026
…T in #9) Checked against 2c9fdd9 with #9 merged locally: crate --lower 162/162 identical (630 maps), crate 280/280, RX_CRATE compiled 97/0 (0 divergences), ssr 90/0/7. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0117BoWMdD4K7882vob4J9vq
…lain solid() - The crate's Node-API build (`--features node`, src/node.rs) over `app`, now a library function (src/app.rs) that `rxc app` also calls; a missing entry is an error instead of an empty program. - package.json for @reactivescript/compiler: one binary per platform (npm/*, as @solidjs/compiler ships), the napi loader, and the Vite front end at `/vite` (moved from vite-plugin-rx/, now calling the binding instead of spawning rxc). Solid's plugin loads it on its own (solidjs/solid-vite-plugin#471), so the examples build with `solid()`. - .github/workflows/compiler.yml: build and test each platform; on main, publish a new version by trusted publishing and tag compiler-v<version>. - spec/11: the Vite paragraph, and decision 7 (taken by default). Tests: npm test (binding, every target); compiler/test/vite.mjs 14 pass on plain solid(); crate conformance 280/280. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0117BoWMdD4K7882vob4J9vq
The module graph keys modules by POSIX path (modules::join_path), so a Windows entry (D:\a\main.rx) found none of its imports (MO-6). app() and rxc's abs() now hand it D:/a/main.rx, which Windows opens alike. Found by the compiler workflow's Windows test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0117BoWMdD4K7882vob4J9vq
…OLID_NEXT in #9) With #9 merged: crate 280/280, --lower 162/162 (630 maps), RX_CRATE=1 compiled 97/0 with no divergences, ssr 90/0/7; compiler/test/vite.mjs 14 pass. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0117BoWMdD4K7882vob4J9vq
ryansolid
pushed a commit
that referenced
this pull request
Oct 27, 2026
compiler/src/check.rs: onSettled/onFlush checks (IO_IN_REACTIVE, HOOK_CALLBACK, SETTLED_CLEANUP_UNOWNED) as in ref/src/check.ts. compiler/src/emit.rs: lowers both to __rt.onSettled/__rt.onFlush. npm --prefix ref run crate: 286/286 agree; --lower: 166/166. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0117BoWNyLJmSs7V2omSfCrh
ryansolid
pushed a commit
that referenced
this pull request
Oct 27, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WjiThB5a8ekFuYHJXkD46h # Conflicts: # ref/package.json
ryansolid
pushed a commit
that referenced
this pull request
Oct 27, 2026
…ding The harness now takes rxc and rt-web.ts from this repo (main has the crate since #6, pinned to rc.19). onFlush checked end to end: the tracker reference clearing its error with onFlush in the action passes all hidden tests; a plain write fails the one that asks for it at once. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0117BoWKEv4MghW8Ns9LeUUX
ryansolid
pushed a commit
that referenced
this pull request
Oct 27, 2026
Conflicts: Cargo.toml's crate-type comment (both builds use the cdylib), emit.rs's EF-7/EF-8 call and check.rs's returns_closure/hook check ported to the span-carrying AST (ExprKind/StmtKind), spec/11's decisions renumbered (main's 7 stays; the editor's are 8, 9, 10). The projection's BUILTINS and prelude take onSettled/onFlush (ref/crate.ts --project 170/170). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0117BoWP4zNW5bnup8XRB8md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Requested by Ryan · project thread
This PR is the Rust port as agreed in #1. It covers:
solidjs-compilerthrough the merged seams (feat(compiler): addcompile_program, compiling a caller-built Oxc program solidjs/solid#4290compile_program, feat(compiler): export the scoped-CSS engine from the Rust core, independent of TSRX solidjs/solid#4289compile_style);@reactivescript/compiler, which Solid's Vite plugin loads for.rxwith no option (feat: frontends option for languages that lower to Solid, with .rx built in solidjs/solid-vite-plugin#471).What's here
compiler/: thereactivescriptcrate, with the binaryrxc. It portsref/src/{parse,ast,modules,content,signature,check}.ts: parsing, the module graph, every diagnostic with the same message, and signatures.trackedSC-1,snapshot,preC-2), its writes (W-1, AC-3..5), its calls and the computation it is nested in. The model is compile-time only (CP-6e).emit.rsandawaits.rsportref/compile/emit.tsandawaits.tsinto a JS tree (js.rs).oxc.rsbuilds the tree as anoxc_ast::Programforcompile_program, for the universal, dom and ssr targets.compile_style.d2323b0) incompiler/Cargo.toml, equal toref/SOLID_NEXTin Repin to Solid 2.0.0-rc.19: zero recorded divergences #9..rxline..rx.file.rx:line.RX_CRATE=1,ref/compile/lowered.tsroutescompile/run.tsandssr/run.tsthrough the crate.@reactivescript/compiler(spec/11 CP-7, decision 7). This replaces the earliervite-plugin-rx/prototype.--features node,src/node.rs, the same work asrxc app), with one binary per platform (npm/), as@solidjs/compilerships./vite. An.rxmodule that JavaScript imports is a program's entry, so no option names it. Dependencies are imported as?rx-dep, and a module shared by two programs is one module (CP-4bmodule, keyed by its factory)..github/workflows/compiler.ymlbuilds and tests five platforms. On main it publishes a new version by trusted publishing, gated on the repo variableRELEASES. The one-time npm setup is incompiler/README.mdunder Releasing.Verification (on rc.19, with #9 merged)
npm --prefix ref run crate.d.rx, modelnpm --prefix ref run crate -- --lowerRX_CRATE=1 npm --prefix ref run compiledRX_CRATE=1 npm --prefix ref run ssrnpm testincompiler/(CI, 5 platforms)node compiler/test/vite.mjssolid()(#471) and run in Chromium, the todo app also under the dev server, and two programs sharing one moduleNot yet done:
.rxare untested;Decisions taken by default (veto in spec/11)
ref/beyond verdicts, byte for byte..rxpositions..rxpositions are lines, not columns..rxin Vite is Solid's plugin loading@reactivescript/compiler, with Node-API builds per platform.🤖 Generated with Claude Code
https://claude.ai/code/session_0117BoWMdD4K7882vob4J9vq