Repository navigation
Conversation
A JS module's .d.rx can declare a component, and a JS fn whose result is
`Component` hands back one. A component is a value only on a JS component's
`Component` prop or inside a factory's argument literals, where it is checked
as applied beneath that application (DV-24). This is what @solidjs/router
2.0's createRouter({ routes }) needs.
This branch has not been deployed
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.
A
.rxapp could not use@solidjs/router. A JS component applied in markup wasUNKNOWN_COMPONENT, a component passed as a value wasCOMPONENT_AS_VALUE, and a JS module's.d.rxcould not declare a component at all (PARSE). This blocks a routed version of thesolid-v2/with-reactivescripttemplate (solidjs/templates#347).Root cause
The language had no way to talk about a component that lives in JS. A
.d.rxfor a JS module accepted onlyfn,errorandtype, and the checker refused any component that was not applied in a view, because.rxhas no way to apply a value.@solidjs/router2.0 (2.0.0-next.44) needs both:createRouter({ routes })returns the router component, and each route names its page as acomponentvalue. Its links are plain<a href>; the 0.x<Router>,<Route>and<A>components are gone.What changed
Spec 09 gains MO-11 (taken by default, open to veto) with a design note that weighs three options: declared components, a routing form in the language, and a TSX route table. It takes the first, because it uses the router's API as it is and works for any Solid component library.
.d.rxmay declareexport component X(props: { … }), with TypeScript field types, optionalcatches(…)per field, andfails(…)andshape(…)after. With no children it lowers to<X />rather thanchildren={[]}, because next.44's router readsprops.childrenas its root layout.Component(orComponent<P>) is a factory. Its call runs once where it is bound, and the bound name is applied as a component (<Router />). It cannot be exported, because only its own module knows what it was given.Componentprop or inside a factory's argument literals. There it is checked as if applied, with no arguments, beneath that application: escaping failures (R-f-5), required contexts (RG-7b), the client-only first load (CN-3d) and HTML nesting (SV-7d) are all checked above<Router />for every route. DV-24 records the assumption that the library renders it beneath the application it was passed to, and the precision it costs: aprovideorerroredinside a layout route is not credited to its pages.useParamsreturns a store whose fields track;useNavigatereturns an io function), and a route's data is anawaitover its params.Both the reference (
ref/) and the crate (compiler/) implement it, with the TSX projection writing.d.tsstubs for declared components and factories. New scenarios: S-module-5 (declared components and component values) and S-module-6 (the router), both checked only, since the runners have no router.examples/router/routes between two pages with a param and per-route data, andcompiler/test/vite.mjsbuilds it and navigates it in Chromium. It fetches@solidjs/router@2.0.0-next.44withnpm packinto.out/, so it needs the network on a fresh run. The guide gains a "Components and routers" section.How it was verified
npm testinref/: 132 scenarios pass.npm run crate: 386/386.npm run crate -- --lower: 215/215, with Solid's compiler built atref/SOLID_NEXT. With a newer../solid-next, 23 existing programs differ on both sides of this change.npm run crate -- --project: every program agrees; the oneFAIL preludeline is already onmain.npm run types, and again withRX_CRATE=1: 179/179.cargo test --release,npm testincompiler/, andnpm testintooling/rx-language-server(16 + 4) pass.SOLID_VITE_PLUGIN=<a 3.0.0-next.57 build> node compiler/test/vite.mjs: every app builds, including both router runs (links change pages without a reload, a param and its data reach the page,navigate()works, the page'sNotFoundboundary shows, back works, a deep link loads).todo (dev)fails with a refused connection, as it does onmain.with-reactivescripttemplate with a router added builds withvite build, navigates the same way in Chromium (one document load), passesrx-tsc --noEmitagainst the router's own.d.ts, passes its Vitest tests, and works under the dev server.npm run compiledfails S-guess-reask-refresh, S-latest-reask, S-solid-44 and S-solid-46, identically onmain.Left open
These are listed as decision 8 in
spec/09-modules.md.<Router>{Layout}</Router>is refused; use a parent route withchildreninstead. Markup children on<Router>are accepted and fail at run time.Error.erroredandprovideto its pages (DV-24's precision)..rxcannot pass a type argument touseParams<{ id: string }>(), so a param isstring | undefinedinrx-tsc..rxpage (overlaps Type an entry's default export; stop rx-tsc crashing on .d.rx #65), and the router under SSR.🤖 Generated with Claude Code