1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// #![include_doc("../README.ja.md", start)]
//! # sigwake
//!
//! [](https://crates.io/crates/sigwake)
//! [](https://docs.rs/sigwake/)
//! [](https://github.com/frozenlib/sigwake/actions)
//!
//! マルチスレッドで使用できるシグナル型の状態管理ライブラリ
//!
//! sigwake は、近年の Web 用フレームワークの多くで採用されているシグナルを用いた状態管理を Rust の非同期プログラミングモデルによって再解釈したライブラリです。
//!
//! ## 特徴
//!
//! - 状態へのアクセスから依存関係を記録する Signal 型のリアクティブプログラミングをサポート
//! - Rust の 非同期プログラミングモデル (`async/await`, `Future`, `Waker`) との統合
//! - マルチスレッド対応
//! - 任意の非同期ランタイムと組み合わせて使用できる、非同期ランタイムに依存しない実装
//! - コンパクトな API
//!
//! ## 例
//!
//! ```rust
//! use std::time::Duration;
//!
//! use futures::StreamExt;
//! use sigwake::{StateContainer, state::Value};
//! use tokio::{spawn, time::sleep};
//!
//! struct State {
//! a: Value<i32>,
//! b: Value<i32>,
//! c: Value<i32>,
//! }
//!
//! #[tokio::main]
//! async fn main() {
//! let st = StateContainer::new(|cx| State {
//! a: Value::new(0, cx),
//! b: Value::new(0, cx),
//! c: Value::new(0, cx),
//! });
//!
//! // 依存する値が更新される度に値が流れるストリーム
//! let mut ac = st.subscribe(|st, cx| st.a.get(cx) + st.c.get(cx));
//! spawn(async move {
//! while let Some(value) = ac.next().await {
//! println!("{value}");
//! }
//! });
//! st.update(|st, cx| st.a.set(1, cx)); // aを更新
//! sleep(Duration::from_secs(1)).await;
//!
//! st.update(|st, cx| st.b.set(2, cx)); // bを更新 (acは再計算されない)
//! sleep(Duration::from_secs(1)).await;
//!
//! st.update(|st, cx| st.c.set(3, cx)); // cを更新
//! sleep(Duration::from_secs(1)).await;
//! }
//! ```
//!
//! Output:
//!
//! ```txt
//! 1
//! 4
//! ```
//!
//! ## License
//!
//! This project is dual licensed under Apache-2.0/MIT. See the two LICENSE-\* files for details.
//!
//! ## Contribution
//!
//! Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
// #![include_doc("../README.ja.md", end)]
// #![include_doc("../README.md", start)]
//! # sigwake
//!
//! [](https://crates.io/crates/sigwake)
//! [](https://docs.rs/sigwake/)
//! [](https://github.com/frozenlib/sigwake/actions)
//!
//! A thread-safe state management library using signals
//!
//! sigwake is a library that reinterprets signal-based state management (commonly used in modern web frameworks) through Rust's asynchronous programming model.
//!
//! ## Features
//!
//! - Supports reactive programming with Signal-based dependency tracking from state access
//! - Integration with Rust's asynchronous programming model (`async/await`, `Future`, `Waker`)
//! - Thread-safe implementation
//! - Runtime-agnostic implementation that can be used with any async runtime
//! - Compact API
//!
//! ## Example
//!
//! ```rust
//! use std::time::Duration;
//!
//! use futures::StreamExt;
//! use sigwake::{StateContainer, state::Value};
//! use tokio::{spawn, time::sleep};
//!
//! struct State {
//! a: Value<i32>,
//! b: Value<i32>,
//! c: Value<i32>,
//! }
//!
//! #[tokio::main]
//! async fn main() {
//! let st = StateContainer::new(|cx| State {
//! a: Value::new(0, cx),
//! b: Value::new(0, cx),
//! c: Value::new(0, cx),
//! });
//!
//! // Stream that emits values whenever dependent values are updated
//! let mut ac = st.subscribe(|st, cx| st.a.get(cx) + st.c.get(cx));
//! spawn(async move {
//! while let Some(value) = ac.next().await {
//! println!("{value}");
//! }
//! });
//! st.update(|st, cx| st.a.set(1, cx)); // Update a
//! sleep(Duration::from_secs(1)).await;
//!
//! st.update(|st, cx| st.b.set(2, cx)); // Update b (ac is not recalculated)
//! sleep(Duration::from_secs(1)).await;
//!
//! st.update(|st, cx| st.c.set(3, cx)); // Update c
//! sleep(Duration::from_secs(1)).await;
//! }
//! ```
//!
//! Output:
//!
//! ```txt
//! 1
//! 4
//! ```
//!
//! ## License
//!
//! This project is dual licensed under Apache-2.0/MIT. See the two LICENSE-\* files for details.
//!
//! ## Contribution
//!
//! Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
// #![include_doc("../README.md", end)]