on master help sign in
Basic app
commit7d27db8d1b9df0c4a067b250961bcdb5e1cbed29 authoriko <mail@iko.soy> dateMon 4 Nov 2024, 17:20 (2 years ago) parentec4cb45
9 files changed+123−23
nock/src/main.rs+2−2 nock/wock.hoon+51 nock/wock.nock wock-web/Cargo.toml+1−1 wock-web/build.sh+1−1 wock-web/event-payloads.md+5 wock-web/index.html+1−2 wock-web/src/lib.rs+62−17 wock.nock
nock/src/main.rs+2−2
@@ -146,7 +146,7 @@ fn main() -> Result<(), std::io::Error> {
146146}
147147
148148/// Reads a `vase` from a `.nock` file.
149−fn read_nock(nock_file: &PathBuf) -> Result<Vase, std::io::Error> {
149+fn read_nock(nock_file: &PathBuf) -> Result<(Rc<Noun>, Rc<Noun>), std::io::Error> {
150150 let nock = cue_bytes(&read_file(nock_file)?);
151151 let (typ, nok) = nock.as_cell().unwrap();
152152 Ok((typ.clone(), nok.clone()))
@@ -223,7 +223,7 @@ fn read_nock_or_compile(
223223 ctx: &mut InterpreterContext,
224224 urbit: &LazyCell<Rc<Noun>>,
225225 path: &PathBuf,
226−) -> Result<Vase, std::io::Error> {
226+) -> Result<(Rc<Noun>, Rc<Noun>), std::io::Error> {
227227 if path.extension().and_then(|x| x.to_str()) == Some("hoon") {
228228 let nock = compile_to_nock(ctx, urbit, spinner, path.clone())?;
229229 let (typ, nok) = nock.as_cell().unwrap();
nock/wock.hoonnew file+51
@@ -0,0 +1,51 @@
1+=>
2+|%
3+++ wock-app
4+ |$ [model event]
5+ $_ ^?
6+ |%
7+ ++ init *model
8+ ++ view |~ model *manx
9+ ++ move |~ [model [event *]] *model
10+ --
11+++ app
12+ |* [model=mold event=mold]
13+ |= app=(wock-app model event)
14+ |= [cmd=@tas args=*]
15+ ?+ cmd !!
16+ %init
17+ init.app
18+ %view
19+ (view.app (model args))
20+ %move
21+ =/ [=model event-tape=tape payload=*] (,[model tape *] args)
22+ (move.app [model (event (crip event-tape)) payload])
23+ ==
24+--
25+=>
26+|%
27++$ event
28+ $?
29+ %inc
30+ %dec
31+ ==
32+--
33+%- (app @ud event)
34+|%
35+++ view
36+ |= count=@ud
37+ ^- manx
38+ ;div
39+ ;h1: {<count>}
40+ ;button(on-click "inc"): +
41+ ;button(on-click "dec"): -
42+ ==
43+++ init 8
44+++ move
45+ |= [model=@ud step=[event *]]
46+ ^- @ud
47+ ?- -.step
48+ %inc +(model)
49+ %dec ?: =(model 0) 0 (dec model)
50+ ==
51+--
nock/wock.nocknew file

Binary file not shown.

wock-web/Cargo.toml+1−1
@@ -37,7 +37,7 @@ wasm-bindgen-test = "0.3.34"
3737
3838[profile.release]
3939# Tell `rustc` to optimize for small code size.
40−opt-level = "s"
40+opt-level = 3
4141
4242[package.metadata.wasm-pack.profile.dev]
4343wasm-opt = ["-O", "--enable-bulk-memory"]
wock-web/build.sh+1−1
@@ -1,3 +1,3 @@
11#!/bin/sh
22
3−wasm-pack build --no-typescript --no-pack --target=web --dev
3+wasm-pack build --release --no-typescript --no-pack --target=web
wock-web/event-payloads.mdnew file+5
@@ -0,0 +1,5 @@
1+# Event payloads
2+
3+| Event attribute name | Hoon payload |
4+| --- | ----------- |
5+| `on-click` | `~` |
wock-web/index.html+1−2
@@ -3,8 +3,7 @@
33 <meta content="text/html;charset=utf-8" http-equiv="Content-Type"/>
44 </head>
55 <body>
6− <input id="input"></input>
76 <div id="output"></div>
8− <script type="module" src="script.mjs?src=/sail.nock"></script>
7+ <script type="module" src="script.mjs?src=/wock.nock"></script>
98 </body>
109</html>
wock-web/src/lib.rs+62−17
@@ -5,12 +5,12 @@ use std::rc::Rc;
55
66use dodrio::{
77 bumpalo::{self, Bump},
8− Attribute, Node, NodeKey, Render, RenderContext,
8+ Attribute, Listener, Node, NodeKey, Render, RenderContext, RootRender, VdomWeak,
99};
1010use nock::{
1111 cue::cue_bytes,
1212 interpreter::{generate_interpreter_context, slam},
13− noun::Noun,
13+ noun::{cell, Noun},
1414};
1515use wasm_bindgen::prelude::*;
1616use wasm_bindgen_futures::JsFuture;
@@ -26,19 +26,25 @@ extern "C" {
2626
2727struct WockApp {
2828 nock: Rc<Noun>,
29+ model: Rc<Noun>,
2930}
3031
3132impl<'a> Render<'a> for WockApp {
3233 fn render(&self, cx: &mut dodrio::RenderContext<'a>) -> dodrio::Node<'a> {
3334 let mut ctx = generate_interpreter_context();
3435
35− let sail = slam(&mut ctx, &self.nock, &Rc::new(Noun::from_u32(0))).unwrap();
36+ let sail = slam(
37+ &mut ctx,
38+ &self.nock,
39+ &cell(&Rc::new(Noun::from_bytes(b"view")), &self.model),
40+ )
41+ .unwrap();
3642
37− render_sail(cx, &sail)
43+ render_sail(cx, sail)
3844 }
3945}
4046
41−fn render_sail<'a>(ctx: &mut RenderContext<'a>, manx: &Rc<Noun>) -> Node<'a> {
47+fn render_sail<'a>(ctx: &mut RenderContext<'a>, manx: Rc<Noun>) -> Node<'a> {
4248 let (marx, marl) = manx.as_cell().unwrap();
4349 let (mane, mart) = marx.as_cell().unwrap();
4450
@@ -53,21 +59,51 @@ fn render_sail<'a>(ctx: &mut RenderContext<'a>, manx: &Rc<Noun>) -> Node<'a> {
5359 } else {
5460 let mut children = bumpalo::collections::Vec::new_in(&ctx.bump);
5561 marl.list_iter()
56− .map(|child| render_sail(ctx, child))
62+ .map(|child| render_sail(ctx, child.clone()))
5763 .collect_into(&mut children);
5864
5965 let mut attributes = bumpalo::collections::Vec::new_in(ctx.bump);
60− mart.list_iter()
61− .map(|attr| {
62− let (name, value) = attr.as_cell().unwrap();
63− Attribute {
66+ let mut listeners = bumpalo::collections::Vec::new_in(ctx.bump);
67+
68+ mart.list_iter().for_each(|attr| {
69+ let (name, value) = attr.as_cell().unwrap();
70+ match &*name.as_bytes().unwrap() {
71+ b"on-click" => listeners.push(Listener {
72+ event: "click",
73+ callback: {
74+ let value = value.clone();
75+ ctx.bump.alloc(
76+ move |root: &mut dyn RootRender,
77+ vdom: VdomWeak,
78+ _event: web_sys::Event| {
79+ let mut ctx = generate_interpreter_context();
80+ let sig = ctx.nouns.sig.clone();
81+
82+ let app = root.unwrap_mut::<WockApp>();
83+
84+ let new_model = slam(
85+ &mut ctx,
86+ &app.nock,
87+ &cell(
88+ &Rc::new(Noun::from_bytes(b"move")),
89+ &cell(&app.model, &cell(&value, &sig)),
90+ ),
91+ )
92+ .unwrap();
93+
94+ app.model = new_model;
95+
96+ vdom.schedule_render();
97+ },
98+ )
99+ },
100+ }),
101+ _ => attributes.push(Attribute {
64102 name: cord_to_bump_str(ctx.bump, name),
65− value: cord_to_bump_str(ctx.bump, value),
66− }
67− })
68− .collect_into(&mut attributes);
69−
70− let listeners = bumpalo::collections::Vec::new_in(ctx.bump);
103+ value: tape_to_bump_str(ctx.bump, value),
104+ }),
105+ };
106+ });
71107
72108 Node::element(
73109 &ctx.bump,
@@ -106,7 +142,16 @@ pub async fn main(path: &str) {
106142 let document = gloo::utils::document();
107143 let output_el: Element = document.get_element_by_id("output").unwrap();
108144
109− dodrio::Vdom::new(&output_el, WockApp { nock }).forget();
145+ let mut ctx = generate_interpreter_context();
146+
147+ let model = slam(
148+ &mut ctx,
149+ &nock,
150+ &cell(&Rc::new(Noun::from_bytes(b"init")), &Rc::new(Noun::SIG)),
151+ )
152+ .unwrap();
153+
154+ dodrio::Vdom::new(&output_el, WockApp { nock, model }).forget();
110155}
111156
112157pub async fn load_nock(path: &str) -> Rc<Noun> {
wock.nocknew file

Binary file not shown.