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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
pub
use PhantomData;
use crateRuntime;
pub use SignalId;
pub use ;
pub use *;
pub use *;
/// A [Signal] is a reactive value or a function that produces a value,
/// with subscribers that are automatically notified when the value changes.
///
/// When it is a function, the function automatically subscribes to all the other
/// signals it is using and automatically re-runs when any of those signals change.
///
/// If the value implements [PartialEq] then the subscribers are notified only if
/// the value changed.
///
/// A [Signal] is created in a reactive [Scope](crate::Scope) using the [signal!](crate::signal!) macro.
/// It can only be deleted by discarding that [Scope](crate::Scope).
///
/// ## Accessors
///
/// Only data signals can be manually changed. Func signals that only runs on `server` or `client`
/// always return optional values which are some only when runninig on their side.
///
/// | Value implements | Data signal | Func signal | Func signal with<br>`server` or `client` |
/// | --- | -- | --- | --- |
/// | - | .set, .update, .with | .with | .opt_with |
/// | [Clone] | .cloned | .cloned | .opt_cloned |
/// | [Copy] | .get | .get | .opt_get |
///
///
/// ## Example
///
/// ```rust
/// use reactive_signals::{runtimes::ClientRuntime, signal};
///
/// // signals are created in scopes
/// let sx = ClientRuntime::new_root_scope();
///
/// // a simple data value
/// let count = signal!(sx, 5);
///
/// // a simple string value
/// let name = signal!(sx, "kiwi");
///
/// // is_plural will update when count changes
/// let is_plural = signal!(sx, move || count.get() != 1);
///
/// // we'll keep a history of all changes
/// let history = signal!(sx, Vec::<String>::new());
///
/// let text = signal!(sx, move || {
/// let ending = if is_plural.get() { "s" } else { "" };
/// let txt = format!("{} {}{ending}", count.get(), name.get());
/// // using .update we can add the text to the vec without cloning the vec
/// history.update(|hist| hist.push(txt.clone()));
/// txt
/// });
///
/// assert_eq!(text.cloned(), "5 kiwis");
///
/// // when setting to same value the subscribers are not notified.
/// name.set("kiwi");
/// assert_eq!(history.with(|h| h.join(", ")), "5 kiwis");
///
/// // when changing the count the name and is_plural are updated automatically.
/// count.set(1);
/// assert_eq!(text.cloned(), "1 kiwi");
///
/// // you can update the name
/// name.update(|t| *t = "fig");
/// assert_eq!(text.cloned(), "1 fig");
///
/// // 1 kiwi is repated because when changing count, is_plural changes as well
/// // triggering a second update of the text. This will be detected in
/// // future versions and only notified once.
/// assert_eq!(
/// history.with(|h| h.join(", ")),
/// "5 kiwis, 1 kiwi, 1 kiwi, 1 fig"
/// );
///
/// with_signal_arg(count);
///
/// // when declaring functions some additional imports are necessary
/// use reactive_signals::{runtimes::Runtime, Signal, types::*};
///
/// fn with_signal_arg<RT: Runtime>(count: Signal<EqData<i32>, RT>) {
/// }
///
/// ```