diff --git a/Cargo.toml b/Cargo.toml index afae137..e8cfff7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,10 @@ members = [ "crates/weft-runtime", "crates/weft-servo-shell", ] +exclude = [ + "examples/org.weft.demo.counter", + "examples/org.weft.demo.notes", +] resolver = "2" [workspace.package] diff --git a/crates/weft-servo-shell/SERVO_PIN.md b/crates/weft-servo-shell/SERVO_PIN.md index 0b527b3..c5511a2 100644 --- a/crates/weft-servo-shell/SERVO_PIN.md +++ b/crates/weft-servo-shell/SERVO_PIN.md @@ -10,12 +10,14 @@ | Crate | `servo` (package name as of 2026-03-11; previously `libservo`) | | Feature | `servo-embed` (optional; off by default) | -## Adding the Cargo dependencies +## Cargo dependencies -The Servo deps are **not** in `Cargo.toml` by default to avoid pulling the -Servo monorepo (~1 GB) into every `cargo check` cycle. To activate, add the -following to `crates/weft-servo-shell/Cargo.toml` and change the `servo-embed` -feature line to declare `dep:servo`, `dep:winit`, and `dep:softbuffer`: +The Servo deps are wired in `crates/weft-servo-shell/Cargo.toml` and +`crates/weft-app-shell/Cargo.toml` under the `servo-embed` optional feature. +They are off by default to avoid pulling the Servo monorepo (~1 GB) into every +`cargo check` cycle. + +Current `Cargo.toml` block (already committed): ```toml [features] @@ -37,7 +39,7 @@ version = "0.4" optional = true ``` -Then build: +To build: ```sh cargo build -p weft-servo-shell --features servo-embed @@ -75,17 +77,15 @@ DMA-BUF buffer sharing with the compositor transparently. - **GAP-1**: ~~Wayland input events not forwarded to Servo~~ **Resolved** — keyboard and mouse events forwarded via `webview.notify_input_event`; key mapping in `keyutils.rs`. -- **GAP-2**: EGL `WindowRenderingContext` path scaffolded (`WEFT_EGL_RENDERING=1`). - When EGL is active, Servo presents frames via surfman's `eglSwapBuffers`; Mesa handles - DMA-BUF buffer sharing with the compositor transparently — no explicit - `zwp_linux_dmabuf_v1` code is needed in the shell for basic rendering. - The `zweft_shell_manager_v1` event queue is now dispatched each frame so `configure`, - `focus_changed`, and `window_closed` events are processed; `window_closed` triggers a - clean Servo shutdown. - Remaining gap: the `ZweftShellWindowV1` is created with `surface = null`; the winit - `wl_surface` is not yet associated with the shell window slot (requires sharing a single - Wayland connection between winit and the shell client, which is not currently feasible - without significant refactoring). +- **GAP-2**: ~~`ZweftShellWindowV1` created with `surface = null`~~ **Resolved** — + `ShellClient::connect_with_display(display_ptr, surface_ptr)` uses + `Backend::from_foreign_display` to share winit's `wl_display` connection; the winit + `wl_surface` pointer is passed directly to `create_window`, associating the compositor + shell slot with the actual rendered surface. `ShellClient` is now constructed inside + `resumed()` after the winit window exists, not before the event loop. EGL path and + per-frame event dispatch are unchanged. + Protocol note: `wayland-scanner 0.31` generates `_type` (not `r#type`) for the + `navigation_gesture` event arg named `type`. - **GAP-3**: WebGPU adapter on Mesa may fail CTS — validation task, requires Mesa GPU hardware. - **GAP-4**: ~~CSS Grid~~ **Grid resolved** (Taffy-backed, fully wired). ~~CSS `backdrop-filter` unimplemented~~ **`backdrop-filter` resolved** (servo/servo issue diff --git a/examples/keys/weft-sign.key b/examples/keys/weft-sign.key new file mode 100644 index 0000000..2f8e510 --- /dev/null +++ b/examples/keys/weft-sign.key @@ -0,0 +1 @@ +6322e10dadbbe0f0d95fa113278392eac87768826167dd1cfcb3cc1cb7e43312 \ No newline at end of file diff --git a/examples/keys/weft-sign.pub b/examples/keys/weft-sign.pub new file mode 100644 index 0000000..46363ed --- /dev/null +++ b/examples/keys/weft-sign.pub @@ -0,0 +1 @@ +470490314923b5f51d96196a6dee67e831f0b758119b8558d83cf415088fe062 \ No newline at end of file diff --git a/examples/org.weft.demo.counter/.cargo/config.toml b/examples/org.weft.demo.counter/.cargo/config.toml new file mode 100644 index 0000000..f68f33c --- /dev/null +++ b/examples/org.weft.demo.counter/.cargo/config.toml @@ -0,0 +1,2 @@ +[build] +target = "wasm32-wasip2" diff --git a/examples/org.weft.demo.counter/Cargo.lock b/examples/org.weft.demo.counter/Cargo.lock new file mode 100644 index 0000000..3732df2 --- /dev/null +++ b/examples/org.weft.demo.counter/Cargo.lock @@ -0,0 +1,321 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "anyhow" +version = "1.0.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" + +[[package]] +name = "bitflags" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +dependencies = [ + "foldhash", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "id-arena" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" + +[[package]] +name = "indexmap" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" +dependencies = [ + "equivalent", + "hashbrown", + "serde", + "serde_core", +] + +[[package]] +name = "itoa" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" + +[[package]] +name = "leb128fmt" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" + +[[package]] +name = "log" +version = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" + +[[package]] +name = "memchr" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" + +[[package]] +name = "org-weft-demo-counter" +version = "0.1.0" +dependencies = [ + "serde_json", + "wit-bindgen", +] + +[[package]] +name = "prettyplease" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn", +] + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "semver" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.149" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "syn" +version = "2.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "wasm-encoder" +version = "0.245.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9dca005e69bf015e45577e415b9af8c67e8ee3c0e38b5b0add5aa92581ed5c" +dependencies = [ + "leb128fmt", + "wasmparser", +] + +[[package]] +name = "wasm-metadata" +version = "0.245.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da55e60097e8b37b475a0fa35c3420dd71d9eb7bd66109978ab55faf56a57efb" +dependencies = [ + "anyhow", + "indexmap", + "wasm-encoder", + "wasmparser", +] + +[[package]] +name = "wasmparser" +version = "0.245.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f08c9adee0428b7bddf3890fc27e015ac4b761cc608c822667102b8bfd6995e" +dependencies = [ + "bitflags", + "hashbrown", + "indexmap", + "semver", +] + +[[package]] +name = "wit-bindgen" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e915216dde3e818093168df8380a64fba25df468d626c80dd5d6a184c87e7c7" +dependencies = [ + "bitflags", + "wit-bindgen-rust-macro", +] + +[[package]] +name = "wit-bindgen-core" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3deda4b7e9f522d994906f6e6e0fc67965ea8660306940a776b76732be8f3933" +dependencies = [ + "anyhow", + "heck", + "wit-parser", +] + +[[package]] +name = "wit-bindgen-rust" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "863a7ab3c4dfee58db196811caeb0718b88412a0aef3d1c2b02fcbae1e37c688" +dependencies = [ + "anyhow", + "heck", + "indexmap", + "prettyplease", + "syn", + "wasm-metadata", + "wit-bindgen-core", + "wit-component", +] + +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d14f3a9bfa3804bb0e9ab7f66da047f210eded6a1297ae3ba5805b384d64797f" +dependencies = [ + "anyhow", + "prettyplease", + "proc-macro2", + "quote", + "syn", + "wit-bindgen-core", + "wit-bindgen-rust", +] + +[[package]] +name = "wit-component" +version = "0.245.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4894f10d2d5cbc17c77e91f86a1e48e191a788da4425293b55c98b44ba3fcac9" +dependencies = [ + "anyhow", + "bitflags", + "indexmap", + "log", + "serde", + "serde_derive", + "serde_json", + "wasm-encoder", + "wasm-metadata", + "wasmparser", + "wit-parser", +] + +[[package]] +name = "wit-parser" +version = "0.245.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330698718e82983499419494dd1e3d7811a457a9bf9f69734e8c5f07a2547929" +dependencies = [ + "anyhow", + "hashbrown", + "id-arena", + "indexmap", + "log", + "semver", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", + "wasmparser", +] + +[[package]] +name = "zmij" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" diff --git a/examples/org.weft.demo.counter/Cargo.toml b/examples/org.weft.demo.counter/Cargo.toml new file mode 100644 index 0000000..a111dc6 --- /dev/null +++ b/examples/org.weft.demo.counter/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "org-weft-demo-counter" +version = "0.1.0" +edition = "2024" + +[[bin]] +name = "app" +path = "src/main.rs" + +[dependencies] +wit-bindgen = "0.53" +serde_json = "1" + +[profile.release] +opt-level = "z" +strip = true +lto = true diff --git a/examples/org.weft.demo.counter/app.wasm b/examples/org.weft.demo.counter/app.wasm new file mode 100644 index 0000000..4bc6854 Binary files /dev/null and b/examples/org.weft.demo.counter/app.wasm differ diff --git a/examples/org.weft.demo.counter/signature.sig b/examples/org.weft.demo.counter/signature.sig new file mode 100644 index 0000000..daeb4c1 --- /dev/null +++ b/examples/org.weft.demo.counter/signature.sig @@ -0,0 +1 @@ +4d26abef46af41b1992c0592313ea6aeb39b21eb4a31b978c13ed7c46b444f4d3469819eec1e9d3a00ef40898b77cc3391edfac55fcc50e13817a9eaf126ec0a \ No newline at end of file diff --git a/examples/org.weft.demo.counter/src/main.rs b/examples/org.weft.demo.counter/src/main.rs new file mode 100644 index 0000000..57067be --- /dev/null +++ b/examples/org.weft.demo.counter/src/main.rs @@ -0,0 +1,42 @@ +wit_bindgen::generate!({ + path: "wit", + world: "app", + with: { + "weft:app/notify@0.1.0": generate, + "weft:app/ipc@0.1.0": generate, + }, +}); + +use weft::app::{ipc, notify}; + +fn main() { + notify::ready(); + + let mut count: i32 = 0; + + loop { + if let Some(raw) = ipc::recv() { + let reply = match raw.trim() { + "increment" => { + count += 1; + format!("{{\"count\":{count}}}") + } + "decrement" => { + count -= 1; + format!("{{\"count\":{count}}}") + } + "reset" => { + count = 0; + format!("{{\"count\":{count}}}") + } + "get" => { + format!("{{\"count\":{count}}}") + } + _ => continue, + }; + let _ = ipc::send(&reply); + } else { + std::thread::sleep(std::time::Duration::from_millis(10)); + } + } +} diff --git a/examples/org.weft.demo.counter/ui/index.html b/examples/org.weft.demo.counter/ui/index.html new file mode 100644 index 0000000..50e535d --- /dev/null +++ b/examples/org.weft.demo.counter/ui/index.html @@ -0,0 +1,144 @@ + + + + + +Counter + + + +
+

