@@ -1,12 +1,8 @@
11#![feature(iter_collect_into)]
22mod utils;
33
4−use std::{
5− borrow::BorrowMut,
6− cell::RefCell,
7− ops::{Deref, DerefMut},
8− rc::Rc,
9−};
4+use core::panic;
5+use std::{cell::RefCell, rc::Rc};
106
117use dodrio::{
128 bumpalo::{self, Bump},
@@ -16,10 +12,11 @@ use nock::{
1612 cue::cue_bytes,
1713 interpreter::{generate_interpreter_context, slam, InterpreterContext},
1814 noun::{cell, Noun},
15+ wash,
1916};
2017use wasm_bindgen::prelude::*;
21−use wasm_bindgen_futures::JsFuture;
22−use web_sys::Element;
18+use wasm_bindgen_futures::{spawn_local, JsFuture};
19+use web_sys::{console::error_1, Element};
2320
2421#[wasm_bindgen]
2522extern "C" {
@@ -32,22 +29,51 @@ extern "C" {
3229 fn error(s: &str);
3330}
3431
32+#[derive(Clone)]
3533struct WockApp {
3634 nock: Rc<Noun>,
3735 ctx: RefCell<InterpreterContext>,
3836 model: Rc<Noun>,
37+ urbit: RefCell<Option<Rc<Noun>>>,
38+}
39+
40+impl WockApp {
41+ async fn get_urbit(self: &Self) -> Rc<Noun> {
42+ match self.urbit.borrow().clone() {
43+ Some(urbit) => urbit,
44+ None => {
45+ let urbit = load_nock("/urbit.nock").await.unwrap_or_else(|err| {
46+ error_1(&err);
47+ panic!("Could not load urbit.")
48+ });
49+
50+ self.urbit.replace(Some(urbit.clone()));
51+
52+ urbit
53+ }
54+ }
55+ }
3956}
4057
4158impl<'a> Render<'a> for WockApp {
4259 fn render(&self, cx: &mut dodrio::RenderContext<'a>) -> dodrio::Node<'a> {
43− let sail = slam(
60+ match slam(
4461 &mut *self.ctx.borrow_mut(),
4562 &self.nock,
4663 &cell(&Rc::new(Noun::from_bytes(b"view")), &self.model),
47− )
48− .unwrap();
49−
50− render_sail(cx, sail)
64+ ) {
65+ Ok(sail) => render_sail(cx, sail),
66+ Err(tanks) => {
67+ let wock_app = self.clone();
68+ let mut ctx = (*self.ctx.borrow()).clone();
69+ spawn_local(async move {
70+ let urbit = wock_app.get_urbit().await;
71+ let str = wash(&mut ctx, &urbit, tanks);
72+ error_1(&JsValue::from_str(&str));
73+ });
74+ panic!("Could not render");
75+ }
76+ }
5177 }
5278}
5379
@@ -151,7 +177,10 @@ fn tape_to_bump_str<'a>(bump: &'a Bump, non: &Rc<Noun>) -> &'a str {
151177
152178#[wasm_bindgen]
153179pub async fn main(path: &str) {
154− let nock = load_nock(path).await;
180+ let nock = load_nock(path).await.unwrap_or_else(|err| {
181+ error_1(&err);
182+ panic!("Could not load nock.")
183+ });
155184
156185 let document = gloo::utils::document();
157186 let output_el: Element = document.get_element_by_id("output").unwrap();
@@ -162,8 +191,20 @@ pub async fn main(path: &str) {
162191 &mut ctx,
163192 &nock,
164193 &cell(&Rc::new(Noun::from_bytes(b"init")), &Rc::new(Noun::SIG)),
165− )
166− .unwrap();
194+ );
195+ let model = match model {
196+ Ok(model) => model,
197+ Err(tanks) => {
198+ let urbit = load_nock("/urbit.nock").await.unwrap_or_else(|err| {
199+ error_1(&err);
200+ panic!("Could not load urbit.")
201+ });
202+
203+ let str = wash(&mut ctx, &urbit, tanks);
204+ error_1(&JsValue::from_str(&str));
205+ panic!("Could not load initial model.");
206+ }
207+ };
167208
168209 dodrio::Vdom::new(
169210 &output_el,
@@ -171,26 +212,26 @@ pub async fn main(path: &str) {
171212 nock,
172213 model,
173214 ctx: RefCell::new(ctx),
215+ urbit: RefCell::new(None),
174216 },
175217 )
176218 .forget();
177219}
178220
179−pub async fn load_nock(path: &str) -> Rc<Noun> {
221+pub async fn load_nock(path: &str) -> Result<Rc<Noun>, JsValue> {
180222 let window = web_sys::window().unwrap();
181223
182− let resp = JsFuture::from(window.fetch_with_str(path)).await.unwrap();
224+ let resp = JsFuture::from(window.fetch_with_str(path)).await?;
183225 assert!(resp.is_instance_of::<web_sys::Response>());
184− let resp: web_sys::Response = resp.dyn_into().unwrap();
185− let blob = JsFuture::from(resp.blob().unwrap()).await.unwrap();
226+ let resp: web_sys::Response = resp.dyn_into()?;
227+ let blob = JsFuture::from(resp.blob()?).await?;
186228 assert!(blob.is_instance_of::<web_sys::Blob>());
187− let blob: web_sys::Blob = blob.dyn_into().unwrap();
229+ let blob: web_sys::Blob = blob.dyn_into()?;
188230
189− let nock =
190− js_sys::Uint8Array::new(&JsFuture::from(blob.array_buffer()).await.unwrap()).to_vec();
231+ let nock = js_sys::Uint8Array::new(&JsFuture::from(blob.array_buffer()).await?).to_vec();
191232
192233 let nock = cue_bytes(&*nock);
193234 let (_typ, nok) = nock.as_cell().unwrap();
194235
195− nok.clone()
236+ Ok(nok.clone())
196237}