Open MaxDesiatov opened 4 years ago
Something to consider is whether the API should be top-level (specify your routes all at once in some sort of structure inside App
or Scene
) or more organic (like React Router which lets you have multiple routers in different parts of the app).
I’ve actually experimented with static rendering and got something up and working fairly quickly. I can make a PR if that’d be of interest...
Static websites support? Hard to specify any requirements for that until we have static HTML rendering actually working.
It would be pretty useful if there was a way to statically export all the valid routes as HTML files/serverless functions like Gatsby or Next.js do so it could be uploaded to a static host and have proper server-side 404s.
@j-f1 yes, I think I'd prefer the latter React-Router-inspired approach, otherwise I'm not sure how to make relative URL composability work from points 3. and 4. I mentioned in the issue description.
It would be pretty useful if there was a way to statically export all the valid routes as HTML files/serverless functions like Gatsby or Next.js do so it could be uploaded to a static host and have proper server-side 404s.
Totally, I'd imagine the renderer would traverse all views while generating HTML anyway, it could then record all the routes and split the generated HTML into separate files for separate routes at later stages of the rendering pipeline.
I’ve actually experimented with static rendering and got something up and working fairly quickly. I can make a PR if that’d be of interest...
@carson-katri I'm very interested! I want tokamak.dev to become a proper website with docs and demos and a landing page, all built with Tokamak as much as possible, maybe we could pre-render your TokamakDocs app with that?
Inspiration: Django, React Router, Vue Router, SwiftUI (based on old react router api), Flask, React Navigation (react native)
Some info on how to handle deep links in SwiftUI: https://medium.com/better-programming/deep-links-universal-links-and-the-swiftui-app-life-cycle-e98e38bcef6e, https://nalexn.github.io/swiftui-deep-linking/
I actually have an almost working type-safe Router package. I'm still working on the SwiftUI implementation, and then it should be able to support Tokamak after that (although it relies on PreferenceKey
which I don't quite have working in the toolbar
branch). Here's what it'd look like:
// Routes.swift
enum AppRoutes: Routes {
case orders
case orderDetails(id: Int, OrderRoutes?)
static let defaultRoute: Self = .orders
}
enum OrderRoutes: Routes {
case overview
case bill
static let defaultRoute: Self = .overview
}
// ContentView.swift
struct ContentView : View {
var body: some View {
Router(AppRoutes.self) {
Route(AppRoutes.orders) {
List(Order.sampleData) {
RouterLink($0.name, to: AppRoutes.orderDetails(id: $0.id, .overview)) // Link to a specific Route
}
}
Route(AppRoutes.orderDetails) { order in // enum cases can be used as functions
Router(OrderRoutes.self) { // Sub Routers
if case let .orderDetails(id, _) = order {
Route(OrderRoutes.overview) { OverviewView(id: id) }
Route(OrderRoutes.bill) { BillView(id: id) }
}
}
}
}
}
}
It has a RouteEncoder
and RouteDecoder
, so you can navigate directly to a route from a String
:
AppRoutes.orderDetails(id: 0, .overview) <-> "orderDetails/0/overview"
Any Codable
type (besides Collections
ATM) can also be used in a route string:
struct Todo: Codable {
let id: Int
let task: String
}
TodoRoutes.todo(.init(id: 0, task: "Pick up dinner")) <-> "todo/0/Pick%20up%20dinner"
As far as I understand, it would satisfy all the requirements from the original post, this is amazing! 👏
I wonder if it would make sense as a separate package in a separate repository so that SwiftUI people could use it without adding a dependency on Tokamak? It would need something like
#if canImport(TokamakShim)
import TokamakShim
#elseif canImport(SwiftUI)
import SwiftUI
#else
#error("Add a dependency on the Tokamak repository")
#endif
to allow linking it all without a dependency on Tokamak on Apple platforms (target dependency conditions in Package.swift
won't help because https://github.com/apple/swift-package-manager/pull/2749 was merged after SwiftPM 5.3 was branched off).
I have a separate TokamakUI organization ready, maybe it's time to move it all there together with TokamakDocs, so that we don't pollute the SwiftWasm organization?
That's seems like a good idea.
Please feel free to create a separate repository under you account in the meantime. I'll transfer the main Tokamak repo to that org and set up the permissions later next week when I get access to my Mac again, and you can transfer yours if you'd like to do so at all when you're ready.
I've got the code up at carson-katri/router
. There are definitely improvements to be made, so feel free to open issues/PRs there now. Also, it only supports SwiftUI ATM.
Just stumbled upon this routing code from the parsing library by the Point-Free folks, seems like an interesting alternative to Codable
...
I had a look at SwiftWebUI Router and it's great stuff, thank you for developing this @carson-katri! I hope it could be used with Tokamak with slight modifications.
In the meantime, I'm just spitballing some requirements for a new router API that I hope could be designed and implemented at some point in the future:
enum AdminRoute: Codable { case users case userDetails(id: Int) }