From 299f00c94feb98ae4289a2832adc6c43d8bfb03a Mon Sep 17 00:00:00 2001 From: Sebastian Moser Date: Sat, 14 Mar 2026 17:58:53 +0100 Subject: [PATCH] dioxus hello world component in obsidian + some other stuff --- Cargo.lock | 2 + md | 2 +- packages/marts/Cargo.toml | 2 +- packages/mize/Cargo.toml | 2 +- packages/mize/deno.json | 2 +- packages/mize/main.ts | 8 - packages/mize/main_test.ts | 6 - packages/mize/src/lib.rs | 20 +- packages/mize/src/platform/js/deno.json | 8 + .../mize/src/platform/{wasm => js}/init.js | 0 .../mize/src/platform/{wasm => js}/mod.rs | 161 ++-- .../mize/src/platform/{wasm => js}/utils.rs | 0 packages/ppc/Cargo.toml | 9 +- packages/ppc/auth/client.rs | 63 +- packages/ppc/platform/obsidian/deno.json | 2 +- packages/ppc/platform/obsidian/mod.rs | 23 +- packages/ppc/platform/obsidian/plugin.ts | 45 +- .../bindings/add_reducer.rs | 104 +++ .../bindings/identity_connected_reducer.rs | 101 ++ .../bindings/identity_disconnected_reducer.rs | 103 ++ packages/spacetime-module-ppc/bindings/mod.rs | 876 ++++++++++++++++++ .../bindings/person_table.rs | 95 ++ .../bindings/person_type.rs | 15 + .../bindings/say_hello_reducer.rs | 100 ++ packages/spacetime-module-ppc/src/lib.rs | 4 +- 25 files changed, 1617 insertions(+), 136 deletions(-) delete mode 100644 packages/mize/main.ts delete mode 100644 packages/mize/main_test.ts create mode 100644 packages/mize/src/platform/js/deno.json rename packages/mize/src/platform/{wasm => js}/init.js (100%) rename packages/mize/src/platform/{wasm => js}/mod.rs (71%) rename packages/mize/src/platform/{wasm => js}/utils.rs (100%) create mode 100644 packages/spacetime-module-ppc/bindings/add_reducer.rs create mode 100644 packages/spacetime-module-ppc/bindings/identity_connected_reducer.rs create mode 100644 packages/spacetime-module-ppc/bindings/identity_disconnected_reducer.rs create mode 100644 packages/spacetime-module-ppc/bindings/mod.rs create mode 100644 packages/spacetime-module-ppc/bindings/person_table.rs create mode 100644 packages/spacetime-module-ppc/bindings/person_type.rs create mode 100644 packages/spacetime-module-ppc/bindings/say_hello_reducer.rs diff --git a/Cargo.lock b/Cargo.lock index ee9de95..23f1ed6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5988,6 +5988,7 @@ dependencies = [ "clap", "dioxus", "dioxus-ssr 0.5.6", + "dioxus-web", "html-escape", "js-sys", "marts", @@ -6005,6 +6006,7 @@ dependencies = [ "tracing", "url", "wasm-bindgen", + "web-sys", "webbrowser", ] diff --git a/md b/md index 23a4bcc..7f005d5 100755 --- a/md +++ b/md @@ -10,7 +10,7 @@ function main { fi if [[ "$1" == "dma" ]]; then - deploy_lush + deploy_main_website fi if [[ "$1" == "dmo" ]]; then diff --git a/packages/marts/Cargo.toml b/packages/marts/Cargo.toml index 5e9768e..450bc65 100644 --- a/packages/marts/Cargo.toml +++ b/packages/marts/Cargo.toml @@ -23,7 +23,7 @@ dioxus = { version = "0.7.1", features = ["router", "fullstack", "web", "desktop [features] default = ["target-os"] target-os = [ "clap", "mize/target-os", "rustyscript", "rusqlite", "dioxus" ] -target-wasm = [ "mize/target-wasm" ] +target-js = [ "mize/target-js" ] clap = ["dep:clap"] [lib] diff --git a/packages/mize/Cargo.toml b/packages/mize/Cargo.toml index d3c1415..0221ac7 100644 --- a/packages/mize/Cargo.toml +++ b/packages/mize/Cargo.toml @@ -22,7 +22,7 @@ required-features = [ "target-os" ] [features] default = [ "target-os" ] target-os= [ "clap", "home", "nix", "sysinfo", "ciborium/default", "tracing-subscriber", "async", "tracing-subscriber/env-filter", "libloading", "ciborium-io", "tracing-core", "tar", "flate2", "http_req" ] -target-wasm = [ "wasm-bindgen", "console_error_panic_hook", "web-sys", "web-sys/Worker", "web-sys/Window", "web-sys/Request", "web-sys/RequestInit", "web-sys/RequestMode", "web-sys/Response", "web-sys/WorkerOptions", "web-sys/WorkerType", "serde-wasm-bindgen", "wasm-bindgen-futures", "wee_alloc"] +target-js = [ "wasm-bindgen", "console_error_panic_hook", "web-sys", "web-sys/Worker", "web-sys/Window", "web-sys/Request", "web-sys/RequestInit", "web-sys/RequestMode", "web-sys/Response", "web-sys/WorkerOptions", "web-sys/WorkerType", "serde-wasm-bindgen", "wasm-bindgen-futures", "wee_alloc"] async = ["tokio/net", "tokio", "tokio/rt-multi-thread", "tokio/io-util"] diff --git a/packages/mize/deno.json b/packages/mize/deno.json index 26cf443..7cd3883 100644 --- a/packages/mize/deno.json +++ b/packages/mize/deno.json @@ -1,5 +1,5 @@ { "name": "@ppc/mize", "imports": {}, - "exports": {} + "exports": "./src/platform/js/index.ts" } diff --git a/packages/mize/main.ts b/packages/mize/main.ts deleted file mode 100644 index 292ce5f..0000000 --- a/packages/mize/main.ts +++ /dev/null @@ -1,8 +0,0 @@ -export function add(a: number, b: number): number { - return a + b; -} - -// Learn more at https://docs.deno.com/runtime/manual/examples/module_metadata#concepts -if (import.meta.main) { - console.log("Add 2 + 3 =", add(2, 3)); -} diff --git a/packages/mize/main_test.ts b/packages/mize/main_test.ts deleted file mode 100644 index 3d981e9..0000000 --- a/packages/mize/main_test.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { assertEquals } from "@std/assert"; -import { add } from "./main.ts"; - -Deno.test(function addTest() { - assertEquals(add(2, 3), 5); -}); diff --git a/packages/mize/src/lib.rs b/packages/mize/src/lib.rs index 85b41cc..f26c1c6 100644 --- a/packages/mize/src/lib.rs +++ b/packages/mize/src/lib.rs @@ -57,41 +57,41 @@ use std::path::PathBuf; // platform specific stuff pub mod platform { - #[cfg(feature = "wasm-target")] - pub mod wasm; + #[cfg(feature = "target-js")] + pub mod js; #[cfg(feature = "target-os")] pub mod os; pub mod any { //////////// instance_init - #[cfg(feature = "wasm-target")] - pub use super::wasm::wasm_instance_init as instance_init; + #[cfg(feature = "target-js")] + pub use super::js::wasm_instance_init as instance_init; #[cfg(feature = "target-os")] pub use super::os::os_instance_init as instance_init; - #[cfg(not(any(feature = "target-os", feature = "target-wasm ")))] + #[cfg(not(any(feature = "target-os", feature = "target-js")))] pub use super::super::instance_init; //////////// load_module #[cfg(feature = "target-os")] pub use super::os::load_module; - #[cfg(feature = "wasm-target")] - pub use super::wasm::load_module; + #[cfg(feature = "target-js")] + pub use super::js::load_module; - #[cfg(not(any(feature = "target-os", feature = "target-wasm ")))] + #[cfg(not(any(feature = "target-os", feature = "target-js")))] pub use super::super::load_module; //////////// fetch_module #[cfg(feature = "target-os")] pub use super::os::fetch_module; - #[cfg(feature = "wasm-target")] + #[cfg(feature = "target-js")] pub use super::super::fetch_module; - #[cfg(not(any(feature = "target-os", feature = "target-wasm ")))] + #[cfg(not(any(feature = "target-os", feature = "target-js")))] pub use super::super::fetch_module; } } diff --git a/packages/mize/src/platform/js/deno.json b/packages/mize/src/platform/js/deno.json new file mode 100644 index 0000000..5b320c2 --- /dev/null +++ b/packages/mize/src/platform/js/deno.json @@ -0,0 +1,8 @@ +{ + "tasks": { + "dev": "deno run --watch main.ts" + }, + "imports": { + "@std/assert": "jsr:@std/assert@1" + } +} diff --git a/packages/mize/src/platform/wasm/init.js b/packages/mize/src/platform/js/init.js similarity index 100% rename from packages/mize/src/platform/wasm/init.js rename to packages/mize/src/platform/js/init.js diff --git a/packages/mize/src/platform/wasm/mod.rs b/packages/mize/src/platform/js/mod.rs similarity index 71% rename from packages/mize/src/platform/wasm/mod.rs rename to packages/mize/src/platform/js/mod.rs index 1714ba8..295c3dc 100644 --- a/packages/mize/src/platform/wasm/mod.rs +++ b/packages/mize/src/platform/js/mod.rs @@ -1,79 +1,72 @@ -use core::convert::From; -use core::option::Option; -use std::ptr::NonNull; -use std::panic; -use web_sys::js_sys::{self, eval, Promise}; use crate::id::MizeId; use crate::item::{Item, ItemData}; -use crate::platform::wasm::js_sys::Function; -use web_sys::{WorkerOptions, WorkerType}; +use crate::platform::js::js_sys::Function; +use core::convert::From; +use core::option::Option; +use std::panic; +use std::ptr::NonNull; +use web_sys::js_sys::{self, eval, Promise}; use web_sys::Worker; +use web_sys::{WorkerOptions, WorkerType}; -use crate::instance::{self, Instance}; -use crate::error::MizeResult; -use crate::{mize_err, Module}; -use crate::MizeError; use crate::core::item::IntoItemData; +use crate::error::MizeResult; use crate::instance::module::EmptyModule; - - - +use crate::Mize; +use crate::MizeError; +use crate::{mize_err, Module}; // console_log macro // that can be copied into other files for debugging purposes -#[cfg(feature = "wasm-target")] +#[cfg(feature = "target-js")] use wasm_bindgen::prelude::*; -#[cfg(feature = "wasm-target")] +#[cfg(feature = "target-js")] #[wasm_bindgen] extern "C" { #[wasm_bindgen(js_namespace = console)] fn log(s: &str); } -#[cfg(feature = "wasm-target")] +#[cfg(feature = "target-js")] macro_rules! console_log { // Note that this is using the `log` function imported above during // `bare_bones` ($($t:tt)*) => (unsafe { log(&format_args!($($t)*).to_string())}) } -#[cfg(not(feature = "wasm-target"))] +#[cfg(not(feature = "target-js"))] macro_rules! console_log { // Note that this is using the `log` function imported above during // `bare_bones` - ($($t:tt)*) => () + ($($t:tt)*) => {}; } //end of console_log macro - - #[global_allocator] static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT; - -pub fn wasm_instance_init(instance: &mut Instance) -> MizeResult<()> { +pub fn wasm_instance_init(mize: &mut Mize) -> MizeResult<()> { console_log!("Hello world from wasm_instance_init!!!!!!!!!!"); Ok(()) } -pub fn load_module(instance: &mut Instance, name: &str, path: Option) -> MizeResult<()> { +pub fn load_module(mize: &mut Mize, name: &str, path: Option) -> MizeResult<()> { console_log!("loading module: {}", name); - wasm_bindgen_futures::spawn_local(load_module_async(instance.clone(), name.to_owned(), path)); + wasm_bindgen_futures::spawn_local(load_module_async(mize.clone(), name.to_owned(), path)); Ok(()) } -async fn load_module_async(mut instance: Instance, name: String, path: Option) -> () { - +async fn load_module_async(mut mize: Mize, name: String, path: Option) -> () { let name = name.as_str(); - let module_url = fetch_module(&mut instance, name).unwrap(); + let module_url = fetch_module(&mut mize, name).unwrap(); let memory = wasm_bindgen::memory(); let mut empty_module: Box = Box::new(EmptyModule {}); - let mut mize = instance.clone(); + let mut mize = mize.clone(); let empty_module_ptr = Box::into_raw(Box::new(empty_module)); let empty_module_usize = empty_module_ptr as usize; @@ -81,7 +74,8 @@ async fn load_module_async(mut instance: Instance, name: String, path: Option {{ import("{module_url}/mize_module_{name}.js").then( module => {{ const wasm_bindgen = module.get_wasm_bindgen(); @@ -97,18 +91,23 @@ async fn load_module_async(mut instance: Instance, name: String, path: Option val, Err(err) => { console_log!("failed to load the wasm mize module...."); console_log!("{:?}", err); return; - }, + } }; console_log!("got ret_value: {:?}", ret_value); @@ -119,20 +118,17 @@ async fn load_module_async(mut instance: Instance, name: String, path: Option MizeResult { - +pub fn fetch_module(mize: &mut Mize, name: &str) -> MizeResult { let module_name_with_slashes = name.replace(".", "/"); - if let Ok(module_path) = instance.get(format!("self/config/module_dir/{}", module_name_with_slashes))?.value_string() { + if let Ok(module_path) = mize + .get(format!( + "self/config/module_dir/{}", + module_name_with_slashes + ))? + .value_string() + { return Ok(module_path); - } else { - let module_url = instance.get("self/config/module_url")?.value_string()?; + let module_url = mize.get("self/config/module_url")?.value_string()?; return Ok(format!("{}/{}", module_url, module_name_with_slashes)); } } -async fn download_module(instance: &mut Instance, name: &str) -> MizeResult { +async fn download_module(mize: &mut Mize, name: &str) -> MizeResult { use wasm_bindgen_futures::JsFuture; use web_sys::{Request, RequestInit, RequestMode, Response}; @@ -173,51 +170,57 @@ async fn download_module(instance: &mut Instance, name: &str) -> MizeResult, +pub struct JsMize { + inner: NonNull, } - #[wasm_bindgen] -pub struct JsItemHandle { - instance: NonNull, +pub struct JsItem { + mize: NonNull, id: MizeId, } #[wasm_bindgen] -pub async fn new_js_instance(config_json_str: String) -> JsInstance { - +pub async fn new_js_instance(config_json_str: String) -> JsMize { panic::set_hook(Box::new(console_error_panic_hook::hook)); let config = ItemData::from_json(config_json_str).expect("parsing of json config failed"); - let mut instance = Instance::empty().expect("Instance::empty() failed"); + let mut mize = Mize::empty().expect("Mize::empty() failed"); - instance.set_blocking("0/config", config).expect("Failed to set the config at item 0"); + mize.set_blocking("0/config", config) + .expect("Failed to set the config at item 0"); - let mut js_instance = JsInstance { inner: NonNull::from(Box::leak(Box::new(instance))) }; + let mut js_instance = JsMize { + inner: NonNull::from(Box::leak(Box::new(mize))), + }; return js_instance; } #[wasm_bindgen] -impl JsInstance { - +impl JsMize { #[wasm_bindgen] pub unsafe fn init(&mut self) -> MizeResult<()> { self.inner.as_mut().init() @@ -231,43 +234,39 @@ impl JsInstance { } #[wasm_bindgen] - pub unsafe fn get_handle(&mut self, id: String) -> MizeResult { + pub unsafe fn get_handle(&mut self, id: String) -> MizeResult { let item = self.inner.as_mut().get(id)?; - Ok(JsItemHandle { instance: self.inner, id: item.id()}) - } - -} - -impl JsInstance { - pub fn inner(&mut self) -> &mut Instance { - unsafe { - self.inner.as_mut() - } + Ok(JsItem { + mize: self.inner, + id: item.id(), + }) } } +impl JsMize { + pub fn inner(&mut self) -> &mut Mize { + unsafe { self.inner.as_mut() } + } +} #[wasm_bindgen] -impl JsItemHandle { - +impl JsItem { #[wasm_bindgen] pub unsafe fn value_string(&mut self) -> MizeResult { - let item = self.instance.as_mut().get(self.id.clone())?; + let item = self.mize.as_mut().get(self.id.clone())?; let string = item.value_string()?; Ok(string) } #[wasm_bindgen] pub unsafe fn as_data_full(&mut self) -> MizeResult { - let item = self.instance.as_mut().get(self.id.clone())?; + let item = self.mize.as_mut().get(self.id.clone())?; let data_raw = item.as_data_full()?; let jsvalue = serde_wasm_bindgen::to_value(data_raw.cbor())?; Ok(jsvalue) } - } - impl From for JsValue { fn from(value: MizeError) -> Self { let string = format!("{:?}", value); diff --git a/packages/mize/src/platform/wasm/utils.rs b/packages/mize/src/platform/js/utils.rs similarity index 100% rename from packages/mize/src/platform/wasm/utils.rs rename to packages/mize/src/platform/js/utils.rs diff --git a/packages/ppc/Cargo.toml b/packages/ppc/Cargo.toml index 475a0eb..480fa88 100644 --- a/packages/ppc/Cargo.toml +++ b/packages/ppc/Cargo.toml @@ -21,7 +21,7 @@ rand = { version = "0.8", optional = true } url = { version = "2", optional = true } time = { version = "0.3", optional = true } tokio = { version = "1.0", features = ["full"], optional = true } -dioxus = { version = "0.7.1", features = ["router", "fullstack", "web", "desktop", "mobile", "server", "ssr"], optional = true } +dioxus = { version = "0.7.1", optional = true } dioxus-ssr = { version = "0.5", optional = true } html-escape = { version = "0.2.13", optional = true } axum-oidc = { version = "1.0.0-dev-1", optional = true } @@ -31,6 +31,8 @@ tower-sessions = { version = "0.14.0", optional = true } tower-http = { version = "0.6.8", features = ["trace"] } webbrowser = { version = "1.2.0", optional = true } base64 = { version = "0.22.1", optional = true } +dioxus-web = { version = "0.7.3", optional = true } +web-sys = { version = "0.3.91", optional = true } [[bin]] name = "ppc" @@ -44,8 +46,9 @@ name = "ppc" [features] default = ["target-os"] target-os = [ "clap", "mize/target-os", "marts/target-os", "server", "tracing", "webbrowser", "base64" ] -target-obsidian = [ "js-sys", "wasm-bindgen", "mize/target-wasm", "marts/target-wasm" ] -server = [ "axum", "axum-extra", "openidconnect", "serde", "serde_json", "reqwest", "rand", "url", "time", "tokio", "dioxus", "dioxus-ssr", "html-escape", "axum-oidc", "tower", "tower-sessions" ] +target-obsidian = [ "js-sys", "wasm-bindgen", "mize/target-js", "marts/target-js", "base64", "serde_json", "serde", "openidconnect", "dioxus", "dioxus-web", "web-sys", "web-sys/Document", "dioxus/web" ] +server = [ "axum", "axum-extra", "openidconnect", "serde", "serde_json", "reqwest", "rand", "url", "time", "tokio", "dioxus/ssr", "dioxus/server", "dioxus/fullstack", "dioxus/desktop", "dioxus/router", "dioxus-ssr", "html-escape", "axum-oidc", "tower", "tower-sessions" ] +web-sys = ["dep:web-sys"] [package.metadata.wasm-pack.profile.release] diff --git a/packages/ppc/auth/client.rs b/packages/ppc/auth/client.rs index 1513f6c..55a9b68 100644 --- a/packages/ppc/auth/client.rs +++ b/packages/ppc/auth/client.rs @@ -3,7 +3,6 @@ use base64::{ alphabet::STANDARD, engine::{DecodePaddingMode, GeneralPurpose, GeneralPurposeConfig}, }; -use clap::Command; use mize::{Mize, MizeError, MizePart, MizeResult, mize_err, mize_part}; use openidconnect::{ AuthorizationCode, ClientId, CsrfToken, IssuerUrl, Nonce, OAuth2TokenResponse, @@ -16,6 +15,28 @@ use std::{ path::PathBuf, }; +// console_log macro +// that can be copied into other files for debugging purposes +#[cfg(feature = "target-obsidian")] +use wasm_bindgen::prelude::*; + +#[cfg(feature = "target-obsidian")] +#[wasm_bindgen] +extern "C" { + #[wasm_bindgen(js_namespace = console)] + fn log(s: &str); +} + +#[cfg(feature = "target-obsidian")] +macro_rules! console_log { + // Note that this is using the `log` function imported above during + // `bare_bones` + ($($t:tt)*) => (unsafe { log(&format_args!($($t)*).to_string())}) +} + +#[cfg(feature = "target-os")] +use clap::Command; + #[derive(Default)] #[mize_part] pub struct ClientAuth { @@ -67,16 +88,22 @@ pub fn client_auth(mize: &mut Mize) -> MizeResult<()> { Err(_) => None, }; - let mut cli = mize.get_part_native::("cli")?; - cli.subcommand(Command::new("login"), |_, mut mize| { - let secrets = mize.spawn_async_blocking("client_auth", auth_flow(mize_clone))?; - println!("hereeeeee oneeeeeeeeee"); - let mut auth = mize.get_part_native::("client_auth")?; - println!("hereeeeee two"); - write_secrets(&mut mize, &secrets)?; - auth.secrets = Some(secrets); - Ok(()) - }); + #[cfg(feature = "target-os")] + { + let mut cli = mize.get_part_native::("cli")?; + cli.subcommand(Command::new("login"), |_, mut mize| { + let secrets = mize.spawn_async_blocking("client_auth", auth_flow(mize_clone))?; + println!("hereeeeee oneeeeeeeeee"); + let mut auth = mize.get_part_native::("client_auth")?; + println!("hereeeeee two"); + write_secrets(&mut mize, &secrets)?; + auth.secrets = Some(secrets); + Ok(()) + }); + } + + #[cfg(feature = "target-obsidian")] + {} mize.register_part(Box::new(ClientAuth { secrets, @@ -159,9 +186,17 @@ async fn auth_flow(mut mize: Mize) -> MizeResult { auth_url ); - // Try to open browser (best-effort) - if let Err(e) = webbrowser::open(auth_url.as_str()) { - eprintln!("Failed to open browser automatically: {}", e); + #[cfg(feature = "target-os")] + { + // Try to open browser (best-effort) + if let Err(e) = webbrowser::open(auth_url.as_str()) { + eprintln!("Failed to open browser automatically: {}", e); + } + } + + #[cfg(feature = "target-obsidian")] + { + console_log!("try to open auth url in browser"); } println!("When the authorization completes, the web page will show the code (and state)."); diff --git a/packages/ppc/platform/obsidian/deno.json b/packages/ppc/platform/obsidian/deno.json index 9bd8d3a..8da7890 100644 --- a/packages/ppc/platform/obsidian/deno.json +++ b/packages/ppc/platform/obsidian/deno.json @@ -1,7 +1,7 @@ { "name": "@ppc/obsidian-plugin", "tasks": { - "build_rust": "wasm-pack -vvvvv build -d src/platform/obsidian/rust_dist --target web --no-default-features --features target-obsidian", + "build_rust": "wasm-pack -vvvvv build -d platform/obsidian/rust_dist --target web --no-default-features --features target-obsidian", "build": "deno run -A build_rust && mkdir -p dist && touch dist/.hotreload && cp manifest.json dist && deno -A esbuild.config.mjs production", "dev": "" }, diff --git a/packages/ppc/platform/obsidian/mod.rs b/packages/ppc/platform/obsidian/mod.rs index 1ba62c8..001e661 100644 --- a/packages/ppc/platform/obsidian/mod.rs +++ b/packages/ppc/platform/obsidian/mod.rs @@ -1,3 +1,4 @@ +use dioxus::prelude::*; use mize::Mize; use wasm_bindgen::prelude::*; @@ -17,7 +18,27 @@ macro_rules! console_log { #[wasm_bindgen] pub fn obsidian_mize_entrypoint() { - console_log!("hiiiiiiiiiiiii from rust"); let mize = Mize::new(); + //crate::client_auth(mize)?; console_log!("Obsidian Mize initialized"); } + +#[wasm_bindgen] +pub fn show_main_ui() { + let document = web_sys::window() + .expect("global window not available") + .document() + .expect("no document in the global window obj"); + let root = document.get_element_by_id("ppc-app-root").unwrap(); + dioxus_web::launch::launch( + app, + Vec::new(), + vec![Box::new(dioxus_web::Config::new().rootelement(root))], + ); +} + +fn app() -> Element { + rsx! { + div { "Hello, from dioxus!" } + } +} diff --git a/packages/ppc/platform/obsidian/plugin.ts b/packages/ppc/platform/obsidian/plugin.ts index 989ba2d..3b9367c 100644 --- a/packages/ppc/platform/obsidian/plugin.ts +++ b/packages/ppc/platform/obsidian/plugin.ts @@ -1,4 +1,4 @@ -import { Plugin, TFile } from "obsidian"; +import { Plugin, ItemView, TFile } from "obsidian"; import wasmBinary from "./rust_dist/ppc_bg.wasm"; import * as wasmNamespace from "./rust_dist/ppc"; import { c2vi_obsidian_canvas_patch } from "@ppc/marts"; @@ -10,23 +10,29 @@ export default class PPCObsidianPlugin extends Plugin { const wasmModule = await import("./rust_dist/ppc.js"); await wasmModule.default({ module_or_path: wasmBinary }); wasmModule.initSync(); - wasmModule.obsidian_mize_entrypoint(); + console.log("module: ", wasmModule); - const mize = {}; - mize.get_part_native = (name) => this; + // mize filler.... till there is a more proper js lib implemented + this.mize = { parts: { obsidian: this }, misc_stuff: { wasmModule } }; + window.mize = this.mize; + mize.get_part_native = (name) => mize.parts[name]; + + wasmModule.obsidian_mize_entrypoint(); // c2vi part which patches canvas movement c2vi_obsidian_canvas_patch(mize); task_obsidian_otask_parse(mize); + this.registerView("ppc-app-view", (leaf) => new PPCAppView(leaf, this)); + this.addCommand({ id: "app", name: "Open ppc app main page", callback: async () => { const leaf = this.app.workspace.getLeaf(true); await leaf.setViewState({ - type: "ppc-app", + type: "ppc-app-view", active: true, }); this.app.workspace.revealLeaf(leaf); @@ -35,6 +41,33 @@ export default class PPCObsidianPlugin extends Plugin { } onunload() { - this.app.workspace.detachLeavesOfType("ppc-app"); + this.app.workspace.detachLeavesOfType("ppc-app-view"); + } +} + +export class PPCAppView extends ItemView { + constructor(leaf: WorkspaceLeaf, plugin: PPCObsidianPlugin) { + super(leaf); + this.plugin = plugin; + } + + getViewType(): string { + return "ppc-app-view"; + } + + getDisplayText(): string { + return "PPC App"; + } + + override async onOpen() { + this.root = document.createElement("div"); + this.root.id = "ppc-app-root"; + this.containerEl.children[1].appendChild(this.root); + + this.plugin.mize.misc_stuff.wasmModule.show_main_ui(); + } + + override async onClose() { + this.root.remove(); } } diff --git a/packages/spacetime-module-ppc/bindings/add_reducer.rs b/packages/spacetime-module-ppc/bindings/add_reducer.rs new file mode 100644 index 0000000..4fa3f62 --- /dev/null +++ b/packages/spacetime-module-ppc/bindings/add_reducer.rs @@ -0,0 +1,104 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +#![allow(unused, clippy::all)] +use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub(super) struct AddArgs { + pub username: String, +} + +impl From for super::Reducer { + fn from(args: AddArgs) -> Self { + Self::Add { + username: args.username, + } + } +} + +impl __sdk::InModule for AddArgs { + type Module = super::RemoteModule; +} + +pub struct AddCallbackId(__sdk::CallbackId); + +#[allow(non_camel_case_types)] +/// Extension trait for access to the reducer `add`. +/// +/// Implemented for [`super::RemoteReducers`]. +pub trait add { + /// Request that the remote module invoke the reducer `add` to run as soon as possible. + /// + /// This method returns immediately, and errors only if we are unable to send the request. + /// The reducer will run asynchronously in the future, + /// and its status can be observed by listening for [`Self::on_add`] callbacks. + fn add(&self, username: String) -> __sdk::Result<()>; + /// Register a callback to run whenever we are notified of an invocation of the reducer `add`. + /// + /// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`] + /// to determine the reducer's status. + /// + /// The returned [`AddCallbackId`] can be passed to [`Self::remove_on_add`] + /// to cancel the callback. + fn on_add( + &self, + callback: impl FnMut(&super::ReducerEventContext, &String) + Send + 'static, + ) -> AddCallbackId; + /// Cancel a callback previously registered by [`Self::on_add`], + /// causing it not to run in the future. + fn remove_on_add(&self, callback: AddCallbackId); +} + +impl add for super::RemoteReducers { + fn add(&self, username: String) -> __sdk::Result<()> { + self.imp.call_reducer("add", AddArgs { username }) + } + fn on_add( + &self, + mut callback: impl FnMut(&super::ReducerEventContext, &String) + Send + 'static, + ) -> AddCallbackId { + AddCallbackId(self.imp.on_reducer( + "add", + Box::new(move |ctx: &super::ReducerEventContext| { + #[allow(irrefutable_let_patterns)] + let super::ReducerEventContext { + event: + __sdk::ReducerEvent { + reducer: super::Reducer::Add { username }, + .. + }, + .. + } = ctx + else { + unreachable!() + }; + callback(ctx, username) + }), + )) + } + fn remove_on_add(&self, callback: AddCallbackId) { + self.imp.remove_on_reducer("add", callback.0) + } +} + +#[allow(non_camel_case_types)] +#[doc(hidden)] +/// Extension trait for setting the call-flags for the reducer `add`. +/// +/// Implemented for [`super::SetReducerFlags`]. +/// +/// This type is currently unstable and may be removed without a major version bump. +pub trait set_flags_for_add { + /// Set the call-reducer flags for the reducer `add` to `flags`. + /// + /// This type is currently unstable and may be removed without a major version bump. + fn add(&self, flags: __ws::CallReducerFlags); +} + +impl set_flags_for_add for super::SetReducerFlags { + fn add(&self, flags: __ws::CallReducerFlags) { + self.imp.set_call_reducer_flags("add", flags); + } +} diff --git a/packages/spacetime-module-ppc/bindings/identity_connected_reducer.rs b/packages/spacetime-module-ppc/bindings/identity_connected_reducer.rs new file mode 100644 index 0000000..2eaaab0 --- /dev/null +++ b/packages/spacetime-module-ppc/bindings/identity_connected_reducer.rs @@ -0,0 +1,101 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +#![allow(unused, clippy::all)] +use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub(super) struct IdentityConnectedArgs {} + +impl From for super::Reducer { + fn from(args: IdentityConnectedArgs) -> Self { + Self::IdentityConnected + } +} + +impl __sdk::InModule for IdentityConnectedArgs { + type Module = super::RemoteModule; +} + +pub struct IdentityConnectedCallbackId(__sdk::CallbackId); + +#[allow(non_camel_case_types)] +/// Extension trait for access to the reducer `identity_connected`. +/// +/// Implemented for [`super::RemoteReducers`]. +pub trait identity_connected { + /// Request that the remote module invoke the reducer `identity_connected` to run as soon as possible. + /// + /// This method returns immediately, and errors only if we are unable to send the request. + /// The reducer will run asynchronously in the future, + /// and its status can be observed by listening for [`Self::on_identity_connected`] callbacks. + fn identity_connected(&self) -> __sdk::Result<()>; + /// Register a callback to run whenever we are notified of an invocation of the reducer `identity_connected`. + /// + /// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`] + /// to determine the reducer's status. + /// + /// The returned [`IdentityConnectedCallbackId`] can be passed to [`Self::remove_on_identity_connected`] + /// to cancel the callback. + fn on_identity_connected( + &self, + callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, + ) -> IdentityConnectedCallbackId; + /// Cancel a callback previously registered by [`Self::on_identity_connected`], + /// causing it not to run in the future. + fn remove_on_identity_connected(&self, callback: IdentityConnectedCallbackId); +} + +impl identity_connected for super::RemoteReducers { + fn identity_connected(&self) -> __sdk::Result<()> { + self.imp + .call_reducer("identity_connected", IdentityConnectedArgs {}) + } + fn on_identity_connected( + &self, + mut callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, + ) -> IdentityConnectedCallbackId { + IdentityConnectedCallbackId(self.imp.on_reducer( + "identity_connected", + Box::new(move |ctx: &super::ReducerEventContext| { + #[allow(irrefutable_let_patterns)] + let super::ReducerEventContext { + event: + __sdk::ReducerEvent { + reducer: super::Reducer::IdentityConnected {}, + .. + }, + .. + } = ctx + else { + unreachable!() + }; + callback(ctx) + }), + )) + } + fn remove_on_identity_connected(&self, callback: IdentityConnectedCallbackId) { + self.imp.remove_on_reducer("identity_connected", callback.0) + } +} + +#[allow(non_camel_case_types)] +#[doc(hidden)] +/// Extension trait for setting the call-flags for the reducer `identity_connected`. +/// +/// Implemented for [`super::SetReducerFlags`]. +/// +/// This type is currently unstable and may be removed without a major version bump. +pub trait set_flags_for_identity_connected { + /// Set the call-reducer flags for the reducer `identity_connected` to `flags`. + /// + /// This type is currently unstable and may be removed without a major version bump. + fn identity_connected(&self, flags: __ws::CallReducerFlags); +} + +impl set_flags_for_identity_connected for super::SetReducerFlags { + fn identity_connected(&self, flags: __ws::CallReducerFlags) { + self.imp.set_call_reducer_flags("identity_connected", flags); + } +} diff --git a/packages/spacetime-module-ppc/bindings/identity_disconnected_reducer.rs b/packages/spacetime-module-ppc/bindings/identity_disconnected_reducer.rs new file mode 100644 index 0000000..c2892ed --- /dev/null +++ b/packages/spacetime-module-ppc/bindings/identity_disconnected_reducer.rs @@ -0,0 +1,103 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +#![allow(unused, clippy::all)] +use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub(super) struct IdentityDisconnectedArgs {} + +impl From for super::Reducer { + fn from(args: IdentityDisconnectedArgs) -> Self { + Self::IdentityDisconnected + } +} + +impl __sdk::InModule for IdentityDisconnectedArgs { + type Module = super::RemoteModule; +} + +pub struct IdentityDisconnectedCallbackId(__sdk::CallbackId); + +#[allow(non_camel_case_types)] +/// Extension trait for access to the reducer `identity_disconnected`. +/// +/// Implemented for [`super::RemoteReducers`]. +pub trait identity_disconnected { + /// Request that the remote module invoke the reducer `identity_disconnected` to run as soon as possible. + /// + /// This method returns immediately, and errors only if we are unable to send the request. + /// The reducer will run asynchronously in the future, + /// and its status can be observed by listening for [`Self::on_identity_disconnected`] callbacks. + fn identity_disconnected(&self) -> __sdk::Result<()>; + /// Register a callback to run whenever we are notified of an invocation of the reducer `identity_disconnected`. + /// + /// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`] + /// to determine the reducer's status. + /// + /// The returned [`IdentityDisconnectedCallbackId`] can be passed to [`Self::remove_on_identity_disconnected`] + /// to cancel the callback. + fn on_identity_disconnected( + &self, + callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, + ) -> IdentityDisconnectedCallbackId; + /// Cancel a callback previously registered by [`Self::on_identity_disconnected`], + /// causing it not to run in the future. + fn remove_on_identity_disconnected(&self, callback: IdentityDisconnectedCallbackId); +} + +impl identity_disconnected for super::RemoteReducers { + fn identity_disconnected(&self) -> __sdk::Result<()> { + self.imp + .call_reducer("identity_disconnected", IdentityDisconnectedArgs {}) + } + fn on_identity_disconnected( + &self, + mut callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, + ) -> IdentityDisconnectedCallbackId { + IdentityDisconnectedCallbackId(self.imp.on_reducer( + "identity_disconnected", + Box::new(move |ctx: &super::ReducerEventContext| { + #[allow(irrefutable_let_patterns)] + let super::ReducerEventContext { + event: + __sdk::ReducerEvent { + reducer: super::Reducer::IdentityDisconnected {}, + .. + }, + .. + } = ctx + else { + unreachable!() + }; + callback(ctx) + }), + )) + } + fn remove_on_identity_disconnected(&self, callback: IdentityDisconnectedCallbackId) { + self.imp + .remove_on_reducer("identity_disconnected", callback.0) + } +} + +#[allow(non_camel_case_types)] +#[doc(hidden)] +/// Extension trait for setting the call-flags for the reducer `identity_disconnected`. +/// +/// Implemented for [`super::SetReducerFlags`]. +/// +/// This type is currently unstable and may be removed without a major version bump. +pub trait set_flags_for_identity_disconnected { + /// Set the call-reducer flags for the reducer `identity_disconnected` to `flags`. + /// + /// This type is currently unstable and may be removed without a major version bump. + fn identity_disconnected(&self, flags: __ws::CallReducerFlags); +} + +impl set_flags_for_identity_disconnected for super::SetReducerFlags { + fn identity_disconnected(&self, flags: __ws::CallReducerFlags) { + self.imp + .set_call_reducer_flags("identity_disconnected", flags); + } +} diff --git a/packages/spacetime-module-ppc/bindings/mod.rs b/packages/spacetime-module-ppc/bindings/mod.rs new file mode 100644 index 0000000..b55ceaf --- /dev/null +++ b/packages/spacetime-module-ppc/bindings/mod.rs @@ -0,0 +1,876 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +// This was generated using spacetimedb cli version 1.11.3 (commit 02449737ca3b29e7e39679fccbef541a50f32094). + +#![allow(unused, clippy::all)] +use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; + +pub mod add_reducer; +pub mod identity_connected_reducer; +pub mod identity_disconnected_reducer; +pub mod person_table; +pub mod person_type; +pub mod say_hello_reducer; + +pub use add_reducer::{add, set_flags_for_add, AddCallbackId}; +pub use identity_connected_reducer::{ + identity_connected, set_flags_for_identity_connected, IdentityConnectedCallbackId, +}; +pub use identity_disconnected_reducer::{ + identity_disconnected, set_flags_for_identity_disconnected, IdentityDisconnectedCallbackId, +}; +pub use person_table::*; +pub use person_type::Person; +pub use say_hello_reducer::{say_hello, set_flags_for_say_hello, SayHelloCallbackId}; + +#[derive(Clone, PartialEq, Debug)] + +/// One of the reducers defined by this module. +/// +/// Contained within a [`__sdk::ReducerEvent`] in [`EventContext`]s for reducer events +/// to indicate which reducer caused the event. + +pub enum Reducer { + Add { username: String }, + IdentityConnected, + IdentityDisconnected, + SayHello, +} + +impl __sdk::InModule for Reducer { + type Module = RemoteModule; +} + +impl __sdk::Reducer for Reducer { + fn reducer_name(&self) -> &'static str { + match self { + Reducer::Add { .. } => "add", + Reducer::IdentityConnected => "identity_connected", + Reducer::IdentityDisconnected => "identity_disconnected", + Reducer::SayHello => "say_hello", + _ => unreachable!(), + } + } +} +impl TryFrom<__ws::ReducerCallInfo<__ws::BsatnFormat>> for Reducer { + type Error = __sdk::Error; + fn try_from(value: __ws::ReducerCallInfo<__ws::BsatnFormat>) -> __sdk::Result { + match &value.reducer_name[..] { + "add" => { + Ok(__sdk::parse_reducer_args::("add", &value.args)?.into()) + } + "identity_connected" => Ok(__sdk::parse_reducer_args::< + identity_connected_reducer::IdentityConnectedArgs, + >("identity_connected", &value.args)? + .into()), + "identity_disconnected" => Ok(__sdk::parse_reducer_args::< + identity_disconnected_reducer::IdentityDisconnectedArgs, + >("identity_disconnected", &value.args)? + .into()), + "say_hello" => Ok( + __sdk::parse_reducer_args::( + "say_hello", + &value.args, + )? + .into(), + ), + unknown => { + Err( + __sdk::InternalError::unknown_name("reducer", unknown, "ReducerCallInfo") + .into(), + ) + } + } + } +} + +#[derive(Default)] +#[allow(non_snake_case)] +#[doc(hidden)] +pub struct DbUpdate { + person: __sdk::TableUpdate, +} + +impl TryFrom<__ws::DatabaseUpdate<__ws::BsatnFormat>> for DbUpdate { + type Error = __sdk::Error; + fn try_from(raw: __ws::DatabaseUpdate<__ws::BsatnFormat>) -> Result { + let mut db_update = DbUpdate::default(); + for table_update in raw.tables { + match &table_update.table_name[..] { + "person" => db_update + .person + .append(person_table::parse_table_update(table_update)?), + + unknown => { + return Err(__sdk::InternalError::unknown_name( + "table", + unknown, + "DatabaseUpdate", + ) + .into()); + } + } + } + Ok(db_update) + } +} + +impl __sdk::InModule for DbUpdate { + type Module = RemoteModule; +} + +impl __sdk::DbUpdate for DbUpdate { + fn apply_to_client_cache( + &self, + cache: &mut __sdk::ClientCache, + ) -> AppliedDiff<'_> { + let mut diff = AppliedDiff::default(); + + diff.person = cache.apply_diff_to_table::("person", &self.person); + + diff + } +} + +#[derive(Default)] +#[allow(non_snake_case)] +#[doc(hidden)] +pub struct AppliedDiff<'r> { + person: __sdk::TableAppliedDiff<'r, Person>, + __unused: std::marker::PhantomData<&'r ()>, +} + +impl __sdk::InModule for AppliedDiff<'_> { + type Module = RemoteModule; +} + +impl<'r> __sdk::AppliedDiff<'r> for AppliedDiff<'r> { + fn invoke_row_callbacks( + &self, + event: &EventContext, + callbacks: &mut __sdk::DbCallbacks, + ) { + callbacks.invoke_table_row_callbacks::("person", &self.person, event); + } +} + +#[doc(hidden)] +pub struct RemoteModule; + +impl __sdk::InModule for RemoteModule { + type Module = Self; +} + +/// The `reducers` field of [`EventContext`] and [`DbConnection`], +/// with methods provided by extension traits for each reducer defined by the module. +pub struct RemoteReducers { + imp: __sdk::DbContextImpl, +} + +impl __sdk::InModule for RemoteReducers { + type Module = RemoteModule; +} + +/// The `procedures` field of [`DbConnection`] and other [`DbContext`] types, +/// with methods provided by extension traits for each procedure defined by the module. +pub struct RemoteProcedures { + imp: __sdk::DbContextImpl, +} + +impl __sdk::InModule for RemoteProcedures { + type Module = RemoteModule; +} + +#[doc(hidden)] +/// The `set_reducer_flags` field of [`DbConnection`], +/// with methods provided by extension traits for each reducer defined by the module. +/// Each method sets the flags for the reducer with the same name. +/// +/// This type is currently unstable and may be removed without a major version bump. +pub struct SetReducerFlags { + imp: __sdk::DbContextImpl, +} + +impl __sdk::InModule for SetReducerFlags { + type Module = RemoteModule; +} + +/// The `db` field of [`EventContext`] and [`DbConnection`], +/// with methods provided by extension traits for each table defined by the module. +pub struct RemoteTables { + imp: __sdk::DbContextImpl, +} + +impl __sdk::InModule for RemoteTables { + type Module = RemoteModule; +} + +/// A connection to a remote module, including a materialized view of a subset of the database. +/// +/// Connect to a remote module by calling [`DbConnection::builder`] +/// and using the [`__sdk::DbConnectionBuilder`] builder-pattern constructor. +/// +/// You must explicitly advance the connection by calling any one of: +/// +/// - [`DbConnection::frame_tick`]. +/// - [`DbConnection::run_threaded`]. +/// - [`DbConnection::run_async`]. +/// - [`DbConnection::advance_one_message`]. +/// - [`DbConnection::advance_one_message_blocking`]. +/// - [`DbConnection::advance_one_message_async`]. +/// +/// Which of these methods you should call depends on the specific needs of your application, +/// but you must call one of them, or else the connection will never progress. +pub struct DbConnection { + /// Access to tables defined by the module via extension traits implemented for [`RemoteTables`]. + pub db: RemoteTables, + /// Access to reducers defined by the module via extension traits implemented for [`RemoteReducers`]. + pub reducers: RemoteReducers, + #[doc(hidden)] + /// Access to setting the call-flags of each reducer defined for each reducer defined by the module + /// via extension traits implemented for [`SetReducerFlags`]. + /// + /// This type is currently unstable and may be removed without a major version bump. + pub set_reducer_flags: SetReducerFlags, + + /// Access to procedures defined by the module via extension traits implemented for [`RemoteProcedures`]. + pub procedures: RemoteProcedures, + + imp: __sdk::DbContextImpl, +} + +impl __sdk::InModule for DbConnection { + type Module = RemoteModule; +} + +impl __sdk::DbContext for DbConnection { + type DbView = RemoteTables; + type Reducers = RemoteReducers; + type Procedures = RemoteProcedures; + type SetReducerFlags = SetReducerFlags; + + fn db(&self) -> &Self::DbView { + &self.db + } + fn reducers(&self) -> &Self::Reducers { + &self.reducers + } + fn procedures(&self) -> &Self::Procedures { + &self.procedures + } + fn set_reducer_flags(&self) -> &Self::SetReducerFlags { + &self.set_reducer_flags + } + + fn is_active(&self) -> bool { + self.imp.is_active() + } + + fn disconnect(&self) -> __sdk::Result<()> { + self.imp.disconnect() + } + + type SubscriptionBuilder = __sdk::SubscriptionBuilder; + + fn subscription_builder(&self) -> Self::SubscriptionBuilder { + __sdk::SubscriptionBuilder::new(&self.imp) + } + + fn try_identity(&self) -> Option<__sdk::Identity> { + self.imp.try_identity() + } + fn connection_id(&self) -> __sdk::ConnectionId { + self.imp.connection_id() + } + fn try_connection_id(&self) -> Option<__sdk::ConnectionId> { + self.imp.try_connection_id() + } +} + +impl DbConnection { + /// Builder-pattern constructor for a connection to a remote module. + /// + /// See [`__sdk::DbConnectionBuilder`] for required and optional configuration for the new connection. + pub fn builder() -> __sdk::DbConnectionBuilder { + __sdk::DbConnectionBuilder::new() + } + + /// If any WebSocket messages are waiting, process one of them. + /// + /// Returns `true` if a message was processed, or `false` if the queue is empty. + /// Callers should invoke this message in a loop until it returns `false` + /// or for as much time is available to process messages. + /// + /// Returns an error if the connection is disconnected. + /// If the disconnection in question was normal, + /// i.e. the result of a call to [`__sdk::DbContext::disconnect`], + /// the returned error will be downcastable to [`__sdk::DisconnectedError`]. + /// + /// This is a low-level primitive exposed for power users who need significant control over scheduling. + /// Most applications should call [`Self::frame_tick`] each frame + /// to fully exhaust the queue whenever time is available. + pub fn advance_one_message(&self) -> __sdk::Result { + self.imp.advance_one_message() + } + + /// Process one WebSocket message, potentially blocking the current thread until one is received. + /// + /// Returns an error if the connection is disconnected. + /// If the disconnection in question was normal, + /// i.e. the result of a call to [`__sdk::DbContext::disconnect`], + /// the returned error will be downcastable to [`__sdk::DisconnectedError`]. + /// + /// This is a low-level primitive exposed for power users who need significant control over scheduling. + /// Most applications should call [`Self::run_threaded`] to spawn a thread + /// which advances the connection automatically. + pub fn advance_one_message_blocking(&self) -> __sdk::Result<()> { + self.imp.advance_one_message_blocking() + } + + /// Process one WebSocket message, `await`ing until one is received. + /// + /// Returns an error if the connection is disconnected. + /// If the disconnection in question was normal, + /// i.e. the result of a call to [`__sdk::DbContext::disconnect`], + /// the returned error will be downcastable to [`__sdk::DisconnectedError`]. + /// + /// This is a low-level primitive exposed for power users who need significant control over scheduling. + /// Most applications should call [`Self::run_async`] to run an `async` loop + /// which advances the connection when polled. + pub async fn advance_one_message_async(&self) -> __sdk::Result<()> { + self.imp.advance_one_message_async().await + } + + /// Process all WebSocket messages waiting in the queue, + /// then return without `await`ing or blocking the current thread. + pub fn frame_tick(&self) -> __sdk::Result<()> { + self.imp.frame_tick() + } + + /// Spawn a thread which processes WebSocket messages as they are received. + pub fn run_threaded(&self) -> std::thread::JoinHandle<()> { + self.imp.run_threaded() + } + + /// Run an `async` loop which processes WebSocket messages when polled. + pub async fn run_async(&self) -> __sdk::Result<()> { + self.imp.run_async().await + } +} + +impl __sdk::DbConnection for DbConnection { + fn new(imp: __sdk::DbContextImpl) -> Self { + Self { + db: RemoteTables { imp: imp.clone() }, + reducers: RemoteReducers { imp: imp.clone() }, + procedures: RemoteProcedures { imp: imp.clone() }, + set_reducer_flags: SetReducerFlags { imp: imp.clone() }, + imp, + } + } +} + +/// A handle on a subscribed query. +// TODO: Document this better after implementing the new subscription API. +#[derive(Clone)] +pub struct SubscriptionHandle { + imp: __sdk::SubscriptionHandleImpl, +} + +impl __sdk::InModule for SubscriptionHandle { + type Module = RemoteModule; +} + +impl __sdk::SubscriptionHandle for SubscriptionHandle { + fn new(imp: __sdk::SubscriptionHandleImpl) -> Self { + Self { imp } + } + + /// Returns true if this subscription has been terminated due to an unsubscribe call or an error. + fn is_ended(&self) -> bool { + self.imp.is_ended() + } + + /// Returns true if this subscription has been applied and has not yet been unsubscribed. + fn is_active(&self) -> bool { + self.imp.is_active() + } + + /// Unsubscribe from the query controlled by this `SubscriptionHandle`, + /// then run `on_end` when its rows are removed from the client cache. + fn unsubscribe_then(self, on_end: __sdk::OnEndedCallback) -> __sdk::Result<()> { + self.imp.unsubscribe_then(Some(on_end)) + } + + fn unsubscribe(self) -> __sdk::Result<()> { + self.imp.unsubscribe_then(None) + } +} + +/// Alias trait for a [`__sdk::DbContext`] connected to this module, +/// with that trait's associated types bounded to this module's concrete types. +/// +/// Users can use this trait as a boundary on definitions which should accept +/// either a [`DbConnection`] or an [`EventContext`] and operate on either. +pub trait RemoteDbContext: + __sdk::DbContext< + DbView = RemoteTables, + Reducers = RemoteReducers, + SetReducerFlags = SetReducerFlags, + SubscriptionBuilder = __sdk::SubscriptionBuilder, +> +{ +} +impl< + Ctx: __sdk::DbContext< + DbView = RemoteTables, + Reducers = RemoteReducers, + SetReducerFlags = SetReducerFlags, + SubscriptionBuilder = __sdk::SubscriptionBuilder, + >, + > RemoteDbContext for Ctx +{ +} + +/// An [`__sdk::DbContext`] augmented with a [`__sdk::Event`], +/// passed to [`__sdk::Table::on_insert`], [`__sdk::Table::on_delete`] and [`__sdk::TableWithPrimaryKey::on_update`] callbacks. +pub struct EventContext { + /// Access to tables defined by the module via extension traits implemented for [`RemoteTables`]. + pub db: RemoteTables, + /// Access to reducers defined by the module via extension traits implemented for [`RemoteReducers`]. + pub reducers: RemoteReducers, + /// Access to setting the call-flags of each reducer defined for each reducer defined by the module + /// via extension traits implemented for [`SetReducerFlags`]. + /// + /// This type is currently unstable and may be removed without a major version bump. + pub set_reducer_flags: SetReducerFlags, + /// Access to procedures defined by the module via extension traits implemented for [`RemoteProcedures`]. + pub procedures: RemoteProcedures, + /// The event which caused these callbacks to run. + pub event: __sdk::Event, + imp: __sdk::DbContextImpl, +} + +impl __sdk::AbstractEventContext for EventContext { + type Event = __sdk::Event; + fn event(&self) -> &Self::Event { + &self.event + } + fn new(imp: __sdk::DbContextImpl, event: Self::Event) -> Self { + Self { + db: RemoteTables { imp: imp.clone() }, + reducers: RemoteReducers { imp: imp.clone() }, + set_reducer_flags: SetReducerFlags { imp: imp.clone() }, + procedures: RemoteProcedures { imp: imp.clone() }, + event, + imp, + } + } +} + +impl __sdk::InModule for EventContext { + type Module = RemoteModule; +} + +impl __sdk::DbContext for EventContext { + type DbView = RemoteTables; + type Reducers = RemoteReducers; + type Procedures = RemoteProcedures; + type SetReducerFlags = SetReducerFlags; + + fn db(&self) -> &Self::DbView { + &self.db + } + fn reducers(&self) -> &Self::Reducers { + &self.reducers + } + fn procedures(&self) -> &Self::Procedures { + &self.procedures + } + fn set_reducer_flags(&self) -> &Self::SetReducerFlags { + &self.set_reducer_flags + } + + fn is_active(&self) -> bool { + self.imp.is_active() + } + + fn disconnect(&self) -> __sdk::Result<()> { + self.imp.disconnect() + } + + type SubscriptionBuilder = __sdk::SubscriptionBuilder; + + fn subscription_builder(&self) -> Self::SubscriptionBuilder { + __sdk::SubscriptionBuilder::new(&self.imp) + } + + fn try_identity(&self) -> Option<__sdk::Identity> { + self.imp.try_identity() + } + fn connection_id(&self) -> __sdk::ConnectionId { + self.imp.connection_id() + } + fn try_connection_id(&self) -> Option<__sdk::ConnectionId> { + self.imp.try_connection_id() + } +} + +impl __sdk::EventContext for EventContext {} + +/// An [`__sdk::DbContext`] augmented with a [`__sdk::ReducerEvent`], +/// passed to on-reducer callbacks. +pub struct ReducerEventContext { + /// Access to tables defined by the module via extension traits implemented for [`RemoteTables`]. + pub db: RemoteTables, + /// Access to reducers defined by the module via extension traits implemented for [`RemoteReducers`]. + pub reducers: RemoteReducers, + /// Access to setting the call-flags of each reducer defined for each reducer defined by the module + /// via extension traits implemented for [`SetReducerFlags`]. + /// + /// This type is currently unstable and may be removed without a major version bump. + pub set_reducer_flags: SetReducerFlags, + /// Access to procedures defined by the module via extension traits implemented for [`RemoteProcedures`]. + pub procedures: RemoteProcedures, + /// The event which caused these callbacks to run. + pub event: __sdk::ReducerEvent, + imp: __sdk::DbContextImpl, +} + +impl __sdk::AbstractEventContext for ReducerEventContext { + type Event = __sdk::ReducerEvent; + fn event(&self) -> &Self::Event { + &self.event + } + fn new(imp: __sdk::DbContextImpl, event: Self::Event) -> Self { + Self { + db: RemoteTables { imp: imp.clone() }, + reducers: RemoteReducers { imp: imp.clone() }, + set_reducer_flags: SetReducerFlags { imp: imp.clone() }, + procedures: RemoteProcedures { imp: imp.clone() }, + event, + imp, + } + } +} + +impl __sdk::InModule for ReducerEventContext { + type Module = RemoteModule; +} + +impl __sdk::DbContext for ReducerEventContext { + type DbView = RemoteTables; + type Reducers = RemoteReducers; + type Procedures = RemoteProcedures; + type SetReducerFlags = SetReducerFlags; + + fn db(&self) -> &Self::DbView { + &self.db + } + fn reducers(&self) -> &Self::Reducers { + &self.reducers + } + fn procedures(&self) -> &Self::Procedures { + &self.procedures + } + fn set_reducer_flags(&self) -> &Self::SetReducerFlags { + &self.set_reducer_flags + } + + fn is_active(&self) -> bool { + self.imp.is_active() + } + + fn disconnect(&self) -> __sdk::Result<()> { + self.imp.disconnect() + } + + type SubscriptionBuilder = __sdk::SubscriptionBuilder; + + fn subscription_builder(&self) -> Self::SubscriptionBuilder { + __sdk::SubscriptionBuilder::new(&self.imp) + } + + fn try_identity(&self) -> Option<__sdk::Identity> { + self.imp.try_identity() + } + fn connection_id(&self) -> __sdk::ConnectionId { + self.imp.connection_id() + } + fn try_connection_id(&self) -> Option<__sdk::ConnectionId> { + self.imp.try_connection_id() + } +} + +impl __sdk::ReducerEventContext for ReducerEventContext {} + +/// An [`__sdk::DbContext`] passed to procedure callbacks. +pub struct ProcedureEventContext { + /// Access to tables defined by the module via extension traits implemented for [`RemoteTables`]. + pub db: RemoteTables, + /// Access to reducers defined by the module via extension traits implemented for [`RemoteReducers`]. + pub reducers: RemoteReducers, + /// Access to setting the call-flags of each reducer defined for each reducer defined by the module + /// via extension traits implemented for [`SetReducerFlags`]. + /// + /// This type is currently unstable and may be removed without a major version bump. + pub set_reducer_flags: SetReducerFlags, + /// Access to procedures defined by the module via extension traits implemented for [`RemoteProcedures`]. + pub procedures: RemoteProcedures, + imp: __sdk::DbContextImpl, +} + +impl __sdk::AbstractEventContext for ProcedureEventContext { + type Event = (); + fn event(&self) -> &Self::Event { + &() + } + fn new(imp: __sdk::DbContextImpl, _event: Self::Event) -> Self { + Self { + db: RemoteTables { imp: imp.clone() }, + reducers: RemoteReducers { imp: imp.clone() }, + procedures: RemoteProcedures { imp: imp.clone() }, + set_reducer_flags: SetReducerFlags { imp: imp.clone() }, + imp, + } + } +} + +impl __sdk::InModule for ProcedureEventContext { + type Module = RemoteModule; +} + +impl __sdk::DbContext for ProcedureEventContext { + type DbView = RemoteTables; + type Reducers = RemoteReducers; + type Procedures = RemoteProcedures; + type SetReducerFlags = SetReducerFlags; + + fn db(&self) -> &Self::DbView { + &self.db + } + fn reducers(&self) -> &Self::Reducers { + &self.reducers + } + fn procedures(&self) -> &Self::Procedures { + &self.procedures + } + fn set_reducer_flags(&self) -> &Self::SetReducerFlags { + &self.set_reducer_flags + } + + fn is_active(&self) -> bool { + self.imp.is_active() + } + + fn disconnect(&self) -> __sdk::Result<()> { + self.imp.disconnect() + } + + type SubscriptionBuilder = __sdk::SubscriptionBuilder; + + fn subscription_builder(&self) -> Self::SubscriptionBuilder { + __sdk::SubscriptionBuilder::new(&self.imp) + } + + fn try_identity(&self) -> Option<__sdk::Identity> { + self.imp.try_identity() + } + fn connection_id(&self) -> __sdk::ConnectionId { + self.imp.connection_id() + } + fn try_connection_id(&self) -> Option<__sdk::ConnectionId> { + self.imp.try_connection_id() + } +} + +impl __sdk::ProcedureEventContext for ProcedureEventContext {} + +/// An [`__sdk::DbContext`] passed to [`__sdk::SubscriptionBuilder::on_applied`] and [`SubscriptionHandle::unsubscribe_then`] callbacks. +pub struct SubscriptionEventContext { + /// Access to tables defined by the module via extension traits implemented for [`RemoteTables`]. + pub db: RemoteTables, + /// Access to reducers defined by the module via extension traits implemented for [`RemoteReducers`]. + pub reducers: RemoteReducers, + /// Access to setting the call-flags of each reducer defined for each reducer defined by the module + /// via extension traits implemented for [`SetReducerFlags`]. + /// + /// This type is currently unstable and may be removed without a major version bump. + pub set_reducer_flags: SetReducerFlags, + /// Access to procedures defined by the module via extension traits implemented for [`RemoteProcedures`]. + pub procedures: RemoteProcedures, + imp: __sdk::DbContextImpl, +} + +impl __sdk::AbstractEventContext for SubscriptionEventContext { + type Event = (); + fn event(&self) -> &Self::Event { + &() + } + fn new(imp: __sdk::DbContextImpl, _event: Self::Event) -> Self { + Self { + db: RemoteTables { imp: imp.clone() }, + reducers: RemoteReducers { imp: imp.clone() }, + procedures: RemoteProcedures { imp: imp.clone() }, + set_reducer_flags: SetReducerFlags { imp: imp.clone() }, + imp, + } + } +} + +impl __sdk::InModule for SubscriptionEventContext { + type Module = RemoteModule; +} + +impl __sdk::DbContext for SubscriptionEventContext { + type DbView = RemoteTables; + type Reducers = RemoteReducers; + type Procedures = RemoteProcedures; + type SetReducerFlags = SetReducerFlags; + + fn db(&self) -> &Self::DbView { + &self.db + } + fn reducers(&self) -> &Self::Reducers { + &self.reducers + } + fn procedures(&self) -> &Self::Procedures { + &self.procedures + } + fn set_reducer_flags(&self) -> &Self::SetReducerFlags { + &self.set_reducer_flags + } + + fn is_active(&self) -> bool { + self.imp.is_active() + } + + fn disconnect(&self) -> __sdk::Result<()> { + self.imp.disconnect() + } + + type SubscriptionBuilder = __sdk::SubscriptionBuilder; + + fn subscription_builder(&self) -> Self::SubscriptionBuilder { + __sdk::SubscriptionBuilder::new(&self.imp) + } + + fn try_identity(&self) -> Option<__sdk::Identity> { + self.imp.try_identity() + } + fn connection_id(&self) -> __sdk::ConnectionId { + self.imp.connection_id() + } + fn try_connection_id(&self) -> Option<__sdk::ConnectionId> { + self.imp.try_connection_id() + } +} + +impl __sdk::SubscriptionEventContext for SubscriptionEventContext {} + +/// An [`__sdk::DbContext`] augmented with a [`__sdk::Error`], +/// passed to [`__sdk::DbConnectionBuilder::on_disconnect`], [`__sdk::DbConnectionBuilder::on_connect_error`] and [`__sdk::SubscriptionBuilder::on_error`] callbacks. +pub struct ErrorContext { + /// Access to tables defined by the module via extension traits implemented for [`RemoteTables`]. + pub db: RemoteTables, + /// Access to reducers defined by the module via extension traits implemented for [`RemoteReducers`]. + pub reducers: RemoteReducers, + /// Access to setting the call-flags of each reducer defined for each reducer defined by the module + /// via extension traits implemented for [`SetReducerFlags`]. + /// + /// This type is currently unstable and may be removed without a major version bump. + pub set_reducer_flags: SetReducerFlags, + /// Access to procedures defined by the module via extension traits implemented for [`RemoteProcedures`]. + pub procedures: RemoteProcedures, + /// The event which caused these callbacks to run. + pub event: Option<__sdk::Error>, + imp: __sdk::DbContextImpl, +} + +impl __sdk::AbstractEventContext for ErrorContext { + type Event = Option<__sdk::Error>; + fn event(&self) -> &Self::Event { + &self.event + } + fn new(imp: __sdk::DbContextImpl, event: Self::Event) -> Self { + Self { + db: RemoteTables { imp: imp.clone() }, + reducers: RemoteReducers { imp: imp.clone() }, + set_reducer_flags: SetReducerFlags { imp: imp.clone() }, + procedures: RemoteProcedures { imp: imp.clone() }, + event, + imp, + } + } +} + +impl __sdk::InModule for ErrorContext { + type Module = RemoteModule; +} + +impl __sdk::DbContext for ErrorContext { + type DbView = RemoteTables; + type Reducers = RemoteReducers; + type Procedures = RemoteProcedures; + type SetReducerFlags = SetReducerFlags; + + fn db(&self) -> &Self::DbView { + &self.db + } + fn reducers(&self) -> &Self::Reducers { + &self.reducers + } + fn procedures(&self) -> &Self::Procedures { + &self.procedures + } + fn set_reducer_flags(&self) -> &Self::SetReducerFlags { + &self.set_reducer_flags + } + + fn is_active(&self) -> bool { + self.imp.is_active() + } + + fn disconnect(&self) -> __sdk::Result<()> { + self.imp.disconnect() + } + + type SubscriptionBuilder = __sdk::SubscriptionBuilder; + + fn subscription_builder(&self) -> Self::SubscriptionBuilder { + __sdk::SubscriptionBuilder::new(&self.imp) + } + + fn try_identity(&self) -> Option<__sdk::Identity> { + self.imp.try_identity() + } + fn connection_id(&self) -> __sdk::ConnectionId { + self.imp.connection_id() + } + fn try_connection_id(&self) -> Option<__sdk::ConnectionId> { + self.imp.try_connection_id() + } +} + +impl __sdk::ErrorContext for ErrorContext {} + +impl __sdk::SpacetimeModule for RemoteModule { + type DbConnection = DbConnection; + type EventContext = EventContext; + type ReducerEventContext = ReducerEventContext; + type ProcedureEventContext = ProcedureEventContext; + type SubscriptionEventContext = SubscriptionEventContext; + type ErrorContext = ErrorContext; + type Reducer = Reducer; + type DbView = RemoteTables; + type Reducers = RemoteReducers; + type SetReducerFlags = SetReducerFlags; + type DbUpdate = DbUpdate; + type AppliedDiff<'r> = AppliedDiff<'r>; + type SubscriptionHandle = SubscriptionHandle; + + fn register_tables(client_cache: &mut __sdk::ClientCache) { + person_table::register_table(client_cache); + } +} diff --git a/packages/spacetime-module-ppc/bindings/person_table.rs b/packages/spacetime-module-ppc/bindings/person_table.rs new file mode 100644 index 0000000..da3f64b --- /dev/null +++ b/packages/spacetime-module-ppc/bindings/person_table.rs @@ -0,0 +1,95 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +#![allow(unused, clippy::all)] +use super::person_type::Person; +use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; + +/// Table handle for the table `person`. +/// +/// Obtain a handle from the [`PersonTableAccess::person`] method on [`super::RemoteTables`], +/// like `ctx.db.person()`. +/// +/// Users are encouraged not to explicitly reference this type, +/// but to directly chain method calls, +/// like `ctx.db.person().on_insert(...)`. +pub struct PersonTableHandle<'ctx> { + imp: __sdk::TableHandle, + ctx: std::marker::PhantomData<&'ctx super::RemoteTables>, +} + +#[allow(non_camel_case_types)] +/// Extension trait for access to the table `person`. +/// +/// Implemented for [`super::RemoteTables`]. +pub trait PersonTableAccess { + #[allow(non_snake_case)] + /// Obtain a [`PersonTableHandle`], which mediates access to the table `person`. + fn person(&self) -> PersonTableHandle<'_>; +} + +impl PersonTableAccess for super::RemoteTables { + fn person(&self) -> PersonTableHandle<'_> { + PersonTableHandle { + imp: self.imp.get_table::("person"), + ctx: std::marker::PhantomData, + } + } +} + +pub struct PersonInsertCallbackId(__sdk::CallbackId); +pub struct PersonDeleteCallbackId(__sdk::CallbackId); + +impl<'ctx> __sdk::Table for PersonTableHandle<'ctx> { + type Row = Person; + type EventContext = super::EventContext; + + fn count(&self) -> u64 { + self.imp.count() + } + fn iter(&self) -> impl Iterator + '_ { + self.imp.iter() + } + + type InsertCallbackId = PersonInsertCallbackId; + + fn on_insert( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, + ) -> PersonInsertCallbackId { + PersonInsertCallbackId(self.imp.on_insert(Box::new(callback))) + } + + fn remove_on_insert(&self, callback: PersonInsertCallbackId) { + self.imp.remove_on_insert(callback.0) + } + + type DeleteCallbackId = PersonDeleteCallbackId; + + fn on_delete( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, + ) -> PersonDeleteCallbackId { + PersonDeleteCallbackId(self.imp.on_delete(Box::new(callback))) + } + + fn remove_on_delete(&self, callback: PersonDeleteCallbackId) { + self.imp.remove_on_delete(callback.0) + } +} + +#[doc(hidden)] +pub(super) fn register_table(client_cache: &mut __sdk::ClientCache) { + let _table = client_cache.get_or_make_table::("person"); +} + +#[doc(hidden)] +pub(super) fn parse_table_update( + raw_updates: __ws::TableUpdate<__ws::BsatnFormat>, +) -> __sdk::Result<__sdk::TableUpdate> { + __sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| { + __sdk::InternalError::failed_parse("TableUpdate", "TableUpdate") + .with_cause(e) + .into() + }) +} diff --git a/packages/spacetime-module-ppc/bindings/person_type.rs b/packages/spacetime-module-ppc/bindings/person_type.rs new file mode 100644 index 0000000..7e627a2 --- /dev/null +++ b/packages/spacetime-module-ppc/bindings/person_type.rs @@ -0,0 +1,15 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +#![allow(unused, clippy::all)] +use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub struct Person { + pub username: String, +} + +impl __sdk::InModule for Person { + type Module = super::RemoteModule; +} diff --git a/packages/spacetime-module-ppc/bindings/say_hello_reducer.rs b/packages/spacetime-module-ppc/bindings/say_hello_reducer.rs new file mode 100644 index 0000000..d326602 --- /dev/null +++ b/packages/spacetime-module-ppc/bindings/say_hello_reducer.rs @@ -0,0 +1,100 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +#![allow(unused, clippy::all)] +use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub(super) struct SayHelloArgs {} + +impl From for super::Reducer { + fn from(args: SayHelloArgs) -> Self { + Self::SayHello + } +} + +impl __sdk::InModule for SayHelloArgs { + type Module = super::RemoteModule; +} + +pub struct SayHelloCallbackId(__sdk::CallbackId); + +#[allow(non_camel_case_types)] +/// Extension trait for access to the reducer `say_hello`. +/// +/// Implemented for [`super::RemoteReducers`]. +pub trait say_hello { + /// Request that the remote module invoke the reducer `say_hello` to run as soon as possible. + /// + /// This method returns immediately, and errors only if we are unable to send the request. + /// The reducer will run asynchronously in the future, + /// and its status can be observed by listening for [`Self::on_say_hello`] callbacks. + fn say_hello(&self) -> __sdk::Result<()>; + /// Register a callback to run whenever we are notified of an invocation of the reducer `say_hello`. + /// + /// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`] + /// to determine the reducer's status. + /// + /// The returned [`SayHelloCallbackId`] can be passed to [`Self::remove_on_say_hello`] + /// to cancel the callback. + fn on_say_hello( + &self, + callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, + ) -> SayHelloCallbackId; + /// Cancel a callback previously registered by [`Self::on_say_hello`], + /// causing it not to run in the future. + fn remove_on_say_hello(&self, callback: SayHelloCallbackId); +} + +impl say_hello for super::RemoteReducers { + fn say_hello(&self) -> __sdk::Result<()> { + self.imp.call_reducer("say_hello", SayHelloArgs {}) + } + fn on_say_hello( + &self, + mut callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, + ) -> SayHelloCallbackId { + SayHelloCallbackId(self.imp.on_reducer( + "say_hello", + Box::new(move |ctx: &super::ReducerEventContext| { + #[allow(irrefutable_let_patterns)] + let super::ReducerEventContext { + event: + __sdk::ReducerEvent { + reducer: super::Reducer::SayHello {}, + .. + }, + .. + } = ctx + else { + unreachable!() + }; + callback(ctx) + }), + )) + } + fn remove_on_say_hello(&self, callback: SayHelloCallbackId) { + self.imp.remove_on_reducer("say_hello", callback.0) + } +} + +#[allow(non_camel_case_types)] +#[doc(hidden)] +/// Extension trait for setting the call-flags for the reducer `say_hello`. +/// +/// Implemented for [`super::SetReducerFlags`]. +/// +/// This type is currently unstable and may be removed without a major version bump. +pub trait set_flags_for_say_hello { + /// Set the call-reducer flags for the reducer `say_hello` to `flags`. + /// + /// This type is currently unstable and may be removed without a major version bump. + fn say_hello(&self, flags: __ws::CallReducerFlags); +} + +impl set_flags_for_say_hello for super::SetReducerFlags { + fn say_hello(&self, flags: __ws::CallReducerFlags) { + self.imp.set_call_reducer_flags("say_hello", flags); + } +} diff --git a/packages/spacetime-module-ppc/src/lib.rs b/packages/spacetime-module-ppc/src/lib.rs index d264a25..56a5da8 100644 --- a/packages/spacetime-module-ppc/src/lib.rs +++ b/packages/spacetime-module-ppc/src/lib.rs @@ -2,7 +2,7 @@ use log::*; use spacetimedb::{ReducerContext, Table}; #[spacetimedb::table(name = person, public)] -pub struct CoolPerson { +pub struct Person { username: String, } @@ -24,7 +24,7 @@ pub fn identity_disconnected(_ctx: &ReducerContext) { #[spacetimedb::reducer] pub fn add(ctx: &ReducerContext, username: String) { - ctx.db.person().insert(CoolPerson { username }); + ctx.db.person().insert(Person { username }); } #[spacetimedb::reducer]