Counter

+
0
+
+ + + +
+
connecting…
+
+ + + + diff --git a/examples/org.weft.demo.counter/wapp.toml b/examples/org.weft.demo.counter/wapp.toml new file mode 100644 index 0000000..41440e0 --- /dev/null +++ b/examples/org.weft.demo.counter/wapp.toml @@ -0,0 +1,12 @@ +[package] +id = "org.weft.demo.counter" +name = "Counter" +version = "0.1.0" +description = "Stateless counter demonstrating weft:app/ipc" +author = "WEFT OS" + +[runtime] +module = "app.wasm" + +[ui] +entry = "ui/index.html" diff --git a/examples/org.weft.demo.counter/wit/deps/weft-app/weft-app.wit b/examples/org.weft.demo.counter/wit/deps/weft-app/weft-app.wit new file mode 100644 index 0000000..7d7e746 --- /dev/null +++ b/examples/org.weft.demo.counter/wit/deps/weft-app/weft-app.wit @@ -0,0 +1,38 @@ +package weft:app@0.1.0; + +interface notify { + ready: func(); +} + +interface ipc { + send: func(payload: string) -> result<_, string>; + recv: func() -> option; +} + +interface fetch { + record response { + status: u16, + content-type: string, + body: list, + } + + fetch: func( + url: string, + method: string, + headers: list>, + body: option>, + ) -> result; +} + +interface notifications { + notify: func( + title: string, + body: string, + icon: option, + ) -> result<_, string>; +} + +interface clipboard { + read: func() -> result; + write: func(text: string) -> result<_, string>; +} diff --git a/examples/org.weft.demo.counter/wit/world.wit b/examples/org.weft.demo.counter/wit/world.wit new file mode 100644 index 0000000..37c2d3c --- /dev/null +++ b/examples/org.weft.demo.counter/wit/world.wit @@ -0,0 +1,6 @@ +package org:weft-demo-counter@0.1.0; + +world app { + import weft:app/notify@0.1.0; + import weft:app/ipc@0.1.0; +} diff --git a/examples/org.weft.demo.notes/.cargo/config.toml b/examples/org.weft.demo.notes/.cargo/config.toml new file mode 100644 index 0000000..f68f33c --- /dev/null +++ b/examples/org.weft.demo.notes/.cargo/config.toml @@ -0,0 +1,2 @@ +[build] +target = "wasm32-wasip2" diff --git a/examples/org.weft.demo.notes/Cargo.lock b/examples/org.weft.demo.notes/Cargo.lock new file mode 100644 index 0000000..1300684 --- /dev/null +++ b/examples/org.weft.demo.notes/Cargo.lock @@ -0,0 +1,321 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "anyhow" +version = "1.0.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" + +[[package]] +name = "bitflags" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +dependencies = [ + "foldhash", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "id-arena" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" + +[[package]] +name = "indexmap" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" +dependencies = [ + "equivalent", + "hashbrown", + "serde", + "serde_core", +] + +[[package]] +name = "itoa" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" + +[[package]] +name = "leb128fmt" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" + +[[package]] +name = "log" +version = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" + +[[package]] +name = "memchr" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" + +[[package]] +name = "org-weft-demo-notes" +version = "0.1.0" +dependencies = [ + "serde_json", + "wit-bindgen", +] + +[[package]] +name = "prettyplease" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn", +] + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "semver" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.149" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "syn" +version = "2.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "wasm-encoder" +version = "0.245.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9dca005e69bf015e45577e415b9af8c67e8ee3c0e38b5b0add5aa92581ed5c" +dependencies = [ + "leb128fmt", + "wasmparser", +] + +[[package]] +name = "wasm-metadata" +version = "0.245.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da55e60097e8b37b475a0fa35c3420dd71d9eb7bd66109978ab55faf56a57efb" +dependencies = [ + "anyhow", + "indexmap", + "wasm-encoder", + "wasmparser", +] + +[[package]] +name = "wasmparser" +version = "0.245.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f08c9adee0428b7bddf3890fc27e015ac4b761cc608c822667102b8bfd6995e" +dependencies = [ + "bitflags", + "hashbrown", + "indexmap", + "semver", +] + +[[package]] +name = "wit-bindgen" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e915216dde3e818093168df8380a64fba25df468d626c80dd5d6a184c87e7c7" +dependencies = [ + "bitflags", + "wit-bindgen-rust-macro", +] + +[[package]] +name = "wit-bindgen-core" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3deda4b7e9f522d994906f6e6e0fc67965ea8660306940a776b76732be8f3933" +dependencies = [ + "anyhow", + "heck", + "wit-parser", +] + +[[package]] +name = "wit-bindgen-rust" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "863a7ab3c4dfee58db196811caeb0718b88412a0aef3d1c2b02fcbae1e37c688" +dependencies = [ + "anyhow", + "heck", + "indexmap", + "prettyplease", + "syn", + "wasm-metadata", + "wit-bindgen-core", + "wit-component", +] + +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d14f3a9bfa3804bb0e9ab7f66da047f210eded6a1297ae3ba5805b384d64797f" +dependencies = [ + "anyhow", + "prettyplease", + "proc-macro2", + "quote", + "syn", + "wit-bindgen-core", + "wit-bindgen-rust", +] + +[[package]] +name = "wit-component" +version = "0.245.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4894f10d2d5cbc17c77e91f86a1e48e191a788da4425293b55c98b44ba3fcac9" +dependencies = [ + "anyhow", + "bitflags", + "indexmap", + "log", + "serde", + "serde_derive", + "serde_json", + "wasm-encoder", + "wasm-metadata", + "wasmparser", + "wit-parser", +] + +[[package]] +name = "wit-parser" +version = "0.245.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330698718e82983499419494dd1e3d7811a457a9bf9f69734e8c5f07a2547929" +dependencies = [ + "anyhow", + "hashbrown", + "id-arena", + "indexmap", + "log", + "semver", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", + "wasmparser", +] + +[[package]] +name = "zmij" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" diff --git a/examples/org.weft.demo.notes/Cargo.toml b/examples/org.weft.demo.notes/Cargo.toml new file mode 100644 index 0000000..8f9731a --- /dev/null +++ b/examples/org.weft.demo.notes/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "org-weft-demo-notes" +version = "0.1.0" +edition = "2024" + +[[bin]] +name = "app" +path = "src/main.rs" + +[dependencies] +wit-bindgen = "0.53" +serde_json = "1" + +[profile.release] +opt-level = "z" +strip = true +lto = true diff --git a/examples/org.weft.demo.notes/app.wasm b/examples/org.weft.demo.notes/app.wasm new file mode 100644 index 0000000..bd523ab Binary files /dev/null and b/examples/org.weft.demo.notes/app.wasm differ diff --git a/examples/org.weft.demo.notes/signature.sig b/examples/org.weft.demo.notes/signature.sig new file mode 100644 index 0000000..feb4212 --- /dev/null +++ b/examples/org.weft.demo.notes/signature.sig @@ -0,0 +1 @@ +e781544104eee4538e17f953ea3223903e2b2a46a78705cd1ffa8d6946a62d0385c76eab2cc1c2533eecbeff7600e76a4205abc66915be8851fe2e71316ebc0d \ No newline at end of file diff --git a/examples/org.weft.demo.notes/src/main.rs b/examples/org.weft.demo.notes/src/main.rs new file mode 100644 index 0000000..485544e --- /dev/null +++ b/examples/org.weft.demo.notes/src/main.rs @@ -0,0 +1,59 @@ +wit_bindgen::generate!({ + path: "wit", + world: "app", + with: { + "weft:app/notify@0.1.0": generate, + "weft:app/ipc@0.1.0": generate, + }, +}); + +use weft::app::{ipc, notify}; + +const NOTES_PATH: &str = "/data/notes.txt"; + +fn load_notes() -> String { + std::fs::read_to_string(NOTES_PATH).unwrap_or_default() +} + +fn save_notes(text: &str) -> Result<(), String> { + std::fs::write(NOTES_PATH, text).map_err(|e| e.to_string()) +} + +fn json_text(text: &str) -> String { + let escaped = text + .replace('\\', "\\\\") + .replace('"', "\\\"") + .replace('\n', "\\n") + .replace('\r', "\\r") + .replace('\t', "\\t"); + format!("{{\"text\":\"{escaped}\"}}") +} + +fn json_error(msg: &str) -> String { + let escaped = msg.replace('"', "\\\""); + format!("{{\"error\":\"{escaped}\"}}") +} + +fn main() { + notify::ready(); + + loop { + if let Some(raw) = ipc::recv() { + let raw = raw.trim().to_owned(); + let reply = if raw == "load" { + json_text(&load_notes()) + } else if let Some(rest) = raw.strip_prefix("save:") { + let text = rest.replace("\\n", "\n"); + match save_notes(&text) { + Ok(()) => json_text(&text), + Err(e) => json_error(&e), + } + } else { + continue; + }; + let _ = ipc::send(&reply); + } else { + std::thread::sleep(std::time::Duration::from_millis(10)); + } + } +} diff --git a/examples/org.weft.demo.notes/ui/index.html b/examples/org.weft.demo.notes/ui/index.html new file mode 100644 index 0000000..e0592e5 --- /dev/null +++ b/examples/org.weft.demo.notes/ui/index.html @@ -0,0 +1,164 @@ + + + + + +Notes + + + +
+

Notes

+
+ + +
+
+ +
+ connecting… + 0 chars +
+ + + + diff --git a/examples/org.weft.demo.notes/wapp.toml b/examples/org.weft.demo.notes/wapp.toml new file mode 100644 index 0000000..a052d45 --- /dev/null +++ b/examples/org.weft.demo.notes/wapp.toml @@ -0,0 +1,13 @@ +[package] +id = "org.weft.demo.notes" +name = "Notes" +version = "0.1.0" +description = "Persistent notes demonstrating fs:rw:app-data via weft:app/ipc" +author = "WEFT OS" +capabilities = ["fs:rw:app-data"] + +[runtime] +module = "app.wasm" + +[ui] +entry = "ui/index.html" diff --git a/examples/org.weft.demo.notes/wit/deps/weft-app/weft-app.wit b/examples/org.weft.demo.notes/wit/deps/weft-app/weft-app.wit new file mode 100644 index 0000000..7d7e746 --- /dev/null +++ b/examples/org.weft.demo.notes/wit/deps/weft-app/weft-app.wit @@ -0,0 +1,38 @@ +package weft:app@0.1.0; + +interface notify { + ready: func(); +} + +interface ipc { + send: func(payload: string) -> result<_, string>; + recv: func() -> option; +} + +interface fetch { + record response { + status: u16, + content-type: string, + body: list, + } + + fetch: func( + url: string, + method: string, + headers: list>, + body: option>, + ) -> result; +} + +interface notifications { + notify: func( + title: string, + body: string, + icon: option, + ) -> result<_, string>; +} + +interface clipboard { + read: func() -> result; + write: func(text: string) -> result<_, string>; +} diff --git a/examples/org.weft.demo.notes/wit/world.wit b/examples/org.weft.demo.notes/wit/world.wit new file mode 100644 index 0000000..0f10f78 --- /dev/null +++ b/examples/org.weft.demo.notes/wit/world.wit @@ -0,0 +1,6 @@ +package org:weft-demo-notes@0.1.0; + +world app { + import weft:app/notify@0.1.0; + import weft:app/ipc@0.1.0; +}