v0.7.0-preview2
leptos-rs/leptosv0.7.0-preview2Apr 29, 2024by gbj
AI Summary
A pre-alpha preview of the 0.7 rewrite indicating significant internal changes, missing features, and that existing applications may not drop in easily.
Key Highlights
- Major internal rewrite of the entire framework.
- Reactive system is now `Send`/`Sync` with Arc-based alternatives.
- New renderer and `IntoView` trait implementation using type erasure.
- Arc equivalents to signal types for manual lifecycle management.
- Statically-typed route matching pattern.
Breaking Changes
- Module import structure changed (use leptos::prelude::*)
- Renaming from `create_` functions to idiomatic patterns (e.g., `signal`)
- Replaced `View` enum with statically-typed views
- Changes to SSR/hydration boilerplate
- Route definition syntax changes
- Signals now require `Send`/`Sync` by default
New Features
- Asynchronous Suspense support
- Arc signal types
- Reactive Stores
- View Transition API
- Custom HTML shell
Full Release Notes
The `-preview` here is intended to convey: Here is a mostly-working but **pre-alpha** release of what I've been working on for the last six months or so. This work can be found in [the `leptos-0.7` branch](https://github.com/leptos-rs/leptos/tree/leptos_0.7). Enough work has been done that many (but not all) of the examples in the repo are functioning. This release is a fairly complete rewrite of the internals of the entire framework. You should expect both missing APIs and bugs. Note the following: - You probably cannot just drop `0.7.0-preview2` to the `Cargo.toml` of an existing app and expect it to work - Imports have moved around a bit, to help improve discoverability, including moving from `use leptos::*;` to `use leptos::prelude::*;` and then using modules and reexports more sanely from the main crate - I've created a [`0.7.0-preview` playground](https://github.com/leptos-rs/preview/) that includes the setup of a basic app with comments. You should be able to expand from there. - There are lots of missing docs. These are easier to fill in going forward than to keep up to date during really active development. ## Examples that Work The following examples in the repo are known to work and can be useful to learn from - [`counter`](https://github.com/leptos-rs/leptos/blob/leptos_0.7/examples/counter/src/lib.rs) - [`counters`](https://github.com/leptos-rs/leptos/blob/leptos_0.7/examples/counters/src/lib.rs) - [`error_boundary`](https://github.com/leptos-rs/leptos/blob/leptos_0.7/examples/error_boundary/src/lib.rs) - [`fetch`](https://github.com/leptos-rs/leptos/blob/leptos_0.7/examples/fetch/src/lib.rs) - [`todomvc`](https://github.com/leptos-rs/leptos/blob/leptos_0.7/examples/todomvc/src/lib.rs) - [`parent_child`](https://github.com/leptos-rs/leptos/blob/leptos_0.7/examples/parent_child/src/lib.rs) - [`router`](https://github.com/leptos-rs/leptos/blob/leptos_0.7/examples/router/src/lib.rs) - [`todo_app_sqlite_axum`](https://github.com/leptos-rs/leptos/blob/leptos_0.7/examples/todo_app_sqlite_axum/src/lib.rs) - [`ssr_modes_axum`](https://github.com/leptos-rs/leptos/blob/leptos_0.7/examples/ssr_modes_axum/src/lib.rs) ## Notable Changes - I'm trying to avoid using features to change behavior as much as possible; see examples for `Cargo.toml` setup - `use leptos::prelude::*` instead of `use leptos::*` - Reactive system is now `Send`/`Sync`. In general for values being stored in signals this means you need to use `Arc` on occasion instead of `Rc`, etc. - For browser-only types stored inside signals I've tended to use the `send_wrapper` crate. Better ergonomics here are an open question - The renderer and `IntoView` trait work quite differently from before. In general, for type-erased views (`.into_view()` previously) you can use `.into_any()` or the `Either::` types. Storing a `View` in a signal, cloning it, etc. are not viable approaches any more: store data in signals and rendering views, rather than storing views in signals. - There are `Arc` equivalents to each signal type (`ArcRwSignal`, `ArcMemo`, etc.) which manage their lifecycle via reference counting rather than the reactive ownership graph. This can be used for things like iterating over nested signals (see `counters` example) and pushing signals "up" in the tree, rather than using the manual `.dispose()` and owner manipulation patterns - Continuing to move names toward more typical Rust naming patterns (`RwSignal::new()`, `signal()` instead of `create_signal()` to match `channel()`, etc.) - Suspense now uses actual async -- see examples - The router uses a more statically-typed/compile-time route segment matching pattern. I have plans for a `path!()` macro to parse the old strings into this format but it's not implemented. - Route matching is now "first match wins," rather than using a scoring algorithm. I think this should work similarly to server-side route matching, but is not exactly how the old system worked. ## Known Missing APIs - [ ] Actix integration (the playground uses Axum) - [x] `on:` on components (e82227aa07023855ac704c4f484a466109c3f8cc) - [x] spreading attributes onto components (e82227aa07023855ac704c4f484a466109c3f8cc) - [ ] `MaybeSignal` - [ ] `Signal::with()` - [ ] `cargo-leptos` hot reloading - [ ] anything animated (AnimatedShow, AnimatedRoutes, AnimatedOutlet) - [ ] Portals - [ ] slots - [ ] islands? - ... will add more here ## Steps before `-alpha` - [ ] Migrate remaining examples - Missing features (above) - [ ] Update docs - [ ] Update tests - [ ] Add a `!Send/!Sync` thread-local arena for browser-type signals ## What's Helpful? Try things out, see what breaks, see what feels good. How can we improve the module imports? What are pain points? etc. Feel free to comment here [or on Discord in the `#preview` channel](https://discord.gg/vYfkXse3),