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),