Renderers are now packages, not features. (#387)
* feat: use synchronous router design * feat: function to get router out of dom * chore: restructure workspace to use renderers as packages, not features
This commit is contained in:
1 parent
c97ca7dff6
commit
d9546d9504
181 files changed
+487
-1463
No files matched your search
@@ -1,46 +0,0 @@
|
||||
# Parity with React
|
||||
|
||||
Parity has moved to the homepage
|
||||
|
||||
## Required services:
|
||||
|
||||
---
|
||||
|
||||
Gloo is covering a lot of these. We want to build hooks around these and provide examples on how to use them.
|
||||
https://github.com/rustwasm/gloo
|
||||
|
||||
For example, resize observer would function like this:
|
||||
|
||||
```rust
|
||||
pub static Example: Component = |cx| {
|
||||
let observer = use_resize_observer();
|
||||
|
||||
cx.render(rsx!(
|
||||
div { ref: observer.node_ref
|
||||
"Size, x: {observer.x} y: {observer.y}"
|
||||
}
|
||||
))
|
||||
}
|
||||
```
|
||||
|
||||
However, resize observing is _not_ cross-platform, so this hook (internally) needs to abstract over the rendering platform.
|
||||
|
||||
For other services, we shell out to gloo. If the gloo service doesn't exist, then we need to contribute to the project to make sure it exists.
|
||||
|
||||
| Service | Hook examples | Current Projects |
|
||||
| ---------------------------- | ------------- | ---------------- |
|
||||
| Fetch | 👀 | Reqwest/surf |
|
||||
| Local storage (cache) | 👀 | Gloo |
|
||||
| Persistent storage (IndexDB) | 👀 | 👀 |
|
||||
| WebSocket | 👀 | Gloo |
|
||||
| 3D Renderer / WebGL | 👀 | Gloo |
|
||||
| Web Worker | 👀 | 👀 |
|
||||
| Router | 👀 | 👀 |
|
||||
| Notifications | 👀 | 👀 |
|
||||
| WebRTC Client | 👀 | 👀 |
|
||||
| Service Workers | 👀 | 👀 |
|
||||
| Resize Observer | 👀 | 👀 |
|
||||
| Canvas | 👀 | 👀 |
|
||||
| Clipboard | 👀 | 👀 |
|
||||
| Fullscreen | 👀 | 👀 |
|
||||
| History API | 👀 | 👀 |
|
||||
+2
-2
@@ -44,7 +44,7 @@ To launch an app, we use the `launch` method for the specific renderer we want t
|
||||
use dioxus::prelude::*;
|
||||
|
||||
fn main() {
|
||||
dioxus::desktop::launch(app);
|
||||
dioxus_desktop::launch(app);
|
||||
}
|
||||
|
||||
fn app(cx: Scope) -> Element {
|
||||
@@ -276,7 +276,7 @@ Using components, templates, and hooks, we can build a simple app.
|
||||
use dioxus::prelude::*;
|
||||
|
||||
fn main() {
|
||||
dioxus::desktop::launch(App);
|
||||
dioxus_desktop::launch(App);
|
||||
}
|
||||
|
||||
fn App(cx: Scope) -> Element {
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
# Road map
|
||||
|
||||
This release map gives a sense of the release cadence and features per update going forward into the future. PRs are required to be squashed before merging. For each point release, we save a branch on master (0.1, 0.2, 0.3, master). Eventually, we'll remove these in favor of higher point releases when dioxus is stabilized. Any live PRs will be merged into the dev branch.
|
||||
|
||||
Until 0.3, Dioxus will be in stealth mode. The goal is to launch with a bountiful feature set and a cohesive API before OSS tears it apart :).
|
||||
|
||||
## v0.1: Bare Necessities
|
||||
|
||||
> Enable ergonomic and performant webapps
|
||||
|
||||
---
|
||||
|
||||
Dioxus Core
|
||||
|
||||
- Lifecycles for components
|
||||
- Internal event system
|
||||
- Diffing
|
||||
- Patching
|
||||
|
||||
Html macro
|
||||
|
||||
- special formatting
|
||||
- closure handlers
|
||||
- child handlers
|
||||
- iterator handlers
|
||||
|
||||
Dioxus web
|
||||
|
||||
- a
|
||||
|
||||
Dioxus CLI
|
||||
|
||||
- Develop
|
||||
- Bundle
|
||||
- Test
|
||||
|
||||
Server-side-rendering
|
||||
|
||||
- Write nodes to string
|
||||
- Integration with tide, Actix, warp
|
||||
|
||||
Dioxus WebView (desktop)
|
||||
|
||||
- One-file setup for desktop apps
|
||||
- Integration with the web browser for rapid development
|
||||
|
||||
## v0.2: Bread and butter
|
||||
|
||||
> Complex apps? CHECK
|
||||
|
||||
---
|
||||
|
||||
State management
|
||||
|
||||
- Dioxus-Reducer as the blessed redux alternative
|
||||
- Includes thunks and reducers (async dispatches)
|
||||
- Dioxus-DataFlow as the blessed recoil alternative
|
||||
- The hip, new approach for granular state
|
||||
|
||||
Dioxus CLI
|
||||
|
||||
- Visual tool?
|
||||
- Asset bundling service
|
||||
|
||||
Dioxus DevTools integration with the web
|
||||
|
||||
- Basic support for pure liveview/webview
|
||||
|
||||
## v0.3: Superpowers
|
||||
|
||||
> Enable LiveView for fullstack development
|
||||
|
||||
---
|
||||
|
||||
Dioxus LiveView
|
||||
|
||||
- Custom server built on Actix (or something fast)
|
||||
- Ergonomic builders
|
||||
- Concurrent system built into dioxus core
|
||||
|
||||
Dioxus iOS
|
||||
|
||||
- Initial support via webview
|
||||
- Look into native support based on how Flutter/SwiftUI works
|
||||
|
||||
Dioxus Android
|
||||
|
||||
## v0.4: Community
|
||||
|
||||
> Foster the incoming community
|
||||
@@ -1,26 +0,0 @@
|
||||
# Safety
|
||||
|
||||
We don't claim to be a "safe" library. We want to be 100% safe, and will create tests and validate that we are, but our priorities for this library are:
|
||||
|
||||
- productivity
|
||||
- performance
|
||||
- safety
|
||||
|
||||
We are willing to use sharp tools (ie transmuting self-referential pointer types) in order to achieve higher ergonomics (ie returning self-referential listeners).
|
||||
|
||||
However, we can only use these sharp tools if we verify that it's not possible to write user-facing code that breaks safety guarantees. For internal code... well, whoever contributes needs to understand the architecture and read the comments related to safety.
|
||||
|
||||
We are doing one of the more annoying things to do with Rust: self-referential graph structures. VNodes reference a bump arena which is contained by scope. Conveniently, the bump arenas also belong to scope, and now we have a self-referential struct.
|
||||
|
||||
We */would/* use a solution like ourborous or self_referential, but these libraries generate "imaginary code" that doesn't integrate with RA. It's simpler and easier to review if we set some rules on what is/isn't allowed.
|
||||
|
||||
Here's the two main sources of unsafety:
|
||||
- 1) vnodes, bump arenas, and scope
|
||||
- 2) context_api and use_context
|
||||
|
||||
For 1), we can fairly confidently guarantee safety by being careful about lifetime casts and by using tools like refcell as flags.
|
||||
|
||||
For 2), use_context authors (mostly state management) can implement either the Unsafe API or the Safe API. The Safe API is less performant, but will likely do everything you need. The Unsafe API is more performant, but will bite you if you don't implement it properly. Always validate with MIRI!
|
||||
|
||||
Because of 2), we provide two state management solutions (D-Reducer and D-Dataflow) that use the Unsafe API, but will still be 100% safe.
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
# Suspense, Async, and More
|
||||
|
||||
This doc goes into the design of asynchronicity in Dioxus.
|
||||
|
||||
|
||||
## for UI elements
|
||||
|
||||
`suspend`-ing a future submits an &mut future to Dioxus. the future must return VNodes. the future is still waiting before the component renders, the `.await` is dropped and tried again. users will want to attach their future to a hook so the future doesn't really get dropped.
|
||||
|
||||
|
||||
## for tasks
|
||||
|
||||
for more general tasks, we need some way of submitting a future or task into some sort of task system.
|
||||
|
||||
|
||||
`use_task()` submits a future to Dioxus. the future is polled infinitely until it finishes. The caller of `use_task` may drop, pause, restart, or insert a new the task
|
||||
|
||||
```rust
|
||||
|
||||
let task = use_hook(|| { /* */ });
|
||||
cx.poll_future()
|
||||
// let recoil_event_loop = cx.use_task(move |_| async move {
|
||||
// loop {
|
||||
// let msg = receiver.await?;
|
||||
// }
|
||||
// });
|
||||
// where suspend wraps use_task
|
||||
```
|
||||
@@ -1,29 +0,0 @@
|
||||
- [x] Move the builder API onto NodeFactory
|
||||
- [x] Transition away from names and towards compile-time safe tags
|
||||
- [x] Fix diffing of fragments
|
||||
- [x] Properly integrate memoization to prevent safety issues with children
|
||||
- [x] Understand and fix the issue with callbacks (outdated generations)
|
||||
- [x] Fix examples for core, web, ssr, and general
|
||||
- [] Finish up documentation
|
||||
- [] Polish the Recoil (Dirac?) API
|
||||
- [x] Find better names for things
|
||||
- [] get the html macro up to parity with the rsx! macro
|
||||
- [x] put warnings in for iterating w/o keys
|
||||
- [] finish up the crate for generating code blocks
|
||||
- [] make progress on the docusarus-style crate for generating the websites
|
||||
- [] build the docsite
|
||||
- [] find a way to serialize the virtualdom completely
|
||||
- [] ...some how deserialize (hydrate) the dom state?
|
||||
- [] Implement controlled inputs for select and textarea
|
||||
- [] ...somehow... noderefs....
|
||||
|
||||
- [x] soup of the use_state hook
|
||||
- [ ] wire up inline css
|
||||
- [ ] compile-time correct inline CSS
|
||||
- [ ] signals
|
||||
- [ ] cooperative scheduler
|
||||
- [ ] suspense
|
||||
- [ ] task system
|
||||
- [] wire up events for webview
|
||||
- [] JIT for class-based style engines
|
||||
- []
|
||||
@@ -1,70 +0,0 @@
|
||||
# March 3, 2021
|
||||
|
||||
Still TODO:
|
||||
- Wire up Nodebuilder to track listeners as they are added. (easyish)
|
||||
- Wire up attrs on nodes to track listeners properly
|
||||
- Could be done in the nodebuilder where the attrs are added automatically (easyish)
|
||||
- Could just inject context into the diffing algorithm (hardish)
|
||||
- Wire up component syntax (easy)
|
||||
- Wire up component calling approach (easyish)
|
||||
- Wire up component diffing (hardish)
|
||||
|
||||
|
||||
Approach:
|
||||
- move listeners out of vnode diffing
|
||||
- move listeners onto scope via nodebuilder
|
||||
- instead of a listeners list, store a list of listeners and their IDs
|
||||
- this way means the diffing algorithm doesn't need to know that context
|
||||
- This should fix our listener approach
|
||||
- The only thing from here is child component
|
||||
|
||||
|
||||
Thoughts:
|
||||
- the macros should generate a static set of attrs into a [attr] array (faster, more predictable, no allocs)
|
||||
- children should be generated as a static set if no parans are detected
|
||||
- More complex in the macro sized, unfortunately, not *too* hard
|
||||
- Listeners should also be a static set (dynamic listeners don't make too much sense)
|
||||
- use the builder syntax if you're doing something wild and need this granular control
|
||||
- Tags should also be &'static str - no reason to generate them on the fly
|
||||
|
||||
Major milestones going forward:
|
||||
- Scheduled updates
|
||||
- String renderer (and methods for accessing vdom directly as a tree of nodes)
|
||||
- good existing work on this in some places
|
||||
- Suspense
|
||||
- Child support, nested diffing
|
||||
- State management
|
||||
- Tests tests tests
|
||||
|
||||
Done so far:
|
||||
- websys
|
||||
- webview
|
||||
- rsx! macro
|
||||
- html! macro
|
||||
- lifecycles
|
||||
- scopes
|
||||
- hooks
|
||||
- context API
|
||||
- bump
|
||||
|
||||
|
||||
## Solutions from today's thinking session...
|
||||
|
||||
### To solve children:
|
||||
|
||||
- maintain a map of `ScopeIdx` to `Node` in the renderer
|
||||
- Add new patch commands
|
||||
- traverse_to_known (idx)
|
||||
- Pop known component onto stack (super easy)
|
||||
- add_known (idx)
|
||||
- Save top of stack as root associated with idx
|
||||
- remove_known (idx)
|
||||
- Remove node on top of stack from known roots
|
||||
- ... Something like this
|
||||
- Continue with BFS exploration of child components, DFS of VNodes
|
||||
- Easier to write, easier to reason about
|
||||
|
||||
### To solve listeners:
|
||||
|
||||
- Map listeners directly as attrs before diffing via a listenerhandle
|
||||
- Evaluation of nodes is now stateful where we track listeners as they are added
|
||||
Reference in new issue
Block a user