Merge remote-tracking branch 'main/signals' into signals

This commit is contained in:
Evan Almloff 2023-08-10 17:20:27 -07:00
commit ee2619abfd
12 changed files with 258 additions and 12 deletions

View file

@ -55,7 +55,7 @@ version = "0.4.1"
# dependencies that are shared across packages # dependencies that are shared across packages
[workspace.dependencies] [workspace.dependencies]
dioxus = { path = "packages/dioxus", version = "0.4.0" } dioxus = { path = "packages/dioxus", version = "0.4.0" }
dioxus-core = { path = "packages/core", version = "0.4.0" } dioxus-core = { path = "packages/core", version = "0.4.1" }
dioxus-core-macro = { path = "packages/core-macro", version = "0.4.0" } dioxus-core-macro = { path = "packages/core-macro", version = "0.4.0" }
dioxus-router = { path = "packages/router", version = "0.4.1" } dioxus-router = { path = "packages/router", version = "0.4.1" }
dioxus-router-macro = { path = "packages/router-macro", version = "0.4.1" } dioxus-router-macro = { path = "packages/router-macro", version = "0.4.1" }

View file

@ -45,6 +45,8 @@
<a href="https://github.com/DioxusLabs/dioxus/blob/master/notes/README/ZH_CN.md"> 中文 </a> <a href="https://github.com/DioxusLabs/dioxus/blob/master/notes/README/ZH_CN.md"> 中文 </a>
<span> | </span> <span> | </span>
<a href="https://github.com/DioxusLabs/dioxus/blob/master/translations/pt-br/README.md"> PT-BR </a> <a href="https://github.com/DioxusLabs/dioxus/blob/master/translations/pt-br/README.md"> PT-BR </a>
<span> | </span>
<a href="https://github.com/DioxusLabs/dioxus/blob/master/translations/ja-jp/README.md"> 日本語 </a>
</h3> </h3>
</div> </div>

View file

@ -25,7 +25,7 @@
</a> </a>
<!--Awesome --> <!--Awesome -->
<a href="https://github.com/dioxuslabs/awesome-dioxus"> <a href="https://dioxuslabs.com/awesome">
<img src="https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg" alt="Awesome Page" /> <img src="https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg" alt="Awesome Page" />
</a> </a>
<!-- Discord --> <!-- Discord -->
@ -45,6 +45,8 @@
<a href="https://github.com/DioxusLabs/dioxus/blob/master/README.md"> English </a> <a href="https://github.com/DioxusLabs/dioxus/blob/master/README.md"> English </a>
<span> | </span> <span> | </span>
<a href="https://github.com/DioxusLabs/dioxus/blob/master/translations/pt-br/README.md"> PT-BR </a> <a href="https://github.com/DioxusLabs/dioxus/blob/master/translations/pt-br/README.md"> PT-BR </a>
<span> | </span>
<a href="https://github.com/DioxusLabs/dioxus/blob/master/translations/ja-jp/README.md"> 日本語 </a>
</h3> </h3>
</div> </div>

View file

@ -39,6 +39,7 @@ dioxus = { workspace = true }
pretty_assertions = "1.3.0" pretty_assertions = "1.3.0"
rand = "0.8.5" rand = "0.8.5"
dioxus-ssr = { workspace = true } dioxus-ssr = { workspace = true }
trybuild = "1.0"
[features] [features]
default = [] default = []

View file

@ -0,0 +1,32 @@
use dioxus::prelude::*;
fn main() {}
fn app(cx: Scope) -> Element {
let count: &RefCell<Vec<Element>> = cx.use_hook(|| RefCell::new(Vec::new()));
render! {
unsafe_child_component {
borrowed: count
}
}
}
#[derive(Props)]
struct Testing<'a> {
borrowed: &'a RefCell<Vec<Element<'a>>>,
}
fn unsafe_child_component<'a>(cx: Scope<'a, Testing<'a>>) -> Element<'a> {
let Testing { borrowed } = cx.props;
let borrowed_temporary_data =
cx.use_hook(|| String::from("This data is only valid for the lifetime of the child"));
borrowed
.borrow_mut()
.push(render! {"{borrowed_temporary_data}"});
cx.render(rsx! {
div { "Hello, world!" }
})
}

View file

@ -0,0 +1,20 @@
error[E0521]: borrowed data escapes outside of function
--> compile_tests/props_safety.rs:8:5
|
5 | fn app(cx: Scope) -> Element {
| --
| |
| `cx` is a reference that is only valid in the function body
| has type `&'1 Scoped<'1>`
...
8 | / render! {
9 | | unsafe_child_component {
10 | | borrowed: count
11 | | }
12 | | }
| | ^
| | |
| |_____`cx` escapes the function body here
| argument requires that `'1` must outlive `'static`
|
= note: this error originates in the macro `render` (in Nightly builds, run with -Z macro-backtrace for more info)

View file

@ -73,3 +73,10 @@ impl EmptyBuilder {
pub fn fc_to_builder<'a, T: Properties + 'a>(_: fn(Scope<'a, T>) -> Element<'a>) -> T::Builder { pub fn fc_to_builder<'a, T: Properties + 'a>(_: fn(Scope<'a, T>) -> Element<'a>) -> T::Builder {
T::builder() T::builder()
} }
#[cfg(not(miri))]
#[test]
fn unsafe_props_fail() {
let t = trybuild::TestCases::new();
t.compile_fail("compile_tests/props_safety.rs");
}

View file

@ -417,19 +417,20 @@ impl<'src> ScopeState {
/// fn(Scope<Props>) -> Element; /// fn(Scope<Props>) -> Element;
/// async fn(Scope<Props<'_>>) -> Element; /// async fn(Scope<Props<'_>>) -> Element;
/// ``` /// ```
pub fn component<P>( pub fn component<'child, P>(
&'src self, &'src self,
component: fn(Scope<'src, P>) -> Element<'src>, component: fn(Scope<'child, P>) -> Element<'child>,
props: P, props: P,
fn_name: &'static str, fn_name: &'static str,
) -> DynamicNode<'src> ) -> DynamicNode<'src>
where where
P: Properties + 'src, P: Properties + 'child,
'src: 'child,
{ {
let vcomp = VProps::new(component, P::memoize, props); let vcomp = VProps::new(component, P::memoize, props);
// cast off the lifetime of the render return // cast off the lifetime of the render return
let as_dyn: Box<dyn AnyProps<'src> + '_> = Box::new(vcomp); let as_dyn: Box<dyn AnyProps<'child> + '_> = Box::new(vcomp);
let extended: Box<dyn AnyProps<'src> + 'src> = unsafe { std::mem::transmute(as_dyn) }; let extended: Box<dyn AnyProps<'src> + 'src> = unsafe { std::mem::transmute(as_dyn) };
DynamicNode::Component(VComponent { DynamicNode::Component(VComponent {

View file

@ -112,7 +112,7 @@ impl Service for ServerFnHandler {
let mut res = http::Response::builder(); let mut res = http::Response::builder();
// Set the headers from the server context // Set the headers from the server context
let parts = server_context.parts.read().unwrap(); let parts = server_context.response_parts().unwrap();
*res.headers_mut().expect("empty headers should be valid") = parts.headers.clone(); *res.headers_mut().expect("empty headers should be valid") = parts.headers.clone();
let serialized = result?; let serialized = result?;

View file

@ -119,21 +119,22 @@ impl<Props: Clone + serde::Serialize + serde::de::DeserializeOwned + Send + Sync
} }
#[cfg(feature = "web")] #[cfg(feature = "web")]
fn launch_web(self) { /// Launch the web application
pub fn launch_web(self) {
let cfg = self.web_cfg.hydrate(true); let cfg = self.web_cfg.hydrate(true);
dioxus_web::launch_with_props(self.component, get_root_props_from_document().unwrap(), cfg); dioxus_web::launch_with_props(self.component, get_root_props_from_document().unwrap(), cfg);
} }
#[cfg(feature = "desktop")] #[cfg(feature = "desktop")]
fn launch_desktop(self) { /// Launch the web application
pub fn launch_desktop(self) {
let cfg = self.desktop_cfg; let cfg = self.desktop_cfg;
dioxus_desktop::launch_with_props(self.component, self.props, cfg); dioxus_desktop::launch_with_props(self.component, self.props, cfg);
} }
/// Launch a server with the given configuration
/// This will use the routing integration of the currently enabled integration feature
#[cfg(feature = "ssr")] #[cfg(feature = "ssr")]
async fn launch_server(self) { /// Launch a server application
pub async fn launch_server(self) {
let addr = self.addr; let addr = self.addr;
println!("Listening on {}", addr); println!("Listening on {}", addr);
let cfg = self.server_cfg.build(); let cfg = self.server_cfg.build();

View file

@ -0,0 +1,178 @@
<p align="center">
<img src="../../notes/header.svg">
</p>
<div align="center">
<!-- Crates version -->
<a href="https://crates.io/crates/dioxus">
<img src="https://img.shields.io/crates/v/dioxus.svg?style=flat-square"
alt="Crates.io version" />
</a>
<!-- Downloads -->
<a href="https://crates.io/crates/dioxus">
<img src="https://img.shields.io/crates/d/dioxus.svg?style=flat-square"
alt="Download" />
</a>
<!-- docs -->
<a href="https://docs.rs/dioxus">
<img src="https://img.shields.io/badge/docs-latest-blue.svg?style=flat-square"
alt="docs.rs docs" />
</a>
<!-- CI -->
<a href="https://github.com/jkelleyrtp/dioxus/actions">
<img src="https://github.com/dioxuslabs/dioxus/actions/workflows/main.yml/badge.svg"
alt="CI status" />
</a>
<!--Awesome -->
<a href="https://dioxuslabs.com/awesome">
<img src="https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg" alt="Awesome Page" />
</a>
<!-- Discord -->
<a href="https://discord.gg/XgGxMSkvUM">
<img src="https://img.shields.io/discord/899851952891002890.svg?logo=discord&style=flat-square" alt="Discord Link" />
</a>
</div>
<div align="center">
<h3>
<a href="https://dioxuslabs.com"> Web サイト </a>
<span> | </span>
<a href="https://github.com/DioxusLabs/example-projects"></a>
<span> | </span>
<a href="https://dioxuslabs.com/docs/0.3/guide/en/"> ガイド </a>
<span> | </span>
<a href="https://github.com/DioxusLabs/dioxus/blob/master/notes/README/ZH_CN.md"> 中文 </a>
<span> | </span>
<a href="https://github.com/DioxusLabs/dioxus/blob/master/translations/pt-br/README.md"> PT-BR </a>
</h3>
</div>
<br/>
Dioxus は、Rust でクロスプラットフォームのユーザー・インターフェースを構築するための、移植性が高く、パフォーマンスと人間工学に基づいたフレームワークです。
```rust
fn app(cx: Scope) -> Element {
let mut count = use_state(cx, || 0);
cx.render(rsx! {
h1 { "High-Five counter: {count}" }
button { onclick: move |_| count += 1, "Up high!" }
button { onclick: move |_| count -= 1, "Down low!" }
})
}
```
Dioxus は、ウェブアプリ、デスクトップアプリ、静的サイト、モバイルアプリ、TUI アプリ、ライブビューアプリなどの配信に使用できます。Dioxus は完全にレンダラーに依存せず、あらゆるレンダラーのプラットフォームとして使用可能です。
React を知っているのであれば、Dioxus はすでにご存知でしょう。
## ユニークな特徴:
- 10 行以下のコードでネイティブに動作するデスクトップアプリElectron は不要!)。
- 人間工学に基づいたパワフルな状態管理。
- 包括的なインラインドキュメント - すべての HTML 要素、リスナー、イベントのホバーとガイド。
- 驚異的な速さ 🔥 🔥 と極めて高いメモリ効率
- 高速反復のための統合されたホットリロード
- コルーチンとサスペンスによるファーストクラスの非同期サポート
- などなど![リリース記事全文](https://dioxuslabs.com/blog/introducing-dioxus/)を読む。
## 対応プラットフォーム
<div align="center">
<table style="width:100%">
<tr>
<td><em>Web</em></td>
<td>
<ul>
<li>WebAssembly を使って DOM に直接レンダリングする</li>
<li>SSR でプレレンダリングし、クライアントの上で再ハイドレーション</li>
<li>シンプルな "hello world "は約 65kb で、React と同等</li>
<li>開発サーバーを内蔵し、ホットリロードで迅速なイテレーションを実現</li>
</ul>
</td>
</tr>
<tr>
<td><em>デスクトップ</em></td>
<td>
<ul>
<li>ウェブビューを使ったレンダリング、あるいは実験的に WGPU や Skia を使ったレンダリング</li>
<li>設定不要。cargo-run を実行するだけで、アプリをビルド可能</li>
<li>電子的な IPC を必要としないネイティブシステムアクセスの完全サポート</li>
<li>macOS、Linux、Windows に対応。ポータブルで 3 mb より小さなバイナリ</li>
</ul>
</td>
</tr>
<tr>
<td><em>モバイル</em></td>
<td>
<ul>
<li>ウェブビューを使ったレンダリング、あるいは実験的に WGPU や Skia を使ったレンダリング</li>
<li>iOS と Android をサポート</li>
<li>React ネイティブよりも<em>大幅に</em>パフォーマンスが高い</li>
</ul>
</td>
</tr>
<tr>
<td><em>ライブビュー</em></td>
<td>
<ul>
<li>アプリケーション、または単一のコンポーネントを完全にサーバー上でレンダリング</li>
<li>Axum や Warp のような人気のある Rust フレームワークとの統合</li>
<li>極めて低いレイテンシーと 10,000 以上の同時アプリをサポートする能力</li>
</ul>
</td>
</tr>
<tr>
<td><em>ターミナル</em></td>
<td>
<ul>
<li><a href="https://github.com/vadimdemedes/ink">ink.js</a> のように、アプリケーションをターミナルに直接レンダリング</li>
<li>ブラウザでおなじみのフレックスボックスと CSS モデルを採用</li>
<li>テキスト入力、ボタン、フォーカスシステムなどの組み込みウィジェット</li>
</ul>
</td>
</tr>
</table>
</div>
## なぜ Dioxus
アプリを構築するための選択肢は山ほどあるのに、なぜ Dioxus を選ぶのでしょうか?
まず第一に、Dioxus は開発者の体験を優先しています。これは Dioxus 独自のさまざまな機能に反映されています:
- メタ言語RSXとそれに付随する VSCode 拡張機能のオートフォーマット機能
- デスクトップとウェブの両方で RSX のインタプリタを使用したホットリロード
- 優れたドキュメントの重視 - 私たちのガイドは完全で、私たちの HTML 要素は文書化されています。
- 簡素化のための多大な研究
Dioxus は非常に拡張性の高いプラットフォームでもあります。
- 非常にシンプルに最適化されたスタックマシンを実装することで、新しいレンダラーを簡単に構築できます。
- コンポーネントやカスタム・エレメントもビルドして共有できます
Dioxus は素晴らしいが、なぜ私には使えないのか?
- まだ完全に成熟していません。API はまだ移行中で、いろいろなものが壊れるかもしれません(私たちはそれを避けようとしていますが)。
- no-std 環境で動作させる必要がある。
- UI を構築する React-hooks モデルが好きではない場合
## コントリビュート
- 私たちの [issue tracker](https://github.com/dioxuslabs/dioxus/issues) で問題を報告してください。
- ディスコードに参加して質問してください!
<a href="https://github.com/dioxuslabs/dioxus/graphs/contributors">
<img src="https://contrib.rocks/image?repo=dioxuslabs/dioxus&max=30&columns=10" />
</a>
## ライセンス
このプロジェクトのライセンスは [MIT ライセンス] です。
[MIT ライセンス]: https://github.com/DioxusLabs/dioxus/blob/master/LICENSE-MIT
あなたが明示的に別段の定めをしない限り、あなたによって Dioxus に含めるために意図的に提出されたコントリビュートは、
いかなる追加条件もなく、MIT としてライセンスされるものとします。

View file

@ -43,6 +43,8 @@
<a href="https://dioxuslabs.com/guide/pt-br"> Guia </a> <a href="https://dioxuslabs.com/guide/pt-br"> Guia </a>
<span> | </span> <span> | </span>
<a href="https://github.com/DioxusLabs/dioxus/blob/master/notes/README/ZH_CN.md"> 中文 </a> <a href="https://github.com/DioxusLabs/dioxus/blob/master/notes/README/ZH_CN.md"> 中文 </a>
<span> | </span>
<a href="https://github.com/DioxusLabs/dioxus/blob/master/translations/ja-jp/README.md"> 日本語 </a>
</h3> </h3>
</div> </div>