on master help sign in
38 files changed+837−659
since splitsnapshots
unifiedsplit
.travis.yml+18−12 Cargo.lock+343−268 Cargo.toml+9−8 benches/benches.rs+9−22 crates/js-api/Cargo.toml+4−4 crates/js-api/src/lib.rs+4−4 examples/counter/Cargo.toml+5−5 examples/counter/src/lib.rs+2−2 examples/game-of-life/Cargo.toml+5−6 examples/game-of-life/src/lib.rs+17−12 examples/hello-world/Cargo.toml+3−3 examples/hello-world/src/lib.rs+2−2 examples/input-form/Cargo.toml+3−3 examples/input-form/src/lib.rs+2−2 examples/js-component/Cargo.toml+3−3 examples/js-component/src/lib.rs+2−2 examples/moire/Cargo.toml+8−9 examples/moire/src/lib.rs+4−4 examples/sierpinski-triangle/Cargo.toml+5−6 examples/sierpinski-triangle/src/lib.rs+4−4 examples/todomvc/Cargo.toml+10−11 examples/todomvc/src/router.rs+22−19 examples/todomvc/src/todo.rs+2−2 examples/todomvc/src/todos.rs+2−2 src/cached.rs+7−7 src/change_list/mod.rs+2−2 src/change_list/traversal.rs+1−1 src/diff.rs+6−6 src/lib.rs+2−2 src/render.rs+39−12 src/render_context.rs+1−1 src/vdom.rs+6 tests/web/cached.rs+73−65 tests/web/events.rs+56−73 tests/web/js_api.rs+30−37 tests/web/keyed.rs+18−19 tests/web/main.rs+19−17 tests/web/render.rs+89−2
.travis.yml+18−12
@@ -25,24 +25,30 @@ matrix:
2525 - name: "build (beta)"
2626 rust: beta
2727 script: INSTALL=1 ./build.sh
28− - name: "build (nightly)"
29− rust: nightly
30− script: INSTALL=1 ./build.sh
3128 - name: "headless browser tests (firefox)"
3229 rust: stable
3330 addons:
3431 firefox: latest
3532 script: wasm-pack test --firefox --headless -- --features xxx-unstable-internal-use-only
36− - name: "headless browser tests (chrome)"
37− rust: stable
38− addons:
39− chrome: stable
40− script: wasm-pack test --chrome --headless -- --features xxx-unstable-internal-use-only
4133 - name: "native tests"
4234 rust: stable
4335 install: echo "no install"
4436 script: cargo test --all
45− - name: "check native benches"
46− rust: nightly
47− install: echo "no install"
48− script: cargo check --benches --features xxx-unstable-internal-use-only
37+
38+ # TODO: A bug in `rustc` is making `js-sys` broken on nightly:
39+ # https://github.com/rust-lang/rust/issues/69315
40+ # - name: "build (nightly)"
41+ # rust: nightly
42+ # script: INSTALL=1 ./build.sh
43+ # - name: "check native benches"
44+ # rust: nightly
45+ # install: echo "no install"
46+ # script: cargo check --benches --features xxx-unstable-internal-use-only
47+
48+ # TODO: `chromedriver` is complaining about ports or something. Temporarily
49+ # disable in CI until we figure it out.
50+ # - name: "headless browser tests (chrome)"
51+ # rust: stable
52+ # addons:
53+ # chrome: stable
54+ # script: wasm-pack test --chrome --headless -- --features xxx-unstable-internal-use-only
Cargo.lock+343−268
@@ -7,12 +7,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
77
88[[package]]
99name = "atty"
10−version = "0.2.11"
10+version = "0.2.13"
1111source = "registry+https://github.com/rust-lang/crates.io-index"
1212dependencies = [
1313 "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
14− "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
15− "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
14+ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
1615]
1716
1817[[package]]
@@ -22,7 +21,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
2221
2322[[package]]
2423name = "bitflags"
25−version = "1.1.0"
24+version = "1.2.1"
2625source = "registry+https://github.com/rust-lang/crates.io-index"
2726
2827[[package]]
@@ -30,10 +29,10 @@ name = "bstr"
3029version = "0.2.8"
3130source = "registry+https://github.com/rust-lang/crates.io-index"
3231dependencies = [
33− "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
34− "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
32+ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
33+ "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
3534 "regex-automata 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
36− "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
35+ "serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)",
3736]
3837
3938[[package]]
@@ -43,13 +42,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
4342
4443[[package]]
4544name = "byteorder"
46−version = "1.3.1"
45+version = "1.3.2"
4746source = "registry+https://github.com/rust-lang/crates.io-index"
4847
4948[[package]]
5049name = "cast"
51−version = "0.2.2"
50+version = "0.2.3"
5251source = "registry+https://github.com/rust-lang/crates.io-index"
52+dependencies = [
53+ "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
54+]
5355
5456[[package]]
5557name = "cfg-if"
@@ -61,9 +63,9 @@ name = "clap"
6163version = "2.33.0"
6264source = "registry+https://github.com/rust-lang/crates.io-index"
6365dependencies = [
64− "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
66+ "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
6567 "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
66− "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
68+ "unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
6769]
6870
6971[[package]]
@@ -77,44 +79,45 @@ dependencies = [
7779
7880[[package]]
7981name = "console_log"
80−version = "0.1.2"
82+version = "0.2.0"
8183source = "registry+https://github.com/rust-lang/crates.io-index"
8284dependencies = [
83− "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
85+ "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
8486 "web-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)",
8587]
8688
8789[[package]]
8890name = "criterion"
89−version = "0.3.0"
91+version = "0.3.3"
9092source = "registry+https://github.com/rust-lang/crates.io-index"
9193dependencies = [
92− "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
93− "cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
94+ "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
95+ "cast 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
9496 "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
95− "criterion-plot 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
97+ "criterion-plot 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
9698 "csv 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
97− "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
98− "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
99− "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
100− "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
101− "rand_os 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
102− "rand_xoshiro 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
103− "rayon 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
104− "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
105− "serde_derive 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
106− "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
107− "tinytemplate 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
108− "walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
99+ "itertools 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
100+ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
101+ "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
102+ "oorandom 11.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
103+ "plotters 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
104+ "rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
105+ "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
106+ "serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)",
107+ "serde_cbor 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)",
108+ "serde_derive 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)",
109+ "serde_json 1.0.57 (registry+https://github.com/rust-lang/crates.io-index)",
110+ "tinytemplate 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
111+ "walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
109112]
110113
111114[[package]]
112115name = "criterion-plot"
113−version = "0.4.0"
116+version = "0.4.3"
114117source = "registry+https://github.com/rust-lang/crates.io-index"
115118dependencies = [
116− "cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
117− "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
119+ "cast 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
120+ "itertools 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
118121]
119122
120123[[package]]
@@ -134,7 +137,7 @@ dependencies = [
134137 "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
135138 "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
136139 "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
137− "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
140+ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
138141 "memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
139142 "scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
140143]
@@ -154,7 +157,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
154157dependencies = [
155158 "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
156159 "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
157− "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
160+ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
158161]
159162
160163[[package]]
@@ -164,9 +167,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
164167dependencies = [
165168 "bstr 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
166169 "csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
167− "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
168− "ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
169− "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
170+ "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
171+ "ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
172+ "serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)",
170173]
171174
172175[[package]]
@@ -174,23 +177,24 @@ name = "csv-core"
174177version = "0.1.6"
175178source = "registry+https://github.com/rust-lang/crates.io-index"
176179dependencies = [
177− "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
180+ "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
178181]
179182
180183[[package]]
181184name = "dodrio"
182−version = "0.1.0"
185+version = "0.2.0"
183186dependencies = [
184187 "bumpalo 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
185188 "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
186− "console_log 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
187− "criterion 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
188− "dodrio-js-api 0.1.0",
189+ "console_log 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
190+ "criterion 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
191+ "dodrio-js-api 0.2.0",
192+ "futures 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
189193 "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
190194 "js-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)",
191− "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
195+ "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
192196 "longest-increasing-subsequence 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
193− "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
197+ "serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)",
194198 "wasm-bindgen 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
195199 "wasm-bindgen-futures 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
196200 "wasm-bindgen-test 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -202,11 +206,11 @@ name = "dodrio-counter"
202206version = "0.1.0"
203207dependencies = [
204208 "console_error_panic_hook 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
205− "console_log 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
206− "dodrio 0.1.0",
207− "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
209+ "console_log 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
210+ "dodrio 0.2.0",
211+ "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
208212 "wasm-bindgen 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
209− "wasm-bindgen-test 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
213+ "wasm-bindgen-test 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
210214 "web-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)",
211215]
212216
@@ -215,12 +219,11 @@ name = "dodrio-game-of-life"
215219version = "0.1.0"
216220dependencies = [
217221 "console_error_panic_hook 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
218− "dodrio 0.1.0",
219− "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
222+ "dodrio 0.2.0",
220223 "js-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)",
221224 "wasm-bindgen 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
222− "wasm-bindgen-futures 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
223− "wasm-bindgen-test 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
225+ "wasm-bindgen-futures 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
226+ "wasm-bindgen-test 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
224227 "web-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)",
225228]
226229
@@ -229,9 +232,9 @@ name = "dodrio-hello-world"
229232version = "0.1.0"
230233dependencies = [
231234 "console_error_panic_hook 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
232− "dodrio 0.1.0",
235+ "dodrio 0.2.0",
233236 "wasm-bindgen 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
234− "wasm-bindgen-test 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
237+ "wasm-bindgen-test 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
235238 "web-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)",
236239]
237240
@@ -240,17 +243,17 @@ name = "dodrio-input-form"
240243version = "0.1.0"
241244dependencies = [
242245 "console_error_panic_hook 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
243− "dodrio 0.1.0",
246+ "dodrio 0.2.0",
244247 "wasm-bindgen 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
245− "wasm-bindgen-test 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
248+ "wasm-bindgen-test 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
246249 "web-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)",
247250]
248251
249252[[package]]
250253name = "dodrio-js-api"
251−version = "0.1.0"
254+version = "0.2.0"
252255dependencies = [
253− "dodrio 0.1.0",
256+ "dodrio 0.2.0",
254257 "js-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)",
255258 "wasm-bindgen 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
256259 "wasm-bindgen-futures 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -262,8 +265,8 @@ name = "dodrio-js-component"
262265version = "0.1.0"
263266dependencies = [
264267 "console_error_panic_hook 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
265− "dodrio 0.1.0",
266− "dodrio-js-api 0.1.0",
268+ "dodrio 0.2.0",
269+ "dodrio-js-api 0.2.0",
267270 "js-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)",
268271 "wasm-bindgen 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
269272 "web-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -275,14 +278,13 @@ version = "0.1.0"
275278dependencies = [
276279 "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
277280 "console_error_panic_hook 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
278− "console_log 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
279− "dodrio 0.1.0",
280− "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
281+ "console_log 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
282+ "dodrio 0.2.0",
281283 "js-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)",
282− "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
284+ "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
283285 "wasm-bindgen 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
284− "wasm-bindgen-futures 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
285− "wasm-bindgen-test 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
286+ "wasm-bindgen-futures 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
287+ "wasm-bindgen-test 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
286288 "web-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)",
287289]
288290
@@ -291,12 +293,11 @@ name = "dodrio-sierpinski"
291293version = "0.1.0"
292294dependencies = [
293295 "console_error_panic_hook 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
294− "dodrio 0.1.0",
295− "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
296+ "dodrio 0.2.0",
296297 "js-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)",
297298 "wasm-bindgen 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
298− "wasm-bindgen-futures 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
299− "wasm-bindgen-test 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
299+ "wasm-bindgen-futures 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
300+ "wasm-bindgen-test 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
300301 "web-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)",
301302]
302303
@@ -306,66 +307,149 @@ version = "0.1.0"
306307dependencies = [
307308 "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
308309 "console_error_panic_hook 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
309− "console_log 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
310− "dodrio 0.1.0",
311− "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
310+ "console_log 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
311+ "dodrio 0.2.0",
312312 "js-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)",
313− "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
314− "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
315− "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
313+ "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
314+ "serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)",
315+ "serde_json 1.0.57 (registry+https://github.com/rust-lang/crates.io-index)",
316316 "wasm-bindgen 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
317− "wasm-bindgen-futures 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
318− "wasm-bindgen-test 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
317+ "wasm-bindgen-futures 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
318+ "wasm-bindgen-test 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
319319 "web-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)",
320320]
321321
322322[[package]]
323323name = "either"
324−version = "1.5.2"
324+version = "1.5.3"
325325source = "registry+https://github.com/rust-lang/crates.io-index"
326326
327327[[package]]
328328name = "futures"
329−version = "0.1.28"
329+version = "0.3.5"
330330source = "registry+https://github.com/rust-lang/crates.io-index"
331+dependencies = [
332+ "futures-channel 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
333+ "futures-core 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
334+ "futures-executor 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
335+ "futures-io 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
336+ "futures-sink 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
337+ "futures-task 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
338+ "futures-util 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
339+]
331340
332341[[package]]
333−name = "fxhash"
334−version = "0.2.1"
342+name = "futures-channel"
343+version = "0.3.5"
335344source = "registry+https://github.com/rust-lang/crates.io-index"
336345dependencies = [
337− "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
346+ "futures-core 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
347+ "futures-sink 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
338348]
339349
340350[[package]]
341−name = "getrandom"
342−version = "0.1.13"
351+name = "futures-core"
352+version = "0.3.5"
353+source = "registry+https://github.com/rust-lang/crates.io-index"
354+
355+[[package]]
356+name = "futures-executor"
357+version = "0.3.5"
343358source = "registry+https://github.com/rust-lang/crates.io-index"
344359dependencies = [
345− "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
346− "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
347− "wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
360+ "futures-core 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
361+ "futures-task 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
362+ "futures-util 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
363+]
364+
365+[[package]]
366+name = "futures-io"
367+version = "0.3.5"
368+source = "registry+https://github.com/rust-lang/crates.io-index"
369+
370+[[package]]
371+name = "futures-macro"
372+version = "0.3.5"
373+source = "registry+https://github.com/rust-lang/crates.io-index"
374+dependencies = [
375+ "proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)",
376+ "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
377+ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
378+ "syn 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
348379]
349380
381+[[package]]
382+name = "futures-sink"
383+version = "0.3.5"
384+source = "registry+https://github.com/rust-lang/crates.io-index"
385+
386+[[package]]
387+name = "futures-task"
388+version = "0.3.5"
389+source = "registry+https://github.com/rust-lang/crates.io-index"
390+dependencies = [
391+ "once_cell 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
392+]
393+
394+[[package]]
395+name = "futures-util"
396+version = "0.3.5"
397+source = "registry+https://github.com/rust-lang/crates.io-index"
398+dependencies = [
399+ "futures-channel 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
400+ "futures-core 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
401+ "futures-io 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
402+ "futures-macro 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
403+ "futures-sink 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
404+ "futures-task 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
405+ "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
406+ "pin-project 0.4.16 (registry+https://github.com/rust-lang/crates.io-index)",
407+ "pin-utils 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
408+ "proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)",
409+ "proc-macro-nested 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
410+ "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
411+]
412+
413+[[package]]
414+name = "fxhash"
415+version = "0.2.1"
416+source = "registry+https://github.com/rust-lang/crates.io-index"
417+dependencies = [
418+ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
419+]
420+
421+[[package]]
422+name = "half"
423+version = "1.6.0"
424+source = "registry+https://github.com/rust-lang/crates.io-index"
425+
350426[[package]]
351427name = "heck"
352428version = "0.3.1"
353429source = "registry+https://github.com/rust-lang/crates.io-index"
354430dependencies = [
355− "unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
431+ "unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
432+]
433+
434+[[package]]
435+name = "hermit-abi"
436+version = "0.1.3"
437+source = "registry+https://github.com/rust-lang/crates.io-index"
438+dependencies = [
439+ "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
356440]
357441
358442[[package]]
359443name = "itertools"
360−version = "0.8.0"
444+version = "0.9.0"
361445source = "registry+https://github.com/rust-lang/crates.io-index"
362446dependencies = [
363− "either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
447+ "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
364448]
365449
366450[[package]]
367451name = "itoa"
368−version = "0.4.3"
452+version = "0.4.4"
369453source = "registry+https://github.com/rust-lang/crates.io-index"
370454
371455[[package]]
@@ -378,7 +462,7 @@ dependencies = [
378462
379463[[package]]
380464name = "lazy_static"
381−version = "1.3.0"
465+version = "1.4.0"
382466source = "registry+https://github.com/rust-lang/crates.io-index"
383467
384468[[package]]
@@ -388,7 +472,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
388472
389473[[package]]
390474name = "log"
391−version = "0.4.8"
475+version = "0.4.11"
392476source = "registry+https://github.com/rust-lang/crates.io-index"
393477dependencies = [
394478 "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -401,7 +485,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
401485
402486[[package]]
403487name = "memchr"
404−version = "2.2.0"
488+version = "2.2.1"
405489source = "registry+https://github.com/rust-lang/crates.io-index"
406490dependencies = [
407491 "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -420,113 +504,130 @@ name = "nom"
420504version = "4.2.3"
421505source = "registry+https://github.com/rust-lang/crates.io-index"
422506dependencies = [
423− "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
507+ "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
424508 "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
425509]
426510
427511[[package]]
428512name = "num-traits"
429−version = "0.2.6"
513+version = "0.2.10"
430514source = "registry+https://github.com/rust-lang/crates.io-index"
515+dependencies = [
516+ "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
517+]
431518
432519[[package]]
433520name = "num_cpus"
434−version = "1.10.0"
521+version = "1.11.1"
435522source = "registry+https://github.com/rust-lang/crates.io-index"
436523dependencies = [
524+ "hermit-abi 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
437525 "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
438526]
439527
440528[[package]]
441−name = "proc-macro2"
442−version = "0.4.27"
529+name = "once_cell"
530+version = "1.3.1"
443531source = "registry+https://github.com/rust-lang/crates.io-index"
444−dependencies = [
445− "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
446−]
447532
448533[[package]]
449−name = "proc-macro2"
450−version = "1.0.6"
534+name = "oorandom"
535+version = "11.1.0"
536+source = "registry+https://github.com/rust-lang/crates.io-index"
537+
538+[[package]]
539+name = "pin-project"
540+version = "0.4.16"
451541source = "registry+https://github.com/rust-lang/crates.io-index"
452542dependencies = [
453− "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
543+ "pin-project-internal 0.4.16 (registry+https://github.com/rust-lang/crates.io-index)",
454544]
455545
456546[[package]]
457−name = "quote"
458−version = "0.6.11"
547+name = "pin-project-internal"
548+version = "0.4.16"
459549source = "registry+https://github.com/rust-lang/crates.io-index"
460550dependencies = [
461− "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
551+ "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
552+ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
553+ "syn 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
462554]
463555
464556[[package]]
465−name = "quote"
466−version = "1.0.2"
557+name = "pin-utils"
558+version = "0.1.0"
559+source = "registry+https://github.com/rust-lang/crates.io-index"
560+
561+[[package]]
562+name = "plotters"
563+version = "0.2.12"
467564source = "registry+https://github.com/rust-lang/crates.io-index"
468565dependencies = [
469− "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
566+ "js-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)",
567+ "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
568+ "wasm-bindgen 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
569+ "web-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)",
470570]
471571
472572[[package]]
473−name = "rand_core"
474−version = "0.5.1"
573+name = "proc-macro-hack"
574+version = "0.5.11"
475575source = "registry+https://github.com/rust-lang/crates.io-index"
476576dependencies = [
477− "getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
577+ "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
578+ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
579+ "syn 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
478580]
479581
480582[[package]]
481−name = "rand_os"
482−version = "0.2.2"
583+name = "proc-macro-nested"
584+version = "0.1.3"
585+source = "registry+https://github.com/rust-lang/crates.io-index"
586+
587+[[package]]
588+name = "proc-macro2"
589+version = "1.0.18"
483590source = "registry+https://github.com/rust-lang/crates.io-index"
484591dependencies = [
485− "getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
486− "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
592+ "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
487593]
488594
489595[[package]]
490−name = "rand_xoshiro"
491−version = "0.3.1"
596+name = "quote"
597+version = "1.0.2"
492598source = "registry+https://github.com/rust-lang/crates.io-index"
493599dependencies = [
494− "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
600+ "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
495601]
496602
497603[[package]]
498604name = "rayon"
499−version = "1.2.1"
605+version = "1.3.0"
500606source = "registry+https://github.com/rust-lang/crates.io-index"
501607dependencies = [
502608 "crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
503− "either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
504− "rayon-core 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
609+ "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
610+ "rayon-core 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
505611]
506612
507613[[package]]
508614name = "rayon-core"
509−version = "1.6.1"
615+version = "1.7.0"
510616source = "registry+https://github.com/rust-lang/crates.io-index"
511617dependencies = [
512618 "crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
513619 "crossbeam-queue 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
514620 "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
515− "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
516− "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
621+ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
622+ "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)",
517623]
518624
519625[[package]]
520−name = "redox_syscall"
521−version = "0.1.52"
522−source = "registry+https://github.com/rust-lang/crates.io-index"
523−
524−[[package]]
525−name = "redox_termios"
526−version = "0.1.1"
626+name = "regex"
627+version = "1.3.3"
527628source = "registry+https://github.com/rust-lang/crates.io-index"
528629dependencies = [
529− "redox_syscall 0.1.52 (registry+https://github.com/rust-lang/crates.io-index)",
630+ "regex-syntax 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
530631]
531632
532633[[package]]
@@ -534,9 +635,14 @@ name = "regex-automata"
534635version = "0.1.8"
535636source = "registry+https://github.com/rust-lang/crates.io-index"
536637dependencies = [
537− "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
638+ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
538639]
539640
641+[[package]]
642+name = "regex-syntax"
643+version = "0.6.13"
644+source = "registry+https://github.com/rust-lang/crates.io-index"
645+
540646[[package]]
541647name = "rustc_version"
542648version = "0.2.3"
@@ -547,12 +653,12 @@ dependencies = [
547653
548654[[package]]
549655name = "ryu"
550−version = "1.0.0"
656+version = "1.0.2"
551657source = "registry+https://github.com/rust-lang/crates.io-index"
552658
553659[[package]]
554660name = "same-file"
555−version = "1.0.4"
661+version = "1.0.5"
556662source = "registry+https://github.com/rust-lang/crates.io-index"
557663dependencies = [
558664 "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -583,32 +689,46 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
583689
584690[[package]]
585691name = "serde"
586−version = "1.0.103"
692+version = "1.0.114"
587693source = "registry+https://github.com/rust-lang/crates.io-index"
588694dependencies = [
589− "serde_derive 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
695+ "serde_derive 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)",
696+]
697+
698+[[package]]
699+name = "serde_cbor"
700+version = "0.11.1"
701+source = "registry+https://github.com/rust-lang/crates.io-index"
702+dependencies = [
703+ "half 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
704+ "serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)",
590705]
591706
592707[[package]]
593708name = "serde_derive"
594−version = "1.0.103"
709+version = "1.0.114"
595710source = "registry+https://github.com/rust-lang/crates.io-index"
596711dependencies = [
597− "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
712+ "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
598713 "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
599− "syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
714+ "syn 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
600715]
601716
602717[[package]]
603718name = "serde_json"
604−version = "1.0.40"
719+version = "1.0.57"
605720source = "registry+https://github.com/rust-lang/crates.io-index"
606721dependencies = [
607− "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
608− "ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
609− "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
722+ "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
723+ "ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
724+ "serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)",
610725]
611726
727+[[package]]
728+name = "slab"
729+version = "0.4.2"
730+source = "registry+https://github.com/rust-lang/crates.io-index"
731+
612732[[package]]
613733name = "sourcefile"
614734version = "0.1.4"
@@ -616,54 +736,39 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
616736
617737[[package]]
618738name = "syn"
619−version = "1.0.9"
739+version = "1.0.33"
620740source = "registry+https://github.com/rust-lang/crates.io-index"
621741dependencies = [
622− "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
742+ "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
623743 "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
624744 "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
625745]
626746
627−[[package]]
628−name = "termion"
629−version = "1.5.1"
630−source = "registry+https://github.com/rust-lang/crates.io-index"
631−dependencies = [
632− "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
633− "redox_syscall 0.1.52 (registry+https://github.com/rust-lang/crates.io-index)",
634− "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
635−]
636−
637747[[package]]
638748name = "textwrap"
639749version = "0.11.0"
640750source = "registry+https://github.com/rust-lang/crates.io-index"
641751dependencies = [
642− "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
752+ "unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
643753]
644754
645755[[package]]
646756name = "tinytemplate"
647−version = "1.0.1"
757+version = "1.1.0"
648758source = "registry+https://github.com/rust-lang/crates.io-index"
649759dependencies = [
650− "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
651− "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
760+ "serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)",
761+ "serde_json 1.0.57 (registry+https://github.com/rust-lang/crates.io-index)",
652762]
653763
654764[[package]]
655765name = "unicode-segmentation"
656−version = "1.2.1"
766+version = "1.6.0"
657767source = "registry+https://github.com/rust-lang/crates.io-index"
658768
659769[[package]]
660770name = "unicode-width"
661−version = "0.1.5"
662−source = "registry+https://github.com/rust-lang/crates.io-index"
663−
664−[[package]]
665−name = "unicode-xid"
666−version = "0.1.0"
771+version = "0.1.6"
667772source = "registry+https://github.com/rust-lang/crates.io-index"
668773
669774[[package]]
@@ -678,19 +783,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
678783
679784[[package]]
680785name = "walkdir"
681−version = "2.2.7"
786+version = "2.3.1"
682787source = "registry+https://github.com/rust-lang/crates.io-index"
683788dependencies = [
684− "same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
685− "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
789+ "same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
790+ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
686791 "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
687792]
688793
689−[[package]]
690−name = "wasi"
691−version = "0.7.0"
692−source = "registry+https://github.com/rust-lang/crates.io-index"
693−
694794[[package]]
695795name = "wasm-bindgen"
696796version = "0.2.55"
@@ -706,24 +806,14 @@ version = "0.2.55"
706806source = "registry+https://github.com/rust-lang/crates.io-index"
707807dependencies = [
708808 "bumpalo 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
709− "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
710− "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
711− "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
809+ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
810+ "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
811+ "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
712812 "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
713− "syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
813+ "syn 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
714814 "wasm-bindgen-shared 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
715815]
716816
717−[[package]]
718−name = "wasm-bindgen-futures"
719−version = "0.3.19"
720−source = "registry+https://github.com/rust-lang/crates.io-index"
721−dependencies = [
722− "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
723− "js-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)",
724− "wasm-bindgen 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
725−]
726−
727817[[package]]
728818name = "wasm-bindgen-futures"
729819version = "0.4.5"
@@ -749,9 +839,9 @@ name = "wasm-bindgen-macro-support"
749839version = "0.2.55"
750840source = "registry+https://github.com/rust-lang/crates.io-index"
751841dependencies = [
752− "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
842+ "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
753843 "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
754− "syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
844+ "syn 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
755845 "wasm-bindgen-backend 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
756846 "wasm-bindgen-shared 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
757847]
@@ -761,20 +851,6 @@ name = "wasm-bindgen-shared"
761851version = "0.2.55"
762852source = "registry+https://github.com/rust-lang/crates.io-index"
763853
764−[[package]]
765−name = "wasm-bindgen-test"
766−version = "0.2.42"
767−source = "registry+https://github.com/rust-lang/crates.io-index"
768−dependencies = [
769− "console_error_panic_hook 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
770− "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
771− "js-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)",
772− "scoped-tls 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
773− "wasm-bindgen 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
774− "wasm-bindgen-futures 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
775− "wasm-bindgen-test-macro 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
776−]
777−
778854[[package]]
779855name = "wasm-bindgen-test"
780856version = "0.3.5"
@@ -788,21 +864,12 @@ dependencies = [
788864 "wasm-bindgen-test-macro 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
789865]
790866
791−[[package]]
792−name = "wasm-bindgen-test-macro"
793−version = "0.2.42"
794−source = "registry+https://github.com/rust-lang/crates.io-index"
795−dependencies = [
796− "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
797− "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
798−]
799−
800867[[package]]
801868name = "wasm-bindgen-test-macro"
802869version = "0.3.5"
803870source = "registry+https://github.com/rust-lang/crates.io-index"
804871dependencies = [
805− "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
872+ "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
806873 "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
807874]
808875
@@ -813,10 +880,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
813880dependencies = [
814881 "anyhow 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
815882 "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
816− "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
817− "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
883+ "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
884+ "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
818885 "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
819− "syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
886+ "syn 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
820887 "wasm-bindgen-backend 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
821888 "weedle 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
822889]
@@ -843,7 +910,7 @@ dependencies = [
843910
844911[[package]]
845912name = "winapi"
846−version = "0.3.7"
913+version = "0.3.8"
847914source = "registry+https://github.com/rust-lang/crates.io-index"
848915dependencies = [
849916 "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -860,7 +927,7 @@ name = "winapi-util"
860927version = "0.1.2"
861928source = "registry+https://github.com/rust-lang/crates.io-index"
862929dependencies = [
863− "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
930+ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
864931]
865932
866933[[package]]
@@ -870,91 +937,99 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
870937
871938[metadata]
872939"checksum anyhow 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "9267dff192e68f3399525901e709a48c1d3982c9c072fa32f2127a0cb0babf14"
873−"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652"
940+"checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90"
874941"checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
875−"checksum bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd"
942+"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
876943"checksum bstr 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8d6c2c5b58ab920a4f5aeaaca34b4488074e8cc7596af94e6f8c6ff247c60245"
877944"checksum bumpalo 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ad807f2fc2bf185eeb98ff3a901bd46dc5ad58163d0fa4577ba0d25674d71708"
878−"checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb"
879−"checksum cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "926013f2860c46252efceabb19f4a6b308197505082c609025aa6706c011d427"
945+"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
946+"checksum cast 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4b9434b9a5aa1450faa3f9cb14ea0e8c53bb5d2b3c1bfd1ab4fc03e9f33fbfb0"
880947"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
881948"checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9"
882949"checksum console_error_panic_hook 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b8d976903543e0c48546a91908f21588a680a8c8f984df9a5d69feccb2b2a211"
883−"checksum console_log 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1e7871d2947441b0fdd8e2bd1ce2a2f75304f896582c0d572162d48290683c48"
884−"checksum criterion 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "938703e165481c8d612ea3479ac8342e5615185db37765162e762ec3523e2fc6"
885−"checksum criterion-plot 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eccdc6ce8bbe352ca89025bee672aa6d24f4eb8c53e3a8b5d1bc58011da072a2"
950+"checksum console_log 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "501a375961cef1a0d44767200e66e4a559283097e91d0730b1d75dfb2f8a1494"
951+"checksum criterion 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "70daa7ceec6cf143990669a04c7df13391d55fb27bd4079d252fca774ba244d8"
952+"checksum criterion-plot 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e022feadec601fba1649cfa83586381a4ad31c6bf3a9ab7d408118b05dd9889d"
886953"checksum crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3aa945d63861bfe624b55d153a39684da1e8c0bc8fba932f7ee3a3c16cea3ca"
887954"checksum crossbeam-epoch 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5064ebdbf05ce3cb95e45c8b086f72263f4166b29b97f6baff7ef7fe047b55ac"
888955"checksum crossbeam-queue 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dfd6515864a82d2f877b42813d4553292c6659498c9a2aa31bab5a15243c2700"
889956"checksum crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce446db02cdc3165b94ae73111e570793400d0794e46125cc4056c81cbb039f4"
890957"checksum csv 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37519ccdfd73a75821cac9319d4fce15a81b9fcf75f951df5b9988aa3a0af87d"
891958"checksum csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9b5cadb6b25c77aeff80ba701712494213f4a8418fcda2ee11b6560c3ad0bf4c"
892−"checksum either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5527cfe0d098f36e3f8839852688e63c8fff1c90b2b405aef730615f9a7bcf7b"
893−"checksum futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "45dc39533a6cae6da2b56da48edae506bb767ec07370f86f70fc062e9d435869"
959+"checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3"
960+"checksum futures 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1e05b85ec287aac0dc34db7d4a569323df697f9c55b99b15d6b4ef8cde49f613"
961+"checksum futures-channel 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f366ad74c28cca6ba456d95e6422883cfb4b252a83bed929c83abfdbbf2967d5"
962+"checksum futures-core 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "59f5fff90fd5d971f936ad674802482ba441b6f09ba5e15fd8b39145582ca399"
963+"checksum futures-executor 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "10d6bb888be1153d3abeb9006b11b02cf5e9b209fda28693c31ae1e4e012e314"
964+"checksum futures-io 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "de27142b013a8e869c14957e6d2edeef89e97c289e69d042ee3a49acd8b51789"
965+"checksum futures-macro 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d0b5a30a4328ab5473878237c447333c093297bded83a4983d10f4deea240d39"
966+"checksum futures-sink 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3f2032893cb734c7a05d85ce0cc8b8c4075278e93b24b66f9de99d6eb0fa8acc"
967+"checksum futures-task 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "bdb66b5f09e22019b1ab0830f7785bcea8e7a42148683f99214f73f8ec21a626"
968+"checksum futures-util 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "8764574ff08b701a084482c3c7031349104b07ac897393010494beaa18ce32c6"
894969"checksum fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
895−"checksum getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e7db7ca94ed4cd01190ceee0d8a8052f08a247aa1b469a7f68c6a3b71afcf407"
970+"checksum half 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d36fab90f82edc3c747f9d438e06cf0a491055896f2a279638bb5beed6c40177"
896971"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
897−"checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358"
898−"checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b"
972+"checksum hermit-abi 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "307c3c9f937f38e3534b1d6447ecf090cafcc9744e4a6360e8b037b2cf5af120"
973+"checksum itertools 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b"
974+"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f"
899975"checksum js-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)" = "1c840fdb2167497b0bd0db43d6dfe61e91637fa72f9d061f8bd17ddc44ba6414"
900−"checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14"
976+"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
901977"checksum libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)" = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558"
902−"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
978+"checksum log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
903979"checksum longest-increasing-subsequence 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3bd0dd2cd90571056fdb71f6275fada10131182f84899f4b2a916e565d81d86"
904−"checksum memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39"
980+"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
905981"checksum memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9"
906982"checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6"
907−"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1"
908−"checksum num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a23f0ed30a54abaa0c7e83b1d2d87ada7c3c23078d1d87815af3e3b6385fbba"
909−"checksum proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)" = "4d317f9caece796be1980837fd5cb3dfec5613ebdb04ad0956deea83ce168915"
910−"checksum proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9c9e470a8dc4aeae2dee2f335e8f533e2d4b347e1434e5671afc49b054592f27"
911−"checksum quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "cdd8e04bd9c52e0342b406469d494fcb033be4bdbe5c606016defbb1681411e1"
983+"checksum num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c81ffc11c212fa327657cb19dd85eb7419e163b5b076bede2bdb5c974c07e4"
984+"checksum num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "76dac5ed2a876980778b8b85f75a71b6cbf0db0b1232ee12f826bccb00d09d72"
985+"checksum once_cell 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b1c601810575c99596d4afc46f78a678c80105117c379eb3650cf99b8a21ce5b"
986+"checksum oorandom 11.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ebcec7c9c2a95cacc7cd0ecb89d8a8454eca13906f6deb55258ffff0adeb9405"
987+"checksum pin-project 0.4.16 (registry+https://github.com/rust-lang/crates.io-index)" = "81d480cb4e89522ccda96d0eed9af94180b7a5f93fb28f66e1fd7d68431663d1"
988+"checksum pin-project-internal 0.4.16 (registry+https://github.com/rust-lang/crates.io-index)" = "a82996f11efccb19b685b14b5df818de31c1edcee3daa256ab5775dd98e72feb"
989+"checksum pin-utils 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
990+"checksum plotters 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "4e3bb8da247d27ae212529352020f3e5ee16e83c0c258061d27b08ab92675eeb"
991+"checksum proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)" = "ecd45702f76d6d3c75a80564378ae228a85f0b59d2f3ed43c91b4a69eb2ebfc5"
992+"checksum proc-macro-nested 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "369a6ed065f249a159e06c45752c780bda2fb53c995718f9e484d08daa9eb42e"
993+"checksum proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa"
912994"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
913−"checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
914−"checksum rand_os 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a788ae3edb696cfcba1c19bfd388cc4b8c21f8a408432b199c072825084da58a"
915−"checksum rand_xoshiro 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0e18c91676f670f6f0312764c759405f13afb98d5d73819840cf72a518487bff"
916−"checksum rayon 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "43739f8831493b276363637423d3622d4bd6394ab6f0a9c4a552e208aeb7fddd"
917−"checksum rayon-core 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f8bf17de6f23b05473c437eb958b9c850bfc8af0961fe17b4cc92d5a627b4791"
918−"checksum redox_syscall 0.1.52 (registry+https://github.com/rust-lang/crates.io-index)" = "d32b3053e5ced86e4bc0411fec997389532bf56b000e66cb4884eeeb41413d69"
919−"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
995+"checksum rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "db6ce3297f9c85e16621bb8cca38a06779ffc31bb8184e1be4bed2be4678a098"
996+"checksum rayon-core 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "08a89b46efaf957e52b18062fb2f4660f8b8a4dde1807ca002690868ef2c85a9"
997+"checksum regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b5508c1941e4e7cb19965abef075d35a9a8b5cdf0846f30b4050e9b55dc55e87"
920998"checksum regex-automata 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "92b73c2a1770c255c240eaa4ee600df1704a38dc3feaa6e949e7fcd4f8dc09f9"
999+"checksum regex-syntax 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e734e891f5b408a29efbf8309e656876276f49ab6a6ac208600b4419bd893d90"
9211000"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
922−"checksum ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c92464b447c0ee8c4fb3824ecc8383b81717b9f1e74ba2e72540aef7b9f82997"
923−"checksum same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8f20c4be53a8a1ff4c1f1b2bd14570d2f634628709752f0702ecdd2b3f9a5267"
1001+"checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8"
1002+"checksum same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "585e8ddcedc187886a30fa705c47985c3fa88d06624095856b36ca0b82ff4421"
9241003"checksum scoped-tls 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
9251004"checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d"
9261005"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
9271006"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
928−"checksum serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)" = "1217f97ab8e8904b57dd22eb61cde455fa7446a9c1cf43966066da047c1f3702"
929−"checksum serde_derive 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)" = "a8c6faef9a2e64b0064f48570289b4bf8823b7581f1d6157c1b52152306651d0"
930−"checksum serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)" = "051c49229f282f7c6f3813f8286cc1e3323e8051823fce42c7ea80fe13521704"
1007+"checksum serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)" = "5317f7588f0a5078ee60ef675ef96735a1442132dc645eb1d12c018620ed8cd3"
1008+"checksum serde_cbor 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1e18acfa2f90e8b735b2836ab8d538de304cbb6729a7360729ea5a895d15a622"
1009+"checksum serde_derive 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)" = "2a0be94b04690fbaed37cddffc5c134bf537c8e3329d53e982fe04c374978f8e"
1010+"checksum serde_json 1.0.57 (registry+https://github.com/rust-lang/crates.io-index)" = "164eacbdb13512ec2745fb09d51fd5b22b0d65ed294a1dcf7285a360c80a675c"
1011+"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
9311012"checksum sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4bf77cb82ba8453b42b6ae1d692e4cdc92f9a47beaf89a847c8be83f4e328ad3"
932−"checksum syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f89693ae015201f8de93fd96bde2d065f8bfc3f97ce006d5bc9f900b97c0c7c0"
933−"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
1013+"checksum syn 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)" = "e8d5d96e8cbb005d6959f119f773bfaebb5684296108fb32600c00cde305b2cd"
9341014"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
935−"checksum tinytemplate 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7655088894274afb52b807bd3c87072daa1fedd155068b8705cabfd628956115"
936−"checksum unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1"
937−"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
938−"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
1015+"checksum tinytemplate 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6d3dc76004a03cec1c5932bca4cdc2e39aaa798e3f82363dd94f9adf6098c12f"
1016+"checksum unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0"
1017+"checksum unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7007dbd421b92cc6e28410fe7362e2e0a2503394908f417b68ec8d1c364c4e20"
9391018"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
9401019"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
941−"checksum walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9d9d7ed3431229a144296213105a390676cc49c9b6a72bd19f3176c98e129fa1"
942−"checksum wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d"
1020+"checksum walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d"
9431021"checksum wasm-bindgen 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)" = "29ae32af33bacd663a9a28241abecf01f2be64e6a185c6139b04f18b6385c5f2"
9441022"checksum wasm-bindgen-backend 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)" = "1845584bd3593442dc0de6e6d9f84454a59a057722f36f005e44665d6ab19d85"
945−"checksum wasm-bindgen-futures 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)" = "0ad171fc1f6e43f97d155d27f4ee5657bd8aa5cce7c497ef3a0a0c5b44618b2d"
9461023"checksum wasm-bindgen-futures 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1458706aa1b8fe6898d19433c9f110d93a05d1f22ae6adf55810409a94df34b4"
9471024"checksum wasm-bindgen-macro 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)" = "87fcc747e6b73c93d22c947a6334644d22cfec5abd8b66238484dc2b0aeb9fe4"
9481025"checksum wasm-bindgen-macro-support 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)" = "3dc4b3f2c4078c8c4a5f363b92fcf62604c5913cbd16c6ff5aaf0f74ec03f570"
9491026"checksum wasm-bindgen-shared 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)" = "ca0b78d6d3be8589b95d1d49cdc0794728ca734adf36d7c9f07e6459508bb53d"
950−"checksum wasm-bindgen-test 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)" = "8aed4ef1aa56f2ef4aff593c516de6a3e48711c703b3f7415c9151a7c9babd17"
9511027"checksum wasm-bindgen-test 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ed5833682054e941db0b7e2b4877b61bbaafd680608e40d268e070d34558b305"
952−"checksum wasm-bindgen-test-macro 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)" = "eb477c50f3c9a9ecd99c78fb9bd3b6599d414b918d5f72165b12c53738011ae1"
9531028"checksum wasm-bindgen-test-macro 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "9c5dcf70d21d0ff0ea5cdb97dba9a9b56ddad4a9bd10c8912eedc55618be022f"
9541029"checksum wasm-bindgen-webidl 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)" = "3126356474ceb717c8fb5549ae387c9fbf4872818454f4d87708bee997214bb5"
9551030"checksum web-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)" = "98405c0a2e722ed3db341b4c5b70eb9fe0021621f7350bab76df93b09b649bbf"
9561031"checksum weedle 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3bb43f70885151e629e2a19ce9e50bd730fd436cfd4b666894c9ce4de9141164"
957−"checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770"
1032+"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
9581033"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
9591034"checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9"
9601035"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
Cargo.toml+9−8
@@ -8,7 +8,7 @@ license = "MPL-2.0"
88name = "dodrio"
99readme = "./README.md"
1010repository = "https://github.com/fitzgen/dodrio"
11−version = "0.1.0"
11+version = "0.2.0"
1212
1313[badges]
1414travis-ci = { repository = "fitzgen/dodrio" }
@@ -46,9 +46,9 @@ bumpalo = "2.6.0"
4646cfg-if = "0.1.10"
4747fxhash = "0.2.1"
4848js-sys = "0.3.32"
49−log = { version = "0.4.8", optional = true }
49+log = { version = "0.4.11", optional = true }
5050longest-increasing-subsequence = "0.1.0"
51−serde = { version = "1.0.103", optional = true }
51+serde = { version = "1.0.114", optional = true }
5252wasm-bindgen = "0.2.55"
5353wasm-bindgen-futures = "0.4.5"
5454
@@ -64,13 +64,14 @@ features = [
6464]
6565
6666[dev-dependencies]
67−console_log = "0.1.2"
68−dodrio-js-api = { version = "=0.1.0", path = "./crates/js-api" }
69−log = "0.4.8"
67+console_log = "0.2.0"
68+dodrio-js-api = { version = "=0.2.0", path = "./crates/js-api" }
69+futures = "0.3.5"
70+log = "0.4.11"
7071wasm-bindgen-test = "0.3.5"
7172
7273[dev-dependencies.web-sys]
73−version = "0.3.19"
74+version = "0.3.32"
7475features = [
7576 "Attr",
7677 "EventTarget",
@@ -80,7 +81,7 @@ features = [
8081]
8182
8283[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
83−criterion = "0.3.0"
84+criterion = "0.3.3"
8485
8586[profile.bench]
8687debug = true
benches/benches.rs+9−22
@@ -13,19 +13,20 @@ use dodrio::{
1313 CachedSet, Node, Render, RenderContext, Vdom,
1414};
1515use std::cell::RefCell;
16+use std::convert::TryInto;
1617
1718/// The simplest thing we can render: `<div/>`.
1819struct Empty;
19−impl Render for Empty {
20− fn render<'a>(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
20+impl<'a> Render<'a> for Empty {
21+ fn render(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
2122 div(&cx).finish()
2223 }
2324}
2425
2526/// Render a list that is `self.0` items long, has attributes and listeners.
2627struct SimpleList(usize);
27−impl Render for SimpleList {
28− fn render<'a>(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
28+impl<'a> Render<'a> for SimpleList {
29+ fn render(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
2930 let mut children = bumpalo::collections::Vec::with_capacity_in(self.0, cx.bump);
3031 children.extend((0..self.0).map(|_| {
3132 li(&cx)
@@ -73,16 +74,9 @@ fn criterion_benchmark(c: &mut Criterion) {
7374 })
7475 }
7576 },
76− vec![
77− // TODO: Only test one `n` value until
78− // https://github.com/bheisler/criterion.rs/issues/269 is fixed.
79− //
80− // 100,
81− // 1_000,
82− 10_000,
83− ],
77+ vec![100, 1_000, 10_000],
8478 )
85− .throughput(|n| Throughput::Elements(*n as u32)),
79+ .throughput(|n| Throughput::Elements((*n).try_into().unwrap())),
8680 );
8781
8882 c.bench(
@@ -96,14 +90,7 @@ fn criterion_benchmark(c: &mut Criterion) {
9690 black_box(&vdom);
9791 })
9892 },
99− vec![
100− // TODO: Only test one `n` value until
101− // https://github.com/bheisler/criterion.rs/issues/269 is fixed.
102− //
103− // 100,
104− // 1_000,
105− 10_000,
106− ],
93+ vec![100, 1_000, 10_000],
10794 )
10895 .with_function("empty-to-full-list-to-empty", |b, &n| {
10996 b.iter(|| {
@@ -123,7 +110,7 @@ fn criterion_benchmark(c: &mut Criterion) {
123110 black_box(&vdom);
124111 })
125112 })
126− .throughput(|n| Throughput::Elements(*n as u32)),
113+ .throughput(|n| Throughput::Elements((*n).try_into().unwrap())),
127114 );
128115}
129116
crates/js-api/Cargo.toml+4−4
@@ -7,15 +7,15 @@ keywords = ["javascript", "js", "vdom", "virtual-dom"]
77license = "MPL-2.0"
88name = "dodrio-js-api"
99repository = "https://github.com/fitzgen/dodrio"
10−version = "0.1.0"
10+version = "0.2.0"
1111
1212[badges]
1313travis-ci = { repository = "fitzgen/dodrio" }
1414
1515[dependencies]
16−dodrio = { version = "=0.1.0", path = "../.." }
17−wasm-bindgen = "0.2.42"
18−js-sys = "0.3.19"
16+dodrio = { version = "=0.2.0", path = "../.." }
17+wasm-bindgen = "0.2.55"
18+js-sys = "0.3.32"
1919wasm-bindgen-futures = "0.4.5"
2020
2121[dev-dependencies]
crates/js-api/src/lib.rs+4−4
@@ -99,8 +99,8 @@ impl GreetingViaJs {
9999
100100/// And finally the `Render` implementation! This adds a `<p>` element and some
101101/// text around whatever the inner JS `Greeting` component renders.
102−impl Render for GreetingViaJs {
103− fn render<'a>(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
102+impl<'a> Render<'a> for GreetingViaJs {
103+ fn render(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
104104 use dodrio::builder::*;
105105 p(&cx)
106106 .children([
@@ -216,8 +216,8 @@ impl JsRender {
216216 }
217217}
218218
219−impl Render for JsRender {
220− fn render<'a>(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
219+impl<'a> Render<'a> for JsRender {
220+ fn render(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
221221 create(cx, self.render())
222222 }
223223}
examples/counter/Cargo.toml+5−5
@@ -11,13 +11,13 @@ crate-type = ["cdylib"]
1111
1212[dependencies]
1313console_error_panic_hook = "0.1.6"
14−console_log = "0.1.2"
14+console_log = "0.2.0"
1515dodrio = { path = "../.." }
16−log = "0.4.8"
17−wasm-bindgen = "0.2.42"
16+log = "0.4.11"
17+wasm-bindgen = "0.2.55"
1818
1919[dependencies.web-sys]
20−version = "0.3.19"
20+version = "0.3.32"
2121features = [
2222 "console",
2323 "Document",
@@ -30,4 +30,4 @@ features = [
3030]
3131
3232[dev-dependencies]
33−wasm-bindgen-test = "0.2.42"
33+wasm-bindgen-test = "0.3.5"
examples/counter/src/lib.rs+2−2
@@ -26,8 +26,8 @@ impl Counter {
2626
2727// The `Render` implementation for `Counter`s displays the current count and has
2828// buttons to increment and decrement the count.
29−impl Render for Counter {
30− fn render<'a>(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
29+impl<'a> Render<'a> for Counter {
30+ fn render(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
3131 use dodrio::builder::*;
3232
3333 // Stringify the count as a bump-allocated string.
examples/game-of-life/Cargo.toml+5−6
@@ -11,14 +11,13 @@ crate-type = ["cdylib"]
1111
1212[dependencies]
1313dodrio = { path = "../.." }
14−wasm-bindgen = "0.2.42"
14+wasm-bindgen = "0.2.55"
1515console_error_panic_hook = "0.1.6"
16−js-sys = "0.3.19"
17−wasm-bindgen-futures = "0.3.19"
18−futures = "0.1.28"
16+js-sys = "0.3.32"
17+wasm-bindgen-futures = "0.4.5"
1918
2019[dependencies.web-sys]
21−version = "0.3.19"
20+version = "0.3.32"
2221features = [
2322 "Document",
2423 "HtmlElement",
@@ -27,4 +26,4 @@ features = [
2726]
2827
2928[dev-dependencies]
30−wasm-bindgen-test = "0.2.42"
29+wasm-bindgen-test = "0.3.5"
examples/game-of-life/src/lib.rs+17−12
@@ -1,5 +1,4 @@
11use dodrio::{bumpalo, Node, Render, RenderContext, Vdom};
2−use futures::prelude::*;
32use std::cell::RefCell;
43use std::rc::Rc;
54use wasm_bindgen::{prelude::*, JsCast};
@@ -127,8 +126,8 @@ impl Universe {
127126}
128127
129128/// The rendering implementation for our Game of Life.
130−impl Render for Universe {
131− fn render<'a>(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
129+impl<'a> Render<'a> for Universe {
130+ fn render(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
132131 use dodrio::builder::*;
133132
134133 let mut rows = bumpalo::collections::Vec::with_capacity_in(self.height as usize, cx.bump);
@@ -178,20 +177,26 @@ pub fn run() {
178177
179178 // Kick off a loop that keeps computing a tick of the universe and then
180179 // re-rendering on every animation frame.
181− let rc: Rc<RefCell<Option<Closure<FnMut()>>>> = Rc::new(RefCell::new(None));
180+ let rc = <Rc<RefCell<Option<Closure<dyn FnMut()>>>>>::default();
182181 let rc2 = rc.clone();
183182 let window2 = window.clone();
184183 let weak = vdom.weak();
185184 let f = Closure::wrap(Box::new(move || {
186185 weak.schedule_render();
187186
188− wasm_bindgen_futures::spawn_local(
189− weak.with_component(|root| {
190− let universe = root.unwrap_mut::<Universe>();
191− universe.tick();
192− })
193− .map_err(|_| wasm_bindgen::throw_str("impossible, we always keep the vdom alive")),
194− );
187+ wasm_bindgen_futures::spawn_local({
188+ let weak = weak.clone();
189+ async move {
190+ let fut = weak.with_component(|root| {
191+ let universe = root.unwrap_mut::<Universe>();
192+ universe.tick();
193+ });
194+
195+ if fut.await.is_err() {
196+ wasm_bindgen::throw_str("impossible, we always keep the vdom alive");
197+ }
198+ }
199+ });
195200
196201 window
197202 .request_animation_frame(
@@ -202,7 +207,7 @@ pub fn run() {
202207 .unchecked_ref::<js_sys::Function>(),
203208 )
204209 .unwrap_throw();
205− }) as Box<FnMut()>);
210+ }) as Box<dyn FnMut()>);
206211 window2
207212 .request_animation_frame(f.as_ref().unchecked_ref::<js_sys::Function>())
208213 .unwrap_throw();
examples/hello-world/Cargo.toml+3−3
@@ -11,11 +11,11 @@ crate-type = ["cdylib"]
1111
1212[dependencies]
1313dodrio = { path = "../.." }
14−wasm-bindgen = "0.2.42"
14+wasm-bindgen = "0.2.55"
1515console_error_panic_hook = "0.1.6"
1616
1717[dependencies.web-sys]
18−version = "0.3.19"
18+version = "0.3.32"
1919features = [
2020 "Document",
2121 "HtmlElement",
@@ -24,4 +24,4 @@ features = [
2424]
2525
2626[dev-dependencies]
27−wasm-bindgen-test = "0.2.42"
27+wasm-bindgen-test = "0.3.5"
examples/hello-world/src/lib.rs+2−2
@@ -10,8 +10,8 @@ struct Hello {
1010
1111// The `Render` implementation describes how to render a `Hello` component into
1212// HTML.
13−impl Render for Hello {
14− fn render<'a>(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
13+impl<'a> Render<'a> for Hello {
14+ fn render(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
1515 let msg = bumpalo::format!(in cx.bump, "Hello, {}!", self.who);
1616 let msg = msg.into_bump_str();
1717 p(&cx).children([text(msg)]).finish()
examples/input-form/Cargo.toml+3−3
@@ -11,11 +11,11 @@ crate-type = ["cdylib"]
1111
1212[dependencies]
1313dodrio = { path = "../.." }
14−wasm-bindgen = "0.2.42"
14+wasm-bindgen = "0.2.55"
1515console_error_panic_hook = "0.1.6"
1616
1717[dependencies.web-sys]
18−version = "0.3.19"
18+version = "0.3.32"
1919features = [
2020 "console",
2121 "Document",
@@ -29,4 +29,4 @@ features = [
2929]
3030
3131[dev-dependencies]
32−wasm-bindgen-test = "0.2.42"
32+wasm-bindgen-test = "0.3.5"
examples/input-form/src/lib.rs+2−2
@@ -23,8 +23,8 @@ impl SayHelloTo {
2323
2424// The `Render` implementation has a text `<input>` and a `<div>` that shows a
2525// greeting to the `<input>`'s value.
26−impl Render for SayHelloTo {
27− fn render<'a>(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
26+impl<'a> Render<'a> for SayHelloTo {
27+ fn render(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
2828 use dodrio::builder::*;
2929
3030 div(&cx)
examples/js-component/Cargo.toml+3−3
@@ -12,12 +12,12 @@ crate-type = ["cdylib"]
1212[dependencies]
1313dodrio = { path = "../.." }
1414dodrio-js-api = { path = "../../crates/js-api" }
15−wasm-bindgen = "0.2.42"
15+wasm-bindgen = "0.2.55"
1616console_error_panic_hook = "0.1.6"
17−js-sys = "0.3.19"
17+js-sys = "0.3.32"
1818
1919[dependencies.web-sys]
20−version = "0.3.19"
20+version = "0.3.32"
2121features = [
2222 "Document",
2323 "HtmlElement",
examples/js-component/src/lib.rs+2−2
@@ -31,8 +31,8 @@ impl GreetingViaJs {
3131
3232/// Here's the `Render` implementation! This adds a `<p>` element and some text
3333/// around whatever the inner JS `Greeting` component renders.
34−impl Render for GreetingViaJs {
35− fn render<'a>(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
34+impl<'a> Render<'a> for GreetingViaJs {
35+ fn render(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
3636 use dodrio::builder::*;
3737 p(&cx)
3838 .children([text("JavaScript says: "), self.js.render(cx)])
examples/moire/Cargo.toml+8−9
@@ -8,20 +8,19 @@ edition = "2018"
88crate-type = ["cdylib"]
99
1010[dependencies]
11−cfg-if = "0.1.9"
11+cfg-if = "0.1.10"
1212dodrio = { path = "../.." }
13−futures = "0.1.28"
14−log = "0.4.8"
15−wasm-bindgen = "0.2.42"
16−wasm-bindgen-futures = "0.3.19"
13+log = "0.4.11"
14+wasm-bindgen = "0.2.55"
15+wasm-bindgen-futures = "0.4.5"
1716
1817# Optional dependencies for logging.
1918console_error_panic_hook = { optional = true, version = "0.1.6" }
20−console_log = { optional = true, version = "0.1.2" }
21−js-sys = "0.3.19"
19+console_log = { optional = true, version = "0.2.0" }
20+js-sys = "0.3.32"
2221
2322[dependencies.web-sys]
24−version = "0.3.19"
23+version = "0.3.32"
2524features = [
2625 "Document",
2726 "Element",
@@ -35,7 +34,7 @@ features = [
3534]
3635
3736[dev-dependencies]
38−wasm-bindgen-test = "0.2.42"
37+wasm-bindgen-test = "0.3.5"
3938
4039[features]
4140logging = [
examples/moire/src/lib.rs+4−4
@@ -27,7 +27,7 @@ pub fn run() {
2727 let vdom = Vdom::new(&scene, component);
2828
2929 // Kick off a loop that keeps re-rendering on every animation frame.
30− let rc: Rc<RefCell<Option<Closure<FnMut()>>>> = Rc::new(RefCell::new(None));
30+ let rc = <Rc<RefCell<Option<Closure<dyn FnMut()>>>>>::default();
3131 let rc2 = rc.clone();
3232 let window2 = window.clone();
3333 let weak = vdom.weak();
@@ -42,7 +42,7 @@ pub fn run() {
4242 .unchecked_ref::<js_sys::Function>(),
4343 )
4444 .unwrap_throw();
45− }) as Box<FnMut()>);
45+ }) as Box<dyn FnMut()>);
4646 window2
4747 .request_animation_frame(f.as_ref().unchecked_ref::<js_sys::Function>())
4848 .unwrap_throw();
@@ -104,8 +104,8 @@ impl Moire {
104104 }
105105}
106106
107−impl Render for Moire {
108− fn render<'a>(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
107+impl<'a> Render<'a> for Moire {
108+ fn render(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
109109 use dodrio::builder::*;
110110
111111 let elapsed = web_sys::window()
examples/sierpinski-triangle/Cargo.toml+5−6
@@ -9,14 +9,13 @@ crate-type = ["cdylib"]
99
1010[dependencies]
1111dodrio = { path = "../.." }
12−wasm-bindgen = "0.2.42"
12+wasm-bindgen = "0.2.55"
1313console_error_panic_hook = "0.1.6"
14−js-sys = "0.3.19"
15−wasm-bindgen-futures = "0.3.19"
16−futures = "0.1.28"
14+js-sys = "0.3.32"
15+wasm-bindgen-futures = "0.4.5"
1716
1817[dependencies.web-sys]
19−version = "0.3.19"
18+version = "0.3.32"
2019features = [
2120 "Document",
2221 "HtmlElement",
@@ -26,4 +25,4 @@ features = [
2625]
2726
2827[dev-dependencies]
29−wasm-bindgen-test = "0.2.42"
28+wasm-bindgen-test = "0.3.5"
examples/sierpinski-triangle/src/lib.rs+4−4
@@ -85,8 +85,8 @@ impl Container {
8585 }
8686}
8787
88−impl Render for Container {
89− fn render<'a>(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
88+impl<'a> Render<'a> for Container {
89+ fn render(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
9090 use dodrio::builder::div;
9191
9292 let elapsed = web_sys::window()
@@ -111,7 +111,7 @@ impl Render for Container {
111111
112112// Kick off a loop that keeps re-rendering on every animation frame.
113113fn animate(window: Window, vdom: Vdom) {
114− let rc: Rc<RefCell<Option<Closure<FnMut()>>>> = Rc::new(RefCell::new(None));
114+ let rc = <Rc<RefCell<Option<Closure<dyn FnMut()>>>>>::default();
115115 let rc2 = rc.clone();
116116 let window2 = window.clone();
117117 let weak = vdom.weak();
@@ -126,7 +126,7 @@ fn animate(window: Window, vdom: Vdom) {
126126 .unchecked_ref::<js_sys::Function>(),
127127 )
128128 .unwrap_throw();
129− }) as Box<FnMut()>);
129+ }) as Box<dyn FnMut()>);
130130 window2
131131 .request_animation_frame(f.as_ref().unchecked_ref::<js_sys::Function>())
132132 .unwrap_throw();
examples/todomvc/Cargo.toml+10−11
@@ -5,22 +5,21 @@ name = "dodrio-todomvc"
55version = "0.1.0"
66
77[dependencies]
8−cfg-if = "0.1.9"
8+cfg-if = "0.1.10"
99dodrio = { path = "../..", features = ["serde"] }
10−futures = "0.1.28"
11−js-sys = "0.3.19"
12−serde = { features = ["derive"], version = "1.0.98" }
13−serde_json = "1.0.40"
14−wasm-bindgen = "0.2.42"
15−wasm-bindgen-futures = "0.3.19"
10+js-sys = "0.3.32"
11+serde = { features = ["derive"], version = "1.0.114" }
12+serde_json = "1.0.57"
13+wasm-bindgen = "0.2.55"
14+wasm-bindgen-futures = "0.4.5"
1615
1716# Optional dependencies for logging.
1817console_error_panic_hook = { optional = true, version = "0.1.6" }
19−console_log = { optional = true, version = "0.1.2" }
20−log = { optional = true, version = "0.4.8" }
18+console_log = { optional = true, version = "0.2.0" }
19+log = { optional = true, version = "0.4.11" }
2120
2221[dependencies.web-sys]
23−version = "0.3.19"
22+version = "0.3.32"
2423features = [
2524 "Document",
2625 "Event",
@@ -35,7 +34,7 @@ features = [
3534]
3635
3736[dev-dependencies]
38−wasm-bindgen-test = "0.2.42"
37+wasm-bindgen-test = "0.3.5"
3938
4039[features]
4140logging = [
examples/todomvc/src/router.rs+22−19
@@ -4,7 +4,6 @@ use crate::todos::Todos;
44use crate::utils;
55use crate::visibility::Visibility;
66use dodrio::VdomWeak;
7−use futures::prelude::*;
87use std::str::FromStr;
98use wasm_bindgen::{prelude::*, JsCast};
109
@@ -29,23 +28,27 @@ pub fn start(vdom: VdomWeak) {
2928 v
3029 });
3130
32− wasm_bindgen_futures::spawn_local(
33− vdom.with_component({
34− let vdom = vdom.clone();
35− move |root| {
36− let todos = root.unwrap_mut::<Todos>();
37− // If the todos' visibility already matches the event's
38− // visibility, then there is nothing to do (ha). If they
39− // don't match, then we need to update the todos' visibility
40− // and re-render.
41− if todos.visibility() != new_vis {
42− todos.set_visibility(new_vis);
43− vdom.schedule_render();
44− }
45− }
46− })
47− .map_err(|_| ()),
48− );
31+ wasm_bindgen_futures::spawn_local({
32+ let vdom = vdom.clone();
33+ async move {
34+ let _ = vdom
35+ .with_component({
36+ let vdom = vdom.clone();
37+ move |root| {
38+ let todos = root.unwrap_mut::<Todos>();
39+ // If the todos' visibility already matches the event's
40+ // visibility, then there is nothing to do (ha). If they
41+ // don't match, then we need to update the todos' visibility
42+ // and re-render.
43+ if todos.visibility() != new_vis {
44+ todos.set_visibility(new_vis);
45+ vdom.schedule_render();
46+ }
47+ }
48+ })
49+ .await;
50+ }
51+ });
4952 };
5053
5154 // Call it once to handle the initial `#` fragment.
@@ -56,7 +59,7 @@ pub fn start(vdom: VdomWeak) {
5659 // Note that if we ever intended to unmount our todos app, we would want to
5760 // provide a method for removing this router's event listener and cleaning
5861 // up after ourselves.
59− let on_hash_change = Closure::wrap(Box::new(on_hash_change) as Box<FnMut()>);
62+ let on_hash_change = Closure::wrap(Box::new(on_hash_change) as Box<dyn FnMut()>);
6063 let window = utils::window();
6164 window
6265 .add_event_listener_with_callback("hashchange", on_hash_change.as_ref().unchecked_ref())
examples/todomvc/src/todo.rs+2−2
@@ -116,8 +116,8 @@ impl<C> Todo<C> {
116116 }
117117}
118118
119−impl<C: TodoActions> Render for Todo<C> {
120− fn render<'a>(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
119+impl<'a, C: TodoActions> Render<'a> for Todo<C> {
120+ fn render(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
121121 use dodrio::{
122122 builder::*,
123123 bumpalo::{self, collections::String},
examples/todomvc/src/todos.rs+2−2
@@ -289,8 +289,8 @@ impl<C: TodosActions> Todos<C> {
289289 }
290290}
291291
292−impl<C: TodosActions> Render for Todos<C> {
293− fn render<'a>(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
292+impl<'a, C: TodosActions> Render<'a> for Todos<C> {
293+ fn render(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
294294 use dodrio::builder::*;
295295
296296 div(&cx)
src/cached.rs+7−7
@@ -45,8 +45,8 @@ where
4545 /// count: u32,
4646 /// }
4747 ///
48− /// impl Render for Counter {
49− /// fn render<'a>(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
48+ /// impl<'a> Render<'a> for Counter {
49+ /// fn render(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
5050 /// // ...
5151 /// # unimplemented!()
5252 /// }
@@ -85,8 +85,8 @@ where
8585 /// who: String
8686 /// }
8787 ///
88− /// impl Render for Hello {
89− /// fn render<'a>(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
88+ /// impl<'a> Render<'a> for Hello {
89+ /// fn render(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
9090 /// use dodrio::builder::*;
9191 /// let greeting = bumpalo::format!(in cx.bump, "Hello, {}!", self.who);
9292 /// p(&cx)
@@ -143,11 +143,11 @@ where
143143 }
144144}
145145
146−impl<R> Render for Cached<R>
146+impl<'a, R> Render<'a> for Cached<R>
147147where
148− R: 'static + Default + Render,
148+ R: 'static + Default + for<'b> Render<'b>,
149149{
150− fn render<'a>(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
150+ fn render(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
151151 let template = cx.template::<R>();
152152 let cached = match self.cached.get() {
153153 // This does-the-cache-contain-this-id check is necessary because
src/change_list/mod.rs+2−2
@@ -233,9 +233,9 @@ impl ChangeListBuilder<'_> {
233233 self.state.emitter.replace_with();
234234 }
235235
236− pub fn set_attribute(&mut self, name: &str, value: &str) {
236+ pub fn set_attribute(&mut self, name: &str, value: &str, is_namespaced: bool) {
237237 debug_assert!(self.traversal_is_committed());
238− if name == "class" {
238+ if name == "class" && !is_namespaced {
239239 let class_id = self.ensure_string(value);
240240 debug!("emit: set_class({:?})", value);
241241 self.state.emitter.set_class(class_id.into());
src/change_list/traversal.rs+1−1
@@ -167,7 +167,7 @@ mod tests {
167167
168168 #[test]
169169 fn test_traversal() {
170− fn t<F>(f: F) -> Box<FnMut(&mut Traversal)>
170+ fn t<F>(f: F) -> Box<dyn FnMut(&mut Traversal)>
171171 where
172172 F: 'static + FnMut(&mut Traversal),
173173 {
src/diff.rs+6−6
@@ -78,7 +78,7 @@ pub(crate) fn diff(
7878 return;
7979 }
8080 diff_listeners(change_list, registry, old_listeners, new_listeners);
81− diff_attributes(change_list, old_attributes, new_attributes);
81+ diff_attributes(change_list, old_attributes, new_attributes, new_namespace.is_some());
8282 diff_children(
8383 cached_set,
8484 change_list,
@@ -204,26 +204,26 @@ fn diff_listeners(
204204// [... node]
205205//
206206// The change list stack is left unchanged.
207−fn diff_attributes(change_list: &mut ChangeListBuilder, old: &[Attribute], new: &[Attribute]) {
207+fn diff_attributes(change_list: &mut ChangeListBuilder, old: &[Attribute], new: &[Attribute], is_namespaced: bool) {
208208 // Do O(n^2) passes to add/update and remove attributes, since
209209 // there are almost always very few attributes.
210210 'outer: for new_attr in new {
211211 if new_attr.is_volatile() {
212212 change_list.commit_traversal();
213− change_list.set_attribute(new_attr.name, new_attr.value);
213+ change_list.set_attribute(new_attr.name, new_attr.value, is_namespaced);
214214 } else {
215215 for old_attr in old {
216216 if old_attr.name == new_attr.name {
217217 if old_attr.value != new_attr.value {
218218 change_list.commit_traversal();
219− change_list.set_attribute(new_attr.name, new_attr.value);
219+ change_list.set_attribute(new_attr.name, new_attr.value, is_namespaced);
220220 }
221221 continue 'outer;
222222 }
223223 }
224224
225225 change_list.commit_traversal();
226− change_list.set_attribute(new_attr.name, new_attr.value);
226+ change_list.set_attribute(new_attr.name, new_attr.value, is_namespaced);
227227 }
228228 }
229229
@@ -953,7 +953,7 @@ fn create(
953953 }
954954
955955 for attr in attributes {
956− change_list.set_attribute(&attr.name, &attr.value);
956+ change_list.set_attribute(&attr.name, &attr.value, namespace.is_some());
957957 }
958958
959959 // Fast path: if there is a single text child, it is faster to
src/lib.rs+2−2
@@ -18,8 +18,8 @@
1818//! }
1919//! }
2020//!
21−//! impl<'who> Render for Hello<'who> {
22−//! fn render<'a>(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
21+//! impl<'a, 'who> Render<'a> for Hello<'who> {
22+//! fn render(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
2323//! use dodrio::builder::*;
2424//!
2525//! let id = bumpalo::format!(in cx.bump, "hello-{}", self.who);
src/render.rs+39−12
@@ -21,8 +21,8 @@ use wasm_bindgen::UnwrapThrowExt;
2121///
2222/// pub struct MyComponent;
2323///
24−/// impl Render for MyComponent {
25−/// fn render<'a>(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
24+/// impl<'a> Render<'a> for MyComponent {
25+/// fn render(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
2626/// use dodrio::builder::*;
2727///
2828/// p(&cx)
@@ -35,26 +35,26 @@ use wasm_bindgen::UnwrapThrowExt;
3535/// }
3636/// }
3737/// ```
38−pub trait Render {
38+pub trait Render<'a> {
3939 /// Render `self` as a virtual DOM. Use the given context's `Bump` for
4040 /// temporary allocations.
41− fn render<'a>(&self, cx: &mut RenderContext<'a>) -> Node<'a>;
41+ fn render(&self, cx: &mut RenderContext<'a>) -> Node<'a>;
4242}
4343
44−impl<'r, R> Render for &'r R
44+impl<'a, 'r, R> Render<'a> for &'r R
4545where
46− R: Render,
46+ R: Render<'a>,
4747{
48− fn render<'a>(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
48+ fn render(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
4949 (**self).render(cx)
5050 }
5151}
5252
53−impl<R> Render for Rc<R>
53+impl<'a, R> Render<'a> for Rc<R>
5454where
55− R: Render,
55+ R: Render<'a>,
5656{
57− fn render<'a>(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
57+ fn render(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
5858 (**self).render(cx)
5959 }
6060}
@@ -69,7 +69,7 @@ where
6969/// You do not need to implement this trait by hand: there is a blanket
7070/// implementation for all `Render` types that fulfill the `RootRender`
7171/// requirements.
72−pub trait RootRender: Any + Render {
72+pub trait RootRender: Any + for<'a> Render<'a> {
7373 /// Get this `&RootRender` trait object as an `&Any` trait object reference.
7474 fn as_any(&self) -> &dyn Any;
7575
@@ -80,7 +80,7 @@ pub trait RootRender: Any + Render {
8080
8181impl<T> RootRender for T
8282where
83− T: Any + Render,
83+ T: Any + for<'a> Render<'a>,
8484{
8585 fn as_any(&self) -> &dyn Any {
8686 self
@@ -138,4 +138,31 @@ mod tests {
138138 #[allow(dead_code)]
139139 fn takes_dyn_render(_: &dyn super::RootRender) {}
140140 }
141+
142+ #[test]
143+ fn render_bump_scoped_child() {
144+ use crate::{builder::*, bumpalo::collections::String, Node, Render, RenderContext};
145+
146+ struct Child<'a> {
147+ name: &'a str,
148+ }
149+
150+ impl<'a> Render<'a> for Child<'a> {
151+ fn render(&self, _cx: &mut RenderContext<'a>) -> Node<'a> {
152+ text(self.name)
153+ }
154+ }
155+
156+ struct Parent;
157+
158+ impl<'a> Render<'a> for Parent {
159+ fn render(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
160+ let child_name = String::from_str_in("child", cx.bump).into_bump_str();
161+
162+ div(&cx)
163+ .children([Child { name: child_name }.render(cx)])
164+ .finish()
165+ }
166+ }
167+ }
141168}
src/render_context.rs+1−1
@@ -69,7 +69,7 @@ impl<'a> RenderContext<'a> {
6969 /// Get or create the cached template for `Cached<R>`.
7070 pub(crate) fn template<R>(&mut self) -> Option<CacheId>
7171 where
72− R: 'static + Default + Render,
72+ R: 'static + Default + for<'b> Render<'b>,
7373 {
7474 let template_id = Cached::<R>::template_id();
7575 if let Some(cache_id) = self.templates.get(&template_id).cloned() {
src/vdom.rs+6
@@ -380,6 +380,9 @@ impl VdomWeak {
380380 ) -> Result<Box<dyn RootRender + 'static>, VdomDroppedError> {
381381 let inner = self.inner.upgrade().ok_or(VdomDroppedError {})?;
382382
383+ // Wait for a new tick of the micro-task queue
384+ let _ = JsFuture::from(js_sys::Promise::resolve(&JsValue::null())).await;
385+
383386 let old = {
384387 let mut exclusive = inner.exclusive.borrow_mut();
385388 mem::replace(&mut *exclusive.component.as_mut().unwrap_throw(), root)
@@ -401,6 +404,9 @@ impl VdomWeak {
401404 {
402405 let inner = self.inner.upgrade().ok_or(VdomDroppedError {})?;
403406
407+ // Wait for a new tick of the micro-task queue
408+ let _ = JsFuture::from(js_sys::Promise::resolve(&JsValue::null())).await;
409+
404410 let mut exclusive = inner.exclusive.borrow_mut();
405411
406412 Ok(f(exclusive.component_raw_mut()))
tests/web/cached.rs+73−65
@@ -1,6 +1,5 @@
11use super::{assert_rendered, before_after, create_element, RenderFn};
22use dodrio::{builder::*, bumpalo, Cached, Node, Render, RenderContext, RootRender, Vdom};
3−use futures::prelude::*;
43use std::cell::Cell;
54use std::rc::Rc;
65use wasm_bindgen::prelude::*;
@@ -19,8 +18,8 @@ impl CountRenders {
1918 }
2019}
2120
22−impl Render for CountRenders {
23− fn render<'a>(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
21+impl<'a> Render<'a> for CountRenders {
22+ fn render(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
2423 let count = self.render_count.get() + 1;
2524 self.render_count.set(count);
2625
@@ -29,8 +28,8 @@ impl Render for CountRenders {
2928 }
3029}
3130
32−#[wasm_bindgen_test(async)]
33−fn uses_cached_render() -> impl Future<Item = (), Error = JsValue> {
31+#[wasm_bindgen_test]
32+async fn uses_cached_render() {
3433 use dodrio::builder::*;
3534
3635 let cached = Cached::new(CountRenders::new());
@@ -50,52 +49,61 @@ fn uses_cached_render() -> impl Future<Item = (), Error = JsValue> {
5049 let vdom6 = vdom0.clone();
5150 let vdom7 = vdom0.clone();
5251
52+ // We render, populate the cache, and get "1".
53+ vdom0.weak().render().await.unwrap();
5354 vdom0
5455 .weak()
55− // We render, populate the cache, and get "1".
56− .render()
57− .and_then(move |_| {
58− vdom0.weak().with_component(move |comp| {
59− let comp = comp.unwrap_mut::<Cached<CountRenders>>();
60− assert_eq!(comp.render_count.get(), 1);
61− assert_rendered(&container1, &RenderFn(|_| text("1")));
62− })
56+ .with_component(move |comp| {
57+ let comp = comp.unwrap_mut::<Cached<CountRenders>>();
58+ assert_eq!(comp.render_count.get(), 1);
59+ assert_rendered(&container1, &RenderFn(|_| text("1")));
6360 })
64− // We re-render, re-use the cached node, and get "1" again.
65− .and_then(move |_| vdom1.weak().render())
66− .and_then(move |_| {
67− vdom2.weak().with_component(move |comp| {
68− let comp = comp.unwrap_mut::<Cached<CountRenders>>();
69− assert_eq!(comp.render_count.get(), 1);
70− assert_rendered(&container2, &RenderFn(|_| text("1")));
71− })
61+ .await
62+ .unwrap();
63+
64+ // We re-render, re-use the cached node, and get "1" again.
65+ vdom1.weak().render().await.unwrap();
66+ vdom2
67+ .weak()
68+ .with_component(move |comp| {
69+ let comp = comp.unwrap_mut::<Cached<CountRenders>>();
70+ assert_eq!(comp.render_count.get(), 1);
71+ assert_rendered(&container2, &RenderFn(|_| text("1")));
7272 })
73− // We invalidate the cache, re-render, re-populate the cache, and should
74− // now have "2".
75− .and_then(move |_| {
76− vdom3.weak().with_component(move |comp| {
77− let comp = comp.unwrap_mut::<Cached<CountRenders>>();
78− Cached::invalidate(comp);
79− })
73+ .await
74+ .unwrap();
75+
76+ // We invalidate the cache, re-render, re-populate the cache, and should now have "2".
77+ vdom3
78+ .weak()
79+ .with_component(move |comp| {
80+ let comp = comp.unwrap_mut::<Cached<CountRenders>>();
81+ Cached::invalidate(comp);
8082 })
81− .and_then(move |_| vdom4.weak().render())
82− .and_then(move |_| {
83− vdom5.weak().with_component(move |comp| {
84− let comp = comp.unwrap_mut::<Cached<CountRenders>>();
85− assert_eq!(comp.render_count.get(), 2);
86− assert_rendered(&container3, &RenderFn(|_| text("2")));
87− })
83+ .await
84+ .unwrap();
85+ vdom4.weak().render().await.unwrap();
86+ vdom5
87+ .weak()
88+ .with_component(move |comp| {
89+ let comp = comp.unwrap_mut::<Cached<CountRenders>>();
90+ assert_eq!(comp.render_count.get(), 2);
91+ assert_rendered(&container3, &RenderFn(|_| text("2")));
8892 })
89− // We re-render, re-use the cached node, and get "2" again.
90− .and_then(move |_| vdom6.weak().render())
91− .and_then(move |_| {
92− vdom7.weak().with_component(move |comp| {
93− let comp = comp.unwrap_mut::<Cached<CountRenders>>();
94− assert_eq!(comp.render_count.get(), 2);
95− assert_rendered(&container4, &RenderFn(|_| text("2")));
96− })
93+ .await
94+ .unwrap();
95+
96+ // We re-render, re-use the cached node, and get "2" again.
97+ vdom6.weak().render().await.unwrap();
98+ vdom7
99+ .weak()
100+ .with_component(move |comp| {
101+ let comp = comp.unwrap_mut::<Cached<CountRenders>>();
102+ assert_eq!(comp.render_count.get(), 2);
103+ assert_rendered(&container4, &RenderFn(|_| text("2")));
97104 })
98− .map_err(|e| JsValue::from(e.to_string()))
105+ .await
106+ .unwrap();
99107}
100108
101109#[wasm_bindgen(module = "/tests/web/cached.js")]
@@ -104,8 +112,8 @@ extern "C" {
104112 fn get_clone_node_count() -> u32;
105113}
106114
107−#[wasm_bindgen_test(async)]
108−fn creating_cached_nodes_uses_clone_node() -> impl Future<Item = (), Error = JsValue> {
115+#[wasm_bindgen_test]
116+async fn creating_cached_nodes_uses_clone_node() {
109117 use dodrio::builder::*;
110118
111119 let container = create_element("div");
@@ -113,28 +121,28 @@ fn creating_cached_nodes_uses_clone_node() -> impl Future<Item = (), Error = JsV
113121 // The initial vdom render should populate the cache and save a template.
114122 let vdom0 = Rc::new(Vdom::new(&container, Cached::new(CountRenders::new())));
115123 let vdom1 = vdom0.clone();
116− let vdom2 = vdom0.clone();
124+ let _vdom2 = vdom0.clone();
117125
118126 let clone_node_count_before = get_clone_node_count();
119127
128+ // Render something entirely different...
120129 vdom0
121130 .weak()
122− // Render something entirely different...
123− .set_component(Box::new(RenderFn(|_| text("hi"))) as Box<RootRender>)
124− .and_then(move |_| {
125− // Re-render our cached node. Since we are creating it from scratch,
126− // and already have a template from the earlier render, we should
127− // call `cloneNode` here.
128− vdom1
129− .weak()
130− .set_component(Box::new(Cached::new(CountRenders::new())) as Box<RootRender>)
131− })
132− .map(move |_| {
133− let clone_node_count_after = get_clone_node_count();
134− assert_eq!(clone_node_count_after, clone_node_count_before + 1);
135− drop(vdom2);
136− })
137− .map_err(|e| JsValue::from(e.to_string()))
131+ .set_component(Box::new(RenderFn(|_| text("hi"))) as Box<dyn RootRender>)
132+ .await
133+ .unwrap();
134+
135+ // Re-render our cached node. Since we are creating it from scratch,
136+ // and already have a template from the earlier render, we should
137+ // call `cloneNode` here.
138+ vdom1
139+ .weak()
140+ .set_component(Box::new(Cached::new(CountRenders::new())) as Box<dyn RootRender>)
141+ .await
142+ .unwrap();
143+
144+ let clone_node_count_after = get_clone_node_count();
145+ assert_eq!(clone_node_count_after, clone_node_count_before + 1);
138146}
139147
140148struct Id(&'static str);
@@ -145,8 +153,8 @@ impl Default for Id {
145153 }
146154}
147155
148−impl Render for Id {
149− fn render<'a>(&self, _cx: &mut RenderContext<'a>) -> Node<'a> {
156+impl<'a> Render<'a> for Id {
157+ fn render(&self, _cx: &mut RenderContext<'a>) -> Node<'a> {
150158 text(self.0)
151159 }
152160}
tests/web/events.rs+56−73
@@ -1,6 +1,6 @@
11use super::create_element;
22use dodrio::{Node, Render, RenderContext, Vdom};
3−use futures::Future;
3+use futures::future::{select, Either};
44use std::cell::{Cell, RefCell};
55use std::rc::Rc;
66use wasm_bindgen::prelude::*;
@@ -9,7 +9,7 @@ use wasm_bindgen_test::*;
99
1010struct EventContainer {
1111 event: &'static str,
12− on_event: Box<FnMut()>,
12+ on_event: Box<dyn FnMut()>,
1313}
1414
1515impl EventContainer {
@@ -24,8 +24,8 @@ impl EventContainer {
2424 }
2525}
2626
27−impl Render for EventContainer {
28− fn render<'a>(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
27+impl<'a> Render<'a> for EventContainer {
28+ fn render(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
2929 use dodrio::builder::*;
3030 div(&cx)
3131 .attr("id", "target")
@@ -44,14 +44,14 @@ fn target(container: &web_sys::Element) -> web_sys::HtmlElement {
4444 .unchecked_into()
4545}
4646
47−#[wasm_bindgen_test(async)]
48−fn click() -> impl Future<Item = (), Error = JsValue> {
47+#[wasm_bindgen_test]
48+async fn click() {
4949 let container = create_element("div");
5050
51− let (sender, receiver) = futures::sync::oneshot::channel();
51+ let (sender, receiver) = futures::channel::oneshot::channel();
5252 let mut sender = Some(sender);
5353
54− let vdom = Vdom::new(
54+ let _vdom = Vdom::new(
5555 &container,
5656 EventContainer::new("click", move || {
5757 sender
@@ -64,18 +64,14 @@ fn click() -> impl Future<Item = (), Error = JsValue> {
6464
6565 target(&container).click();
6666
67− receiver
68− .map(|_| {
69− drop(vdom);
70− })
71− .map_err(|e| JsValue::from(e.to_string()))
67+ receiver.await.unwrap();
7268}
7369
74−#[wasm_bindgen_test(async)]
75−fn updated_listener_is_called() -> impl Future<Item = (), Error = JsValue> {
70+#[wasm_bindgen_test]
71+async fn updated_listener_is_called() {
7672 let container = create_element("div");
7773
78− let (first_sender, first_receiver) = futures::sync::oneshot::channel();
74+ let (first_sender, first_receiver) = futures::channel::oneshot::channel();
7975 let mut first_sender = Some(first_sender);
8076
8177 let vdom = Vdom::new(
@@ -89,7 +85,7 @@ fn updated_listener_is_called() -> impl Future<Item = (), Error = JsValue> {
8985 }),
9086 );
9187
92− let (second_sender, second_receiver) = futures::sync::oneshot::channel();
88+ let (second_sender, second_receiver) = futures::channel::oneshot::channel();
9389 let mut second_sender = Some(second_sender);
9490
9591 vdom.weak()
@@ -100,25 +96,22 @@ fn updated_listener_is_called() -> impl Future<Item = (), Error = JsValue> {
10096 .send("second")
10197 .expect_throw("should not have dropped the receiver");
10298 })))
103− .map_err(|e| JsValue::from(e.to_string()))
104− .and_then(move |_| {
105− target(&container).click();
106−
107− first_receiver
108− .select(second_receiver)
109− .map(|(which, _other)| which)
110− .or_else(|(_error, other)| other)
111− .map(|which| {
112− assert_eq!(which, "second");
113− drop(vdom);
114− })
115− .map_err(|e| JsValue::from(e.to_string()))
116− })
99+ .await
100+ .unwrap();
101+
102+ target(&container).click();
103+
104+ match select(first_receiver, second_receiver).await {
105+ Either::Left((Ok(_), _)) => panic!(),
106+ Either::Left((Err(_), second)) => assert_eq!(second.await, Ok("second")),
107+ Either::Right((Ok(msg), _)) => assert_eq!(msg, "second"),
108+ Either::Right((Err(_), _)) => panic!(),
109+ }
117110}
118111
119112struct ListensOnlyOnFirstRender {
120113 count: Cell<usize>,
121− callback: Box<FnMut()>,
114+ callback: Box<dyn FnMut()>,
122115}
123116
124117impl ListensOnlyOnFirstRender {
@@ -133,8 +126,8 @@ impl ListensOnlyOnFirstRender {
133126 }
134127}
135128
136−impl Render for ListensOnlyOnFirstRender {
137− fn render<'a>(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
129+impl<'a> Render<'a> for ListensOnlyOnFirstRender {
130+ fn render(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
138131 use dodrio::builder::*;
139132
140133 let count = self.count.get();
@@ -150,11 +143,11 @@ impl Render for ListensOnlyOnFirstRender {
150143 }
151144}
152145
153−#[wasm_bindgen_test(async)]
154−fn removed_listener_is_not_called() -> impl Future<Item = (), Error = JsValue> {
146+#[wasm_bindgen_test]
147+async fn removed_listener_is_not_called() {
155148 let container = create_element("div");
156149
157− let (outer_sender, outer_receiver) = futures::sync::oneshot::channel();
150+ let (outer_sender, outer_receiver) = futures::channel::oneshot::channel();
158151 let outer_sender = Rc::new(RefCell::new(Some(outer_sender)));
159152 let outer_listener = Closure::wrap(Box::new(move |_| {
160153 outer_sender
@@ -163,13 +156,13 @@ fn removed_listener_is_not_called() -> impl Future<Item = (), Error = JsValue> {
163156 .expect_throw("should only invoke outer_listener once")
164157 .send("outer")
165158 .expect_throw("should not have dropped receiver");
166− }) as Box<FnMut(web_sys::Event)>);
159+ }) as Box<dyn FnMut(web_sys::Event)>);
167160
168161 container
169162 .add_event_listener_with_callback("click", outer_listener.as_ref().unchecked_ref())
170163 .unwrap();
171164
172− let (vdom_sender, vdom_receiver) = futures::sync::oneshot::channel();
165+ let (vdom_sender, vdom_receiver) = futures::channel::oneshot::channel();
173166 let mut vdom_sender = Some(vdom_sender);
174167
175168 // Render a vdom with a listener into container.
@@ -184,33 +177,26 @@ fn removed_listener_is_not_called() -> impl Future<Item = (), Error = JsValue> {
184177 }),
185178 );
186179
187− vdom.weak()
188− // Re-render, so we aren't listening anymore.
189− .render()
190− .map_err(|e| JsValue::from(e.to_string()))
191− .and_then(move |_| {
192− target(&container).click();
193−
194− // We should get our container's event handler fired, and not the unmounted
195− // vdom's event handler.
196− outer_receiver
197− .select(vdom_receiver)
198− .map(|(which, _other)| which)
199− .or_else(|(_error, other)| other)
200− .map(|which| {
201− assert_eq!(which, "outer");
202− drop(outer_listener);
203− drop(vdom)
204− })
205− .map_err(|e| JsValue::from(e.to_string()))
206− })
180+ // Re-render, so we aren't listening anymore.
181+ vdom.weak().render().await.unwrap();
182+
183+ target(&container).click();
184+
185+ // We should get our container's event handler fired, and not the unmounted
186+ // vdom's event handler.
187+ match select(outer_receiver, vdom_receiver).await {
188+ Either::Left((Ok(msg), _)) => assert_eq!(msg, ("outer")),
189+ Either::Left((Err(_), _)) => panic!(),
190+ Either::Right((Ok(_), _)) => panic!(),
191+ Either::Right((Err(_), outer)) => assert_eq!(outer.await, Ok("outer")),
192+ }
207193}
208194
209−#[wasm_bindgen_test(async)]
210−fn event_does_not_fire_after_unmounting() -> impl Future<Item = (), Error = JsValue> {
195+#[wasm_bindgen_test]
196+async fn event_does_not_fire_after_unmounting() {
211197 let container = create_element("div");
212198
213− let (outer_sender, outer_receiver) = futures::sync::oneshot::channel();
199+ let (outer_sender, outer_receiver) = futures::channel::oneshot::channel();
214200 let outer_sender = Rc::new(RefCell::new(Some(outer_sender)));
215201 let outer_listener = Closure::wrap(Box::new(move |_| {
216202 outer_sender
@@ -219,13 +205,13 @@ fn event_does_not_fire_after_unmounting() -> impl Future<Item = (), Error = JsVa
219205 .expect_throw("should only invoke outer_listener once")
220206 .send("outer")
221207 .expect_throw("should not have dropped receiver");
222− }) as Box<FnMut(web_sys::Event)>);
208+ }) as Box<dyn FnMut(web_sys::Event)>);
223209
224210 container
225211 .add_event_listener_with_callback("click", outer_listener.as_ref().unchecked_ref())
226212 .unwrap();
227213
228− let (vdom_sender, vdom_receiver) = futures::sync::oneshot::channel();
214+ let (vdom_sender, vdom_receiver) = futures::channel::oneshot::channel();
229215 let mut vdom_sender = Some(vdom_sender);
230216
231217 // Render a vdom with a listener into container.
@@ -255,13 +241,10 @@ fn event_does_not_fire_after_unmounting() -> impl Future<Item = (), Error = JsVa
255241
256242 // We should get our container's event handler fired, and not the unmounted
257243 // vdom's event handler.
258− outer_receiver
259− .select(vdom_receiver)
260− .map(|(which, _other)| which)
261− .or_else(|(_error, other)| other)
262− .map(|which| {
263− assert_eq!(which, "outer");
264− drop(outer_listener);
265− })
266− .map_err(|e| JsValue::from(e.to_string()))
244+ match select(outer_receiver, vdom_receiver).await {
245+ Either::Left((Ok(msg), _)) => assert_eq!(msg, ("outer")),
246+ Either::Left((Err(_), _)) => panic!(),
247+ Either::Right((Ok(_), _)) => panic!(),
248+ Either::Right((Err(_), outer)) => assert_eq!(outer.await, Ok("outer")),
249+ }
267250}
tests/web/js_api.rs+30−37
@@ -1,8 +1,7 @@
11use super::{assert_rendered, create_element, RenderFn};
22use dodrio::{builder::*, Node, Render, RenderContext, Vdom};
33use dodrio_js_api::JsRender;
4−use futures::prelude::*;
5−use futures::sync::oneshot;
4+use futures::channel::oneshot;
65use js_sys::Object;
76use std::rc::Rc;
87use wasm_bindgen::prelude::*;
@@ -14,7 +13,7 @@ pub struct WrapJs {
1413}
1514
1615impl WrapJs {
17− pub fn new() -> (WrapJs, oneshot::Receiver<()>, Closure<FnMut()>) {
16+ pub fn new() -> (WrapJs, oneshot::Receiver<()>, Closure<dyn FnMut()>) {
1817 let (sender, receiver) = oneshot::channel();
1918
2019 let on_after_render = Closure::wrap(Box::new({
@@ -26,7 +25,7 @@ impl WrapJs {
2625 .send(())
2726 .expect_throw("receiver should not have been dropped");
2827 }
29− }) as Box<FnMut()>);
28+ }) as Box<dyn FnMut()>);
3029
3130 let component = WrapJs {
3231 inner: JsRender::new(JsComponent::new(&on_after_render)),
@@ -36,8 +35,8 @@ impl WrapJs {
3635 }
3736}
3837
39−impl Render for WrapJs {
40− fn render<'a>(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
38+impl<'a> Render<'a> for WrapJs {
39+ fn render(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
4140 div(&cx)
4241 .attr("class", "wrap-js")
4342 .children([self.inner.render(cx)])
@@ -52,7 +51,7 @@ extern "C" {
5251 type JsComponent;
5352
5453 #[wasm_bindgen(constructor)]
55− fn new(on_after_render: &Closure<FnMut()>) -> JsComponent;
54+ fn new(on_after_render: &Closure<dyn FnMut()>) -> JsComponent;
5655}
5756
5857fn eval_js_rendering_component() {
@@ -96,14 +95,14 @@ fn eval_js_rendering_component() {
9695 });
9796}
9897
99−#[wasm_bindgen_test(async)]
100−fn can_use_js_rendering_components() -> impl Future<Item = (), Error = JsValue> {
98+#[wasm_bindgen_test]
99+async fn can_use_js_rendering_components() {
101100 eval_js_rendering_component();
102101
103102 let container = create_element("div");
104− let (component, receiver, closure) = WrapJs::new();
103+ let (component, receiver, _closure) = WrapJs::new();
104+ let _vdom = Rc::new(Vdom::new(&container, component));
105105
106− let vdom = Rc::new(Vdom::new(&container, component));
107106 assert_rendered(
108107 &container,
109108 &RenderFn(|cx| {
@@ -131,30 +130,24 @@ fn can_use_js_rendering_components() -> impl Future<Item = (), Error = JsValue>
131130 .expect_throw("should be an `HTMLElement` object")
132131 .click();
133132
134− receiver
135− .map(move |_| {
136− assert_rendered(
137− &container,
138− &RenderFn(|cx| {
139− div(&cx)
140− .attr("class", "wrap-js")
141− .children([span(&cx)
142− .attr("class", "js-component")
143− .children([
144− text("Here is some plain text"),
145− b(&cx)
146− .children([text("...and here is some bold text")])
147− .finish(),
148− text("1"),
149− ])
150− .finish()])
151− .finish()
152− }),
153− );
154−
155− drop(vdom);
156− drop(container);
157− drop(closure);
158− })
159− .map_err(|e| e.to_string().into())
133+ receiver.await.unwrap();
134+
135+ assert_rendered(
136+ &container,
137+ &RenderFn(|cx| {
138+ div(&cx)
139+ .attr("class", "wrap-js")
140+ .children([span(&cx)
141+ .attr("class", "js-component")
142+ .children([
143+ text("Here is some plain text"),
144+ b(&cx)
145+ .children([text("...and here is some bold text")])
146+ .finish(),
147+ text("1"),
148+ ])
149+ .finish()])
150+ .finish()
151+ }),
152+ );
160153}
tests/web/keyed.rs+18−19
@@ -1,6 +1,5 @@
11use crate::{assert_rendered, create_element};
22use dodrio::{builder::*, bumpalo, Node, Render, RenderContext, Vdom};
3−use futures::Future;
43use log::*;
54use std::rc::Rc;
65use wasm_bindgen::prelude::*;
@@ -8,8 +7,8 @@ use wasm_bindgen_test::*;
87
98struct Keyed(u16);
109
11−impl Render for Keyed {
12− fn render<'a>(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
10+impl<'a> Render<'a> for Keyed {
11+ fn render(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
1312 let key = bumpalo::format!(in cx.bump, "{}", self.0).into_bump_str();
1413 div(&cx)
1514 .attr("class", "keyed")
@@ -32,13 +31,10 @@ where
3231 parent.finish()
3332}
3433
35−fn assert_keyed<Before, After>(
36− before: Before,
37− after: After,
38−) -> impl Future<Item = (), Error = JsValue>
34+async fn assert_keyed<Before, After>(before: Before, after: After) -> Result<(), JsValue>
3935where
40− Before: 'static + Render,
41− After: 'static + Render,
36+ Before: 'static + for<'a> Render<'a>,
37+ After: 'static + for<'a> Render<'a>,
4238{
4339 #[wasm_bindgen(module = "/tests/web/keyed.js")]
4440 extern "C" {
@@ -56,7 +52,7 @@ where
5652
5753 debug!("====== Rendering the *before* DOM into the physical DOM ======");
5854 let vdom1 = Rc::new(Vdom::new(&container, before.clone()));
59− let vdom2 = vdom1.clone();
55+ let _vdom2 = vdom1.clone();
6056 let saved = save_keyed_elements(&container);
6157
6258 debug!("====== Checking the *before* DOM against the physical DOM ======");
@@ -65,13 +61,14 @@ where
6561 debug!("====== Rendering the *after* DOM into the physical DOM ======");
6662 let weak = vdom1.weak();
6763 weak.set_component(Box::new(after.clone()))
68− .map(move |_| {
69− debug!("====== Checking the *after* DOM against the physical DOM ======");
70− assert_rendered(&container, &after);
71− check_keyed_elements(&container, saved);
72− drop(vdom2);
73− })
74− .map_err(|e| JsValue::from(e.to_string()))
64+ .await
65+ .map_err(|e| e.to_string())?;
66+
67+ debug!("====== Checking the *after* DOM against the physical DOM ======");
68+ assert_rendered(&container, &after);
69+ check_keyed_elements(&container, saved);
70+
71+ Ok(())
7572}
7673
7774macro_rules! keyed_tests {
@@ -86,14 +83,16 @@ macro_rules! keyed_tests {
8683 }
8784 )* ) => {
8885 $(
89− #[wasm_bindgen_test(async)]
90− fn $name() -> impl Future<Item = (), Error = wasm_bindgen::JsValue> {
86+ #[wasm_bindgen_test]
87+ async fn $name() {
9188 use crate::RenderFn;
9289 log::debug!("############### {} ###############", stringify!($name));
9390 assert_keyed(
9491 RenderFn(|$before_cx| { $( $before )* }),
9592 RenderFn(|$after_cx| { $( $after )* }),
9693 )
94+ .await
95+ .unwrap()
9796 }
9897 )*
9998 }
tests/web/main.rs+19−17
@@ -6,7 +6,6 @@ use bumpalo::Bump;
66use dodrio::{
77 Attribute, CachedSet, ElementNode, Node, NodeKind, Render, RenderContext, TextNode, Vdom,
88};
9−use futures::prelude::*;
109use fxhash::FxHashMap;
1110use log::*;
1211use std::cell::RefCell;
@@ -51,7 +50,7 @@ pub fn init_logging() {
5150
5251/// Assert that the `container` contains the physical DOM tree that matches
5352/// `r`'s rendered virtual DOM.
54−pub fn assert_rendered<R: Render>(container: &web_sys::Element, r: &R) {
53+pub fn assert_rendered<R: for<'a> Render<'a>>(container: &web_sys::Element, r: &R) {
5554 init_logging();
5655
5756 let cached_set = &RefCell::new(CachedSet::default());
@@ -156,11 +155,11 @@ pub struct RenderFn<F>(F)
156155where
157156 F: for<'a> Fn(&mut RenderContext<'a>) -> Node<'a>;
158157
159−impl<F> Render for RenderFn<F>
158+impl<'a, F> Render<'a> for RenderFn<F>
160159where
161− F: for<'a> Fn(&mut RenderContext<'a>) -> Node<'a>,
160+ F: for<'b> Fn(&mut RenderContext<'b>) -> Node<'b>,
162161{
163− fn render<'a>(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
162+ fn render(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
164163 (self.0)(cx)
165164 }
166165}
@@ -168,10 +167,10 @@ where
168167/// Assert that if we start by rendering the `before` virtual DOM tree into a
169168/// physical DOM tree, and then diff it with the `after` virtual DOM tree, then
170169/// the physical DOM tree correctly matches `after`.
171−pub fn assert_before_after<R, S>(before: R, after: S) -> impl Future<Item = (), Error = JsValue>
170+pub async fn assert_before_after<R, S>(before: R, after: S) -> Result<(), JsValue>
172171where
173− R: 'static + Render,
174− S: 'static + Render,
172+ R: 'static + for<'a> Render<'a>,
173+ S: 'static + for<'a> Render<'a>,
175174{
176175 let container = create_element("div");
177176
@@ -180,7 +179,7 @@ where
180179
181180 debug!("====== Rendering the *before* DOM into the physical DOM ======");
182181 let vdom1 = Rc::new(Vdom::new(&container, before.clone()));
183− let vdom2 = vdom1.clone();
182+ let _vdom2 = vdom1.clone();
184183
185184 debug!("====== Checking the *before* DOM against the physical DOM ======");
186185 assert_rendered(&container, &before);
@@ -188,12 +187,13 @@ where
188187 debug!("====== Rendering the *after* DOM into the physical DOM ======");
189188 let weak = vdom1.weak();
190189 weak.set_component(Box::new(after.clone()))
191− .map(move |_| {
192− debug!("====== Checking the *after* DOM against the physical DOM ======");
193− assert_rendered(&container, &after);
194− drop(vdom2);
195− })
196− .map_err(|e| JsValue::from(e.to_string()))
190+ .await
191+ .map_err(|e| e.to_string())?;
192+
193+ debug!("====== Checking the *after* DOM against the physical DOM ======");
194+ assert_rendered(&container, &after);
195+
196+ Ok(())
197197}
198198
199199/// A helper macro for declaring a bunch of `assert_before_after` tests.
@@ -210,14 +210,16 @@ macro_rules! before_after {
210210 }
211211 )* ) => {
212212 $(
213− #[wasm_bindgen_test(async)]
214− fn $name() -> impl Future<Item = (), Error = wasm_bindgen::JsValue> {
213+ #[wasm_bindgen_test]
214+ async fn $name() {
215215 use crate::{assert_before_after, RenderFn};
216216 log::debug!("############### {} ###############", stringify!($name));
217217 assert_before_after(
218218 RenderFn(|$before_bump| { $( $before )* }),
219219 RenderFn(|$after_bump| { $( $after )* })
220220 )
221+ .await
222+ .unwrap()
221223 }
222224 )*
223225 }
tests/web/render.rs+89−2
@@ -1,7 +1,7 @@
11use super::{assert_rendered, before_after, create_element, RenderFn};
2−use dodrio::{builder::*, Vdom};
3−use futures::prelude::*;
2+use dodrio::{builder::*, bumpalo::collections::String, Node, Render, RenderContext, Vdom};
43use std::rc::Rc;
4+use wasm_bindgen::{ JsCast};
55use wasm_bindgen_test::*;
66
77#[wasm_bindgen_test]
@@ -35,6 +35,93 @@ fn container_is_emptied_upon_drop() {
3535 assert!(container.first_child().is_none());
3636}
3737
38+/// Renders a child with a lifetime scoped to the RenderContext bump arena.
39+#[wasm_bindgen_test]
40+fn render_bump_scoped_node() {
41+ struct Child<'a> {
42+ name: &'a str,
43+ }
44+
45+ impl<'a> Render<'a> for Child<'a> {
46+ fn render(&self, _cx: &mut RenderContext<'a>) -> Node<'a> {
47+ text(self.name)
48+ }
49+ }
50+
51+ struct Parent;
52+
53+ impl<'a> Render<'a> for Parent {
54+ fn render(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
55+ let child_name = String::from_str_in("child", cx.bump).into_bump_str();
56+
57+ div(&cx)
58+ .children([Child { name: child_name }.render(cx)])
59+ .finish()
60+ }
61+ }
62+
63+ let parent = Rc::new(RenderFn(|cx| {
64+ Parent.render(cx)
65+ }));
66+
67+ let container = create_element("div");
68+ let _vdom = Vdom::new(&container, parent.clone());
69+
70+ assert_rendered(&container, &parent);
71+}
72+
73+/// Originally, dodrio would use the className property for SVGs.
74+///
75+/// This is problematic because when SVG elements are created, the className is flagged as a read
76+/// only property, so setting it causes an exception to be thrown. Here's an example of how this
77+/// happens:
78+///
79+/// let elem = web_sys::window()
80+/// .unwrap()
81+/// .document()
82+/// .unwrap()
83+/// .create_element_ns(Some("http://www.w3.org/2000/svg"), "svg")
84+/// .unwrap();
85+///
86+/// elem.set_class_name("does-not-work");
87+///
88+/// -----------------------------------------------------------------------------------------------
89+///
90+/// wasm-bindgen: imported JS function that was not marked as `catch` threw an error:
91+/// setting getter-only property "className"
92+///
93+/// -----------------------------------------------------------------------------------------------
94+///
95+/// Now, dodrio passes the 'class' attribute of all namespaced elements into set_attribute. This
96+/// satisfies the restrictions on SVG and keeps the optimized path for non-namespaced elements
97+#[wasm_bindgen_test(async)]
98+async fn test_svg_set_class() {
99+ let container = create_element("div");
100+
101+
102+ let valid_svg = Rc::new(RenderFn(|cx| {
103+ ElementBuilder::new(cx.bump, "svg")
104+ .namespace(Some("http://www.w3.org/2000/svg"))
105+ .attr("class", "works")
106+ .finish()
107+ }));
108+
109+ let vdom = Vdom::new(&container, valid_svg.clone());
110+ let weak = vdom.weak();
111+
112+ weak.render().await.unwrap();
113+
114+ assert_eq!(
115+ "works",
116+ container.first_child()
117+ .expect("unable to get svg")
118+ .dyn_ref::<web_sys::Element>()
119+ .expect("svg should be an element")
120+ .get_attribute("class")
121+ .expect("unable to get 'class' of svg")
122+ );
123+}
124+
38125before_after! {
39126 same_text {
40127 before(_cx) {