Open MrFoxPro opened 2 years ago
Now with stuff like the latest Tanstack Router being fully typed this sort of thing is picking up steam again.
I'd love to work with people on how to accomplish this within the framing of the router. Keep in mind a lot of the router is designed a specific way for performance and meta-framework integration consideration. But I'd love to do better here if people could help me.
I'm now working on a successor to solid-typefu-router5 that:
Has its own router backends. To be honest I used router5 only because I figured it must be abstracting over some really hairy web/node APIs that I had no desire at all to learn, but it turns out the history API is really small. Unfortunately router5 seems unmaintained nowadays and has a few bugs.
Has a simpler syntax for specifying router definitions, and more type-safety for parameter types. The idea is to support things like:
const router = createRouter({
blog: {
"?page: natural": 0, // "/blog?page=123" query param
".id: natural": 0, // "/blog/543" paramaterised URI component
},
cups: {
"?page: natural": 0, // "cups?page=xxx"
"cup/.cupId:uuid": { // "cups/cup/xxxx-xxx-xxx-xx"
"stage/.stageId:uuid": {} // "cups/cup/.../stage/...
}
}
}, { // types to support in parameters
/* natural: { decode(input: string): number | undefined, encode(value: number): string } */
natural: { decode: ...parseInt blah blah blah..., encode: String }
uuid: { ... }
});
The unique IDs roughly correspond to the URIs, and are, for each route (that you'd use in a type-safe Link
or navigate
): /blog
, /blog?page
, /blog/.id
, /cups
, /cups?page
, /cups/cup/.cupId
, /cups/cup/.cupId/stage/.stageId
.
In case of ambiguity in the routes, it would attempt to parse routes doing using literal path components, then path component parameters, then query parameters. If you had ambiguity because of parameters using different types, behaviour is undefined; support this by making a new type that combines the ones you need to support.
So if you navigate from "/blog/42" to "/blog/43" you do not reload any data you loaded for "/blog", but you do for "/blog/.id".
For sites where basically everything rendered by SolidJS is determinable from the URI (with a lot of REST/GraphQL/whatever in between), I think this would be quite convenient and make it so you don't need to necessarily create large context objects for any shared data.
I think this would work by an API like router.addData<ID extends RouteID<typeof router>, T>(id: ID, data: () => Promise<T>): magicNewRouterType
, and adding making data T
available when matching on a route using a Router
(like https://github.com/mikeplus64/solid-typefu-router5/blob/6ed7ef9f83030ed4a7ab597a91d7fabcb88eb1b9/example/src/index.tsx#L162) or ShowRoute
etc, similar to how params are available in solid-typefu-router5
.
I would probably keep it as minimalist as possible, leaving caching questions up to the programmer. It probably would use reactive data that gets reconcile
'd when updated though.
Repo is https://github.com/mikeplus64/solid-cartography which also seems like a much better name than solid-typefu-router5
:).
@mikeplus64 off the top of your head, do you see any reasons why the approach you took with router5 would not work with solid-router
?
I fell in love using https://github.com/mikeplus64/solid-typefu-router5 Now I'm missing this ability to see available routes and its params when using
navigate
from 'useNavigate',Link
and so on. I think it's readlly worth to implement @mikeplus64 approach here. It gives you pleasure when writing code.