diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..cffc922 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use flake . --impure diff --git a/.gitignore b/.gitignore index ab1d027..bf05319 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ target +.direnv # for nix result @@ -12,3 +13,4 @@ mize_config.toml # I put testing stuff for this projekt that I don't want to push to github into a folder called gitignore gitignore + diff --git a/Cargo.lock b/Cargo.lock index dc01d90..1468184 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -73,6 +73,21 @@ dependencies = [ "memchr", ] +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + [[package]] name = "allocator-api2" version = "0.2.21" @@ -144,6 +159,12 @@ version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" +[[package]] +name = "anymap3" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "170433209e817da6aae2c51aa0dd443009a613425dd041ebfb2492d1c4c11a25" + [[package]] name = "approx" version = "0.3.2" @@ -690,6 +711,27 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "brotli" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d640d25bc63c50fb1f0b545ffd80207d2e10a4c965530809b40ba3386825c391" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "2.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e2e4afe60d7dd600fdd3de8d0f08c2b7ec039712e3b6137ff98b7004e82de4f" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + [[package]] name = "bumpalo" version = "3.20.2" @@ -730,6 +772,16 @@ dependencies = [ "serde", ] +[[package]] +name = "bytestring" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "113b4343b5f6617e7ad401ced8de3cc8b012e73a594347c307b90db3e9271289" +dependencies = [ + "bytes", + "serde_core", +] + [[package]] name = "cairo-rs" version = "0.18.5" @@ -1051,6 +1103,17 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "console" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d64e8af5551369d19cf50138de61f1c42074ab970f74e99be916646777f8fc87" +dependencies = [ + "encode_unicode", + "libc", + "windows-sys 0.61.2", +] + [[package]] name = "console_error_panic_hook" version = "0.1.7" @@ -1340,6 +1403,15 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "crossbeam-queue" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-utils" version = "0.8.21" @@ -1764,8 +1836,8 @@ dependencies = [ "proc-macro2", "quote", "stringcase", - "strum", - "strum_macros", + "strum 0.27.2", + "strum_macros 0.27.2", "syn 2.0.117", "syn-match", "thiserror 2.0.18", @@ -2901,6 +2973,12 @@ dependencies = [ "zeroize", ] +[[package]] +name = "encode_unicode" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" + [[package]] name = "encoding_rs" version = "0.8.35" @@ -2922,6 +3000,26 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "enum-map" +version = "2.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6866f3bfdf8207509a033af1a75a7b08abda06bbaaeae6669323fd5a097df2e9" +dependencies = [ + "enum-map-derive", +] + +[[package]] +name = "enum-map-derive" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f282cfdfe92516eb26c2af8589c274c7c17681f5ecc03c18255fe741c6aa64eb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "enumset" version = "1.1.10" @@ -3057,6 +3155,12 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + [[package]] name = "flate2" version = "1.1.9" @@ -3807,6 +3911,9 @@ dependencies = [ "allocator-api2", "equivalent", "foldhash 0.2.0", + "rayon", + "serde", + "serde_core", ] [[package]] @@ -4400,6 +4507,22 @@ dependencies = [ "generic-array", ] +[[package]] +name = "insta" +version = "1.47.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b4a6248eb93a4401ed2f37dfe8ea592d3cf05b7cf4f8efa867b6895af7e094e" +dependencies = [ + "console", + "once_cell", + "regex", + "serde", + "similar", + "tempfile", + "toml_edit 0.25.8+spec-1.1.0", + "toml_writer", +] + [[package]] name = "interner" version = "0.2.1" @@ -5181,17 +5304,17 @@ dependencies = [ [[package]] name = "native-tls" -version = "0.2.18" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "465500e14ea162429d264d44189adc38b199b62b1c21eea9f69e4b73cb03bbf2" +checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" dependencies = [ "libc", "log", "openssl", - "openssl-probe", + "openssl-probe 0.1.6", "openssl-sys", "schannel", - "security-framework", + "security-framework 2.11.1", "security-framework-sys", "tempfile", ] @@ -5616,6 +5739,12 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "openssl-probe" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" + [[package]] name = "openssl-probe" version = "0.2.1" @@ -5777,6 +5906,16 @@ version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" +[[package]] +name = "petgraph" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" +dependencies = [ + "fixedbitset", + "indexmap 2.13.0", +] + [[package]] name = "phf" version = "0.8.0" @@ -6032,10 +6171,12 @@ dependencies = [ "axum-extra 0.10.3", "axum-oidc", "base64 0.22.1", + "chrono", "clap", "dioxus", "dioxus-ssr 0.5.6", "dioxus-web", + "flume 0.12.0", "html-escape", "js-sys", "marts", @@ -6045,6 +6186,7 @@ dependencies = [ "reqwest 0.11.27", "serde", "serde_json", + "spacetimedb-sdk", "time", "tokio", "tower 0.5.3", @@ -6057,6 +6199,14 @@ dependencies = [ "webbrowser", ] +[[package]] +name = "ppc-spacetime" +version = "0.1.0" +dependencies = [ + "log", + "spacetimedb", +] + [[package]] name = "ppv-lite86" version = "0.2.21" @@ -6170,6 +6320,41 @@ dependencies = [ "version_check", ] +[[package]] +name = "prometheus" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ca5326d8d0b950a9acd87e6a3f94745394f62e4dae1b1ee22b2bc0c394af43a" +dependencies = [ + "cfg-if 1.0.4", + "fnv", + "lazy_static", + "memchr", + "parking_lot", + "protobuf", + "thiserror 2.0.18", +] + +[[package]] +name = "protobuf" +version = "3.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d65a1d4ddae7d8b5de68153b48f6aa3bba8cb002b243dbdbc55a5afbc98f99f4" +dependencies = [ + "once_cell", + "protobuf-support", + "thiserror 1.0.69", +] + +[[package]] +name = "protobuf-support" +version = "3.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e36c2f31e0a47f9280fb347ef5e461ffcd2c52dd520d8e216b52f93b0b0d7d6" +dependencies = [ + "thiserror 1.0.69", +] + [[package]] name = "psl-types" version = "2.0.11" @@ -6196,14 +6381,6 @@ dependencies = [ "psl-types", ] -[[package]] -name = "quickstart_chat" -version = "0.1.0" -dependencies = [ - "log", - "spacetimedb", -] - [[package]] name = "quinn" version = "0.11.9" @@ -6810,10 +6987,10 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" dependencies = [ - "openssl-probe", + "openssl-probe 0.2.1", "rustls-pki-types", "schannel", - "security-framework", + "security-framework 3.7.0", ] [[package]] @@ -6859,7 +7036,7 @@ dependencies = [ "rustls-native-certs", "rustls-platform-verifier-android", "rustls-webpki 0.103.10", - "security-framework", + "security-framework 3.7.0", "security-framework-sys", "webpki-root-certs", "windows-sys 0.61.2", @@ -7021,6 +7198,19 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4904c83c6e51f1b9b08bfa5a86f35a51798e8307186e6f5513852210a219c0bb" +[[package]] +name = "security-framework" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +dependencies = [ + "bitflags 2.11.0", + "core-foundation 0.9.4", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + [[package]] name = "security-framework" version = "3.7.0" @@ -7209,6 +7399,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_spanned" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26" +dependencies = [ + "serde_core", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -7385,6 +7584,12 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" +[[package]] +name = "similar" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa" + [[package]] name = "siphasher" version = "0.3.11" @@ -7569,6 +7774,43 @@ dependencies = [ "spacetimedb-primitives", ] +[[package]] +name = "spacetimedb-client-api-messages" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02a18c2e145f61ad498f8094a2231e09f8d39a3dde09defa716075dbcb8c7e85" +dependencies = [ + "bytes", + "bytestring", + "chrono", + "derive_more 0.99.20", + "enum-as-inner", + "serde", + "serde_json", + "serde_with", + "smallvec", + "spacetimedb-lib", + "spacetimedb-primitives", + "spacetimedb-sats", + "strum 0.25.0", + "thiserror 1.0.69", +] + +[[package]] +name = "spacetimedb-data-structures" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e4035c17ddbfc8c49a659bd6fb265b0a2a11115d1b4ad1963bccfad75cdfb4b" +dependencies = [ + "ahash", + "crossbeam-queue", + "either", + "hashbrown 0.16.1", + "nohash-hasher", + "smallvec", + "thiserror 1.0.69", +] + [[package]] name = "spacetimedb-lib" version = "2.1.0" @@ -7581,15 +7823,40 @@ dependencies = [ "chrono", "derive_more 0.99.20", "enum-as-inner", + "enum-map", "hex", "itertools 0.12.1", "log", + "serde", "spacetimedb-bindings-macro", + "spacetimedb-metrics", "spacetimedb-primitives", "spacetimedb-sats", "thiserror 1.0.69", ] +[[package]] +name = "spacetimedb-memory-usage" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c00614eb981354ee6b31661ec47002d3fc274f9d4543279dd6ee8692cdd8266" +dependencies = [ + "decorum", + "ethnum", +] + +[[package]] +name = "spacetimedb-metrics" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef6f7f6b24932505a696b75b7e5e60646ab1d76eeb8d2f95f04948562c965b5e" +dependencies = [ + "arrayvec", + "itertools 0.12.1", + "paste", + "prometheus", +] + [[package]] name = "spacetimedb-primitives" version = "2.1.0" @@ -7601,6 +7868,7 @@ dependencies = [ "enum-as-inner", "itertools 0.12.1", "nohash-hasher", + "spacetimedb-memory-usage", ] [[package]] @@ -7623,6 +7891,7 @@ dependencies = [ "bitflags 2.11.0", "bytemuck", "bytes", + "bytestring", "chrono", "decorum", "derive_more 0.99.20", @@ -7633,14 +7902,92 @@ dependencies = [ "lean_string", "rand 0.9.2", "second-stack", + "serde", "sha3", "smallvec", "spacetimedb-bindings-macro", + "spacetimedb-memory-usage", + "spacetimedb-metrics", "spacetimedb-primitives", "thiserror 1.0.69", "uuid", ] +[[package]] +name = "spacetimedb-schema" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b03b34a38bd39f3f60a0687efafb942355bd9f6026b88a38c7c9ec904e944f1" +dependencies = [ + "anyhow", + "convert_case 0.6.0", + "derive_more 0.99.20", + "enum-as-inner", + "enum-map", + "indexmap 2.13.0", + "insta", + "itertools 0.12.1", + "lazy_static", + "lean_string", + "petgraph", + "serde_json", + "smallvec", + "spacetimedb-data-structures", + "spacetimedb-lib", + "spacetimedb-memory-usage", + "spacetimedb-primitives", + "spacetimedb-sats", + "spacetimedb-sql-parser", + "termcolor", + "thiserror 1.0.69", + "unicode-ident", + "unicode-normalization", +] + +[[package]] +name = "spacetimedb-sdk" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e7302851fec72929ffef976125f51971b0ec76be2730e27705a8e544f2ce159" +dependencies = [ + "anymap3", + "base64 0.21.7", + "brotli", + "bytes", + "flate2", + "futures", + "futures-channel", + "home", + "http 1.4.0", + "log", + "native-tls", + "once_cell", + "prometheus", + "rand 0.9.2", + "spacetimedb-client-api-messages", + "spacetimedb-data-structures", + "spacetimedb-lib", + "spacetimedb-metrics", + "spacetimedb-query-builder", + "spacetimedb-sats", + "spacetimedb-schema", + "thiserror 1.0.69", + "tokio", + "tokio-tungstenite 0.27.0", +] + +[[package]] +name = "spacetimedb-sql-parser" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7cbb9a837ac5f1ddb0cfb745159dea276dcf456244452f5a90684e5184f1f31" +dependencies = [ + "derive_more 0.99.20", + "spacetimedb-lib", + "sqlparser", + "thiserror 1.0.69", +] + [[package]] name = "spin" version = "0.9.8" @@ -7660,6 +8007,15 @@ dependencies = [ "der", ] +[[package]] +name = "sqlparser" +version = "0.38.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0272b7bb0a225320170c99901b4b5fb3a4384e255a7f2cc228f61e2ba3893e75" +dependencies = [ + "log", +] + [[package]] name = "stable_deref_trait" version = "1.2.1" @@ -7742,13 +8098,35 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "strum" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" +dependencies = [ + "strum_macros 0.25.3", +] + [[package]] name = "strum" version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" dependencies = [ - "strum_macros", + "strum_macros 0.27.2", +] + +[[package]] +name = "strum_macros" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.117", ] [[package]] @@ -8683,7 +9061,9 @@ checksum = "489a59b6730eda1b0171fcfda8b121f4bee2b35cba8645ca35c5f7ba3eb736c1" dependencies = [ "futures-util", "log", + "native-tls", "tokio", + "tokio-native-tls", "tungstenite 0.27.0", ] @@ -8721,7 +9101,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" dependencies = [ "serde", - "serde_spanned", + "serde_spanned 0.6.9", "toml_datetime 0.6.11", "toml_edit 0.22.27", ] @@ -8774,7 +9154,7 @@ checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ "indexmap 2.13.0", "serde", - "serde_spanned", + "serde_spanned 0.6.9", "toml_datetime 0.6.11", "toml_write", "winnow 0.7.15", @@ -8787,8 +9167,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16bff38f1d86c47f9ff0647e6838d7bb362522bdf44006c7068c2b1e606f1f3c" dependencies = [ "indexmap 2.13.0", + "serde_core", + "serde_spanned 1.1.1", "toml_datetime 1.1.0+spec-1.1.0", "toml_parser", + "toml_writer", "winnow 1.0.0", ] @@ -8807,6 +9190,12 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" +[[package]] +name = "toml_writer" +version = "1.1.1+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" + [[package]] name = "tower" version = "0.4.13" @@ -9125,6 +9514,7 @@ dependencies = [ "rustls 0.23.37", "sha1", "thiserror 2.0.18", + "url", "utf-8", ] @@ -9169,6 +9559,15 @@ version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" +[[package]] +name = "unicode-normalization" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fd4f6878c9cb28d874b009da9e8d183b5abc80117c40bbd187a1fde336be6e8" +dependencies = [ + "tinyvec", +] + [[package]] name = "unicode-segmentation" version = "1.13.1" diff --git a/Cargo.toml b/Cargo.toml index c9081f0..0bfc2ba 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,6 @@ members = [ "packages/marts", "packages/mize", "packages/ppc", - "packages/spacetime-module-ppc", + "packages/ppc/spacetimedb", ] resolver = "2" diff --git a/flake.lock b/flake.lock index 98576ee..52e10a6 100644 --- a/flake.lock +++ b/flake.lock @@ -72,11 +72,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1770115704, - "narHash": "sha256-KHFT9UWOF2yRPlAnSXQJh6uVcgNcWlFqqiAZ7OVlHNc=", + "lastModified": 1774709303, + "narHash": "sha256-D3Q07BbIA2KnTcSXIqqu9P586uWxN74zNoCH3h2ESHg=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "e6eae2ee2110f3d31110d5c222cd395303343b08", + "rev": "8110df5ad7abf5d4c0f6fb0f8f978390e77f9685", "type": "github" }, "original": { diff --git a/md b/md index 6e87f9f..1cef9ef 100755 --- a/md +++ b/md @@ -33,13 +33,16 @@ function deploy_lush { } function deploy_main_website { - echo "c2vi: Deploying website to ppc-hosting..." + echo "c2vi: Deploying website to fes" # compile - ssh ppc-hosting nix develop /root/host/ppc-src --impure -v -L -c sh -c "cargo build --release --manifest-path /root/host/ppc-src/packages/ppc/Cargo.toml" + cargo build --release --no-default-features --features server --manifest-path $MIZE_SRC/packages/ppc/Cargo.toml + + # upload + scp $MIZE_SRC/target/release/ppc fes:here # restart service - ssh ppc-hosting "sudo systemctl restart ppc" + ssh fe "sudo systemctl restart ppc" } function deploy_main_obsidian { diff --git a/packages/marts/c2vi/mod.rs b/packages/marts/c2vi/mod.rs index 1994000..ee88940 100644 --- a/packages/marts/c2vi/mod.rs +++ b/packages/marts/c2vi/mod.rs @@ -42,6 +42,13 @@ impl C2vi { } pub fn c2vi(mize: &mut Mize) -> MizeResult<()> { + #[cfg(feature = "client")] + c2vi_client(mize)?; + + Ok(()) +} + +pub fn c2vi_client(mize: &mut Mize) -> MizeResult<()> { //let storage_path = mize.get_config("c2vi.local_storage_path")?.as_ let storage_path = "/home/me/work/app-data/ppc"; println!("storage_path: {}", storage_path); diff --git a/packages/mize/src/core/instance/mod.rs b/packages/mize/src/core/instance/mod.rs index 1e7c9a8..f67a643 100644 --- a/packages/mize/src/core/instance/mod.rs +++ b/packages/mize/src/core/instance/mod.rs @@ -312,7 +312,7 @@ impl Mize { part: Some(part.take().unwrap()), mize: self.clone(), }), - None => Err(mize_err!("Part not found or currently taken")), + None => Err(mize_err!("Part '{name}' not found or currently taken")), } } pub fn has_part(&mut self, name: &str) -> bool { @@ -909,6 +909,7 @@ impl Mize { let part_names = self.part_names(); for part_name in part_names { let mut part = self.get_part(part_name)?; + //println!("running part {part_name}"); part.run(&mut self.clone())?; } let mut threads_inner = self.threads.lock().unwrap(); @@ -924,11 +925,8 @@ impl Mize { &mut self, name: &str, ) -> MizeResult> { - println!("Getting part native hiiiiiii"); let mut dyn_guard = self.get_part(name)?; - println!("Getting part native hiiiiiii two"); let part = dyn_guard.part.take().unwrap(); - println!("Getting part native hiiiiiii three"); drop(dyn_guard); let concrete_part = part.into_any().downcast::().unwrap(); Ok(MizePartGuard { diff --git a/packages/mize/src/core/item.rs b/packages/mize/src/core/item.rs index 6a5c077..c12fbf6 100644 --- a/packages/mize/src/core/item.rs +++ b/packages/mize/src/core/item.rs @@ -205,6 +205,13 @@ impl ItemData { return Ok(value.into_item_data()); } + pub fn to_toml(&self) -> MizeResult { + let mut out_string = String::new(); + let toml_serializer = toml::Serializer::new(&mut out_string); + CborValue::serialize(&self.cbor(), toml_serializer)?; + Ok(out_string) + } + pub fn value_string(self) -> MizeResult { match self.cbor() { CborValue::Text(string) => Ok(string.to_owned()), @@ -212,6 +219,13 @@ impl ItemData { } } + pub fn value_bool(self) -> MizeResult { + match self.cbor() { + CborValue::Bool(val) => Ok(*val), + _ => Err(mize_err!("this ItemData has no string value")), + } + } + pub fn from_string>(into_string: S) -> ItemData { let string = into_string.into(); let data = CborValue::Text(string); diff --git a/packages/ppc/Cargo.toml b/packages/ppc/Cargo.toml index ab4a42c..8edf469 100644 --- a/packages/ppc/Cargo.toml +++ b/packages/ppc/Cargo.toml @@ -33,6 +33,9 @@ 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 } +spacetimedb-sdk = "2.1.0" +flume = "0.12.0" +chrono = "0.4.44" [[bin]] name = "ppc" @@ -44,11 +47,13 @@ path = "lib.rs" name = "ppc" [features] -default = ["target-os", "desktop", "server"] +default = ["target-os", "server", "client"] target-os = [ "clap", "mize/target-os", "marts/target-os", "tracing", "webbrowser", "base64", "serde_json", "serde" ] 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/router", "dioxus-ssr", "html-escape", "axum-oidc", "tower", "tower-sessions", "marts/server", "target-os" ] desktop = ["dioxus/desktop", "marts/desktop", "target-os"] +client = [] +webbrowser = ["dep:webbrowser"] [package.metadata.wasm-pack.profile.release] diff --git a/packages/ppc/auth/client.rs b/packages/ppc/auth/client.rs index 55a9b68..92fb26e 100644 --- a/packages/ppc/auth/client.rs +++ b/packages/ppc/auth/client.rs @@ -3,10 +3,11 @@ use base64::{ alphabet::STANDARD, engine::{DecodePaddingMode, GeneralPurpose, GeneralPurposeConfig}, }; -use mize::{Mize, MizeError, MizePart, MizeResult, mize_err, mize_part}; +use mize::{Mize, MizeError, MizePart, MizeResult, item::ItemData, mize_err, mize_part}; use openidconnect::{ - AuthorizationCode, ClientId, CsrfToken, IssuerUrl, Nonce, OAuth2TokenResponse, - PkceCodeChallenge, PkceCodeVerifier, RedirectUrl, RefreshToken, Scope, + AuthorizationCode, ClientId, CsrfToken, DeviceAuthorizationResponse, + EmptyExtraDeviceAuthorizationFields, IssuerUrl, Nonce, OAuth2TokenResponse, PkceCodeChallenge, + PkceCodeVerifier, RedirectUrl, RefreshToken, Scope, core::{CoreAuthenticationFlow, CoreClient, CoreProviderMetadata}, }; use serde::{Deserialize, Serialize}; @@ -93,10 +94,8 @@ pub fn client_auth(mize: &mut Mize) -> MizeResult<()> { 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)?; + let mut auth = mize.get_part_native::("client_auth")?; auth.secrets = Some(secrets); Ok(()) }); @@ -127,6 +126,14 @@ fn write_secrets(mize: &mut Mize, secrets: &ClientSecrets) -> MizeResult<()> { let secrets_string = serde_json::to_string(secrets)?; std::fs::write(secrets_file_path, secrets_string)?; + // update the spacetimedb_token in XDG_CONFIG_HOME/spacetime/cli.toml config file if configured to do so + if mize + .get_config("auth.client.update_spacetime_token")? + .value_bool()? + { + update_spacetimedb_token(&secrets.id_token.as_str())?; + } + Ok(()) } @@ -136,121 +143,150 @@ struct Combined<'a> { state: &'a str, } +use openidconnect::reqwest::Client as HttpClient; +use openidconnect::{AuthUrl, DeviceAuthorizationUrl}; +use std::time::Duration; +use tokio::time::sleep; + async fn auth_flow(mut mize: Mize) -> MizeResult { // ===== CONFIG ===== - // Replace these with your issuer, client id and the public redirect URL served by the axum app. - let issuer = mize.get_config("auth.client.issuer")?.value_string()?; let client_id = mize.get_config("auth.client.client_id")?.value_string()?; - let redirect_url = mize - .get_config("auth.client.redirect_url")? - .value_string()?; let issuer = IssuerUrl::new(issuer)?; let client_id = ClientId::new(client_id); - let redirect_uri = RedirectUrl::new(redirect_url)?; + + let http_client = HttpClient::new(); + + // Teach openidconnect-rs about the device authorization url. + #[derive(Clone, Debug, Deserialize, Serialize)] + struct MyExtraProviderMetadata { + device_authorization_endpoint: String, + } + use openidconnect::AdditionalProviderMetadata; + use openidconnect::ProviderMetadata; + use openidconnect::core::{ + CoreAuthDisplay, CoreClaimName, CoreClaimType, CoreClient, CoreClientAuthMethod, + CoreDeviceAuthorizationResponse, CoreGrantType, CoreJsonWebKey, CoreJsonWebKeyType, + CoreJsonWebKeyUse, CoreJweContentEncryptionAlgorithm, CoreJweKeyManagementAlgorithm, + CoreJwsSigningAlgorithm, CoreResponseMode, CoreResponseType, CoreSubjectIdentifierType, + }; + impl AdditionalProviderMetadata for MyExtraProviderMetadata {} + type MyProviderMetadata = ProviderMetadata< + MyExtraProviderMetadata, + CoreAuthDisplay, + CoreClientAuthMethod, + CoreClaimName, + CoreClaimType, + CoreGrantType, + CoreJweContentEncryptionAlgorithm, + CoreJweKeyManagementAlgorithm, + CoreJsonWebKey, + CoreResponseMode, + CoreResponseType, + CoreSubjectIdentifierType, + >; // Discover provider metadata - let provider_metadata = - CoreProviderMetadata::discover_async(issuer, &openidconnect::reqwest::Client::new()) - .await?; + let provider_metadata: MyProviderMetadata = + MyProviderMetadata::discover_async(issuer, &http_client).await?; + + let device_auth_url = provider_metadata + .additional_metadata() + .device_authorization_endpoint + .clone(); let client = CoreClient::from_provider_metadata( provider_metadata, client_id, - None, // no client secret for public clients + None, // public client ) - .set_redirect_uri(redirect_uri); + .set_device_authorization_url(DeviceAuthorizationUrl::new(device_auth_url)?); - // ===== PKCE + state + nonce ===== - let (pkce_challenge, pkce_verifier) = PkceCodeChallenge::new_random_sha256(); - let csrf_token = CsrfToken::new_random(); - let csrf_token_clone = csrf_token.clone(); - let nonce = Nonce::new_random(); + // ===== DEVICE AUTH REQUEST ===== + let details: Result, _> = + client + .exchange_device_code() + .add_scope(Scope::new("openid".into())) + .add_scope(Scope::new("profile".into())) + .add_scope(Scope::new("offline_access".into())) + .request_async(&http_client) + .await; - // Build the authorization URL - include code_challenge and state - let (auth_url, _csrf_token_returned, _nonce_returned) = client - .authorize_url( - CoreAuthenticationFlow::AuthorizationCode, - move || csrf_token_clone.clone(), - move || nonce.clone(), - ) - .set_pkce_challenge(pkce_challenge) - .add_scope(Scope::new("openid".to_string())) - .add_scope(Scope::new("profile".to_string())) - .url(); + let details = match details { + Ok(val) => val, + Err(err) => { + println!("err: {:?}", err); + println!("err: {}", err); + panic!(); + } + }; - println!("Opening browser to authenticate..."); println!( - "If your browser does not open automatically, visit:\n\n{}\n", - auth_url + "If your browser does not open automatically, open this URL in it:\n{}\n", + details.verification_uri_complete().unwrap().secret() + ); + println!( + "Or enter this PPC login code:\n{}\n", + details.user_code().secret() ); #[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); + if let Some(uri_complete) = details.verification_uri_complete() { + let _ = webbrowser::open(details.verification_uri_complete().unwrap().secret()); } } - #[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)."); - print!("Paste login string here: "); - io::stdout().flush()?; - - // Read user input - let mut input = String::new(); - io::stdin().read_line(&mut input)?; - let input = input.trim(); - - if input.is_empty() { - return Err(mize_err!("No login string provided")); - } - - let base64_engine = GeneralPurpose::new( - &STANDARD, - GeneralPurposeConfig::new().with_decode_padding_mode(DecodePaddingMode::RequireNone), - ); - - let json_bytes = base64_engine.decode(input)?; - let json_str = String::from_utf8(json_bytes)?; - let combined: Combined = serde_json::from_str(json_str.as_str())?; - - if combined.state != csrf_token.secret() { - return Err(mize_err!( - "State mismatch: pasted state does not match expected value" - )); - } else { - println!("State is valid"); - }; - - // Perform token exchange let token_response = client - .exchange_code(AuthorizationCode::new(combined.code.to_string()))? - .set_pkce_verifier(PkceCodeVerifier::new(pkce_verifier.secret().to_string())) - .request_async(&openidconnect::reqwest::Client::new()) + .exchange_device_access_token(&details)? + .request_async( + &http_client, + async |dur: Duration| { + tokio::time::sleep(dur); + }, + None, + ) .await?; + // ===== TOKENS ===== let id_token = token_response .extra_fields() .id_token() .ok_or(mize_err!("no id_token"))?; - //let refresh = token_response.refresh_token(); - - println!("\n=== Token response ==="); - println!("Access token: {:?}", token_response.access_token().secret()); - println!("ID token: {}", id_token.to_string()); - //println!("Refresh token: {}", refresh.secret()); + let refresh = token_response + .refresh_token() + .ok_or(mize_err!("no refresh token present"))?; Ok(ClientSecrets { id_token: id_token.to_string(), access_token: token_response.access_token().secret().to_string(), - refresh_token: "".to_string(), + refresh_token: refresh.secret().to_owned(), }) } + +fn update_spacetimedb_token(new_token: &str) -> MizeResult<()> { + // Resolve config directory + let config_dir = match std::env::var("XDG_CONFIG_HOME") { + Ok(val) => PathBuf::from(val), + Err(_) => { + let home = std::env::var("HOME")?; + std::path::PathBuf::from(home).join(".config") + } + }; + + let file_path = config_dir.join("spacetime").join("cli.toml"); + + // Read existing file (or create empty document if it doesn't exist) + let content = std::fs::read_to_string(&file_path).unwrap_or_default(); + let mut data = ItemData::from_toml(content.as_str())?; + + // Update the field + data.set_path("spacetimedb_token", new_token)?; + + // Write back + std::fs::write(&file_path, data.to_toml()?)?; + + Ok(()) +} diff --git a/packages/ppc/generated/activities_table.rs b/packages/ppc/generated/activities_table.rs new file mode 100644 index 0000000..82d823f --- /dev/null +++ b/packages/ppc/generated/activities_table.rs @@ -0,0 +1,159 @@ +// 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::activity_type::Activity; +use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; + +/// Table handle for the table `activities`. +/// +/// Obtain a handle from the [`ActivitiesTableAccess::activities`] method on [`super::RemoteTables`], +/// like `ctx.db.activities()`. +/// +/// Users are encouraged not to explicitly reference this type, +/// but to directly chain method calls, +/// like `ctx.db.activities().on_insert(...)`. +pub struct ActivitiesTableHandle<'ctx> { + imp: __sdk::TableHandle, + ctx: std::marker::PhantomData<&'ctx super::RemoteTables>, +} + +#[allow(non_camel_case_types)] +/// Extension trait for access to the table `activities`. +/// +/// Implemented for [`super::RemoteTables`]. +pub trait ActivitiesTableAccess { + #[allow(non_snake_case)] + /// Obtain a [`ActivitiesTableHandle`], which mediates access to the table `activities`. + fn activities(&self) -> ActivitiesTableHandle<'_>; +} + +impl ActivitiesTableAccess for super::RemoteTables { + fn activities(&self) -> ActivitiesTableHandle<'_> { + ActivitiesTableHandle { + imp: self.imp.get_table::("activities"), + ctx: std::marker::PhantomData, + } + } +} + +pub struct ActivitiesInsertCallbackId(__sdk::CallbackId); +pub struct ActivitiesDeleteCallbackId(__sdk::CallbackId); + +impl<'ctx> __sdk::Table for ActivitiesTableHandle<'ctx> { + type Row = Activity; + type EventContext = super::EventContext; + + fn count(&self) -> u64 { + self.imp.count() + } + fn iter(&self) -> impl Iterator + '_ { + self.imp.iter() + } + + type InsertCallbackId = ActivitiesInsertCallbackId; + + fn on_insert( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, + ) -> ActivitiesInsertCallbackId { + ActivitiesInsertCallbackId(self.imp.on_insert(Box::new(callback))) + } + + fn remove_on_insert(&self, callback: ActivitiesInsertCallbackId) { + self.imp.remove_on_insert(callback.0) + } + + type DeleteCallbackId = ActivitiesDeleteCallbackId; + + fn on_delete( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, + ) -> ActivitiesDeleteCallbackId { + ActivitiesDeleteCallbackId(self.imp.on_delete(Box::new(callback))) + } + + fn remove_on_delete(&self, callback: ActivitiesDeleteCallbackId) { + self.imp.remove_on_delete(callback.0) + } +} + +pub struct ActivitiesUpdateCallbackId(__sdk::CallbackId); + +impl<'ctx> __sdk::TableWithPrimaryKey for ActivitiesTableHandle<'ctx> { + type UpdateCallbackId = ActivitiesUpdateCallbackId; + + fn on_update( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static, + ) -> ActivitiesUpdateCallbackId { + ActivitiesUpdateCallbackId(self.imp.on_update(Box::new(callback))) + } + + fn remove_on_update(&self, callback: ActivitiesUpdateCallbackId) { + self.imp.remove_on_update(callback.0) + } +} + +/// Access to the `id` unique index on the table `activities`, +/// which allows point queries on the field of the same name +/// via the [`ActivitiesIdUnique::find`] method. +/// +/// Users are encouraged not to explicitly reference this type, +/// but to directly chain method calls, +/// like `ctx.db.activities().id().find(...)`. +pub struct ActivitiesIdUnique<'ctx> { + imp: __sdk::UniqueConstraintHandle, + phantom: std::marker::PhantomData<&'ctx super::RemoteTables>, +} + +impl<'ctx> ActivitiesTableHandle<'ctx> { + /// Get a handle on the `id` unique index on the table `activities`. + pub fn id(&self) -> ActivitiesIdUnique<'ctx> { + ActivitiesIdUnique { + imp: self.imp.get_unique_constraint::("id"), + phantom: std::marker::PhantomData, + } + } +} + +impl<'ctx> ActivitiesIdUnique<'ctx> { + /// Find the subscribed row whose `id` column value is equal to `col_val`, + /// if such a row is present in the client cache. + pub fn find(&self, col_val: &u64) -> Option { + self.imp.find(col_val) + } +} + +#[doc(hidden)] +pub(super) fn register_table(client_cache: &mut __sdk::ClientCache) { + let _table = client_cache.get_or_make_table::("activities"); + _table.add_unique_constraint::("id", |row| &row.id); +} + +#[doc(hidden)] +pub(super) fn parse_table_update( + raw_updates: __ws::v2::TableUpdate, +) -> __sdk::Result<__sdk::TableUpdate> { + __sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| { + __sdk::InternalError::failed_parse("TableUpdate", "TableUpdate") + .with_cause(e) + .into() + }) +} + +#[allow(non_camel_case_types)] +/// Extension trait for query builder access to the table `Activity`. +/// +/// Implemented for [`__sdk::QueryTableAccessor`]. +pub trait activitiesQueryTableAccess { + #[allow(non_snake_case)] + /// Get a query builder for the table `Activity`. + fn activities(&self) -> __sdk::__query_builder::Table; +} + +impl activitiesQueryTableAccess for __sdk::QueryTableAccessor { + fn activities(&self) -> __sdk::__query_builder::Table { + __sdk::__query_builder::Table::new("activities") + } +} diff --git a/packages/ppc/generated/activity_type.rs b/packages/ppc/generated/activity_type.rs new file mode 100644 index 0000000..f9c162d --- /dev/null +++ b/packages/ppc/generated/activity_type.rs @@ -0,0 +1,58 @@ +// 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 Activity { + pub id: u64, + pub name: String, + pub task: Option, + pub parents_ids: Vec, +} + +impl __sdk::InModule for Activity { + type Module = super::RemoteModule; +} + +/// Column accessor struct for the table `Activity`. +/// +/// Provides typed access to columns for query building. +pub struct ActivityCols { + pub id: __sdk::__query_builder::Col, + pub name: __sdk::__query_builder::Col, + pub task: __sdk::__query_builder::Col>, + pub parents_ids: __sdk::__query_builder::Col>, +} + +impl __sdk::__query_builder::HasCols for Activity { + type Cols = ActivityCols; + fn cols(table_name: &'static str) -> Self::Cols { + ActivityCols { + id: __sdk::__query_builder::Col::new(table_name, "id"), + name: __sdk::__query_builder::Col::new(table_name, "name"), + task: __sdk::__query_builder::Col::new(table_name, "task"), + parents_ids: __sdk::__query_builder::Col::new(table_name, "parents_ids"), + } + } +} + +/// Indexed column accessor struct for the table `Activity`. +/// +/// Provides typed access to indexed columns for query building. +pub struct ActivityIxCols { + pub id: __sdk::__query_builder::IxCol, +} + +impl __sdk::__query_builder::HasIxCols for Activity { + type IxCols = ActivityIxCols; + fn ix_cols(table_name: &'static str) -> Self::IxCols { + ActivityIxCols { + id: __sdk::__query_builder::IxCol::new(table_name, "id"), + } + } +} + +impl __sdk::__query_builder::CanBeLookupTable for Activity {} diff --git a/packages/ppc/generated/add_activity_reducer.rs b/packages/ppc/generated/add_activity_reducer.rs new file mode 100644 index 0000000..d04a765 --- /dev/null +++ b/packages/ppc/generated/add_activity_reducer.rs @@ -0,0 +1,66 @@ +// 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 AddActivityArgs { + pub name: String, +} + +impl From for super::Reducer { + fn from(args: AddActivityArgs) -> Self { + Self::AddActivity { name: args.name } + } +} + +impl __sdk::InModule for AddActivityArgs { + type Module = super::RemoteModule; +} + +#[allow(non_camel_case_types)] +/// Extension trait for access to the reducer `add_activity`. +/// +/// Implemented for [`super::RemoteReducers`]. +pub trait add_activity { + /// Request that the remote module invoke the reducer `add_activity` 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 this method provides no way to listen for its completion status. + /// /// Use [`add_activity:add_activity_then`] to run a callback after the reducer completes. + fn add_activity(&self, name: String) -> __sdk::Result<()> { + self.add_activity_then(name, |_, _| {}) + } + + /// Request that the remote module invoke the reducer `add_activity` to run as soon as possible, + /// registering `callback` to run when we are notified that the reducer completed. + /// + /// 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 with the `callback`. + fn add_activity_then( + &self, + name: String, + + callback: impl FnOnce(&super::ReducerEventContext, Result, __sdk::InternalError>) + + Send + + 'static, + ) -> __sdk::Result<()>; +} + +impl add_activity for super::RemoteReducers { + fn add_activity_then( + &self, + name: String, + + callback: impl FnOnce(&super::ReducerEventContext, Result, __sdk::InternalError>) + + Send + + 'static, + ) -> __sdk::Result<()> { + self.imp + .invoke_reducer_with_callback(AddActivityArgs { name }, callback) + } +} diff --git a/packages/ppc/generated/event_type.rs b/packages/ppc/generated/event_type.rs new file mode 100644 index 0000000..8f30d8b --- /dev/null +++ b/packages/ppc/generated/event_type.rs @@ -0,0 +1,53 @@ +// 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}; + +use super::activity_type::Activity; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub struct Event { + pub start: __sdk::Timestamp, + pub end: __sdk::Timestamp, + pub activity: Activity, +} + +impl __sdk::InModule for Event { + type Module = super::RemoteModule; +} + +/// Column accessor struct for the table `Event`. +/// +/// Provides typed access to columns for query building. +pub struct EventCols { + pub start: __sdk::__query_builder::Col, + pub end: __sdk::__query_builder::Col, + pub activity: __sdk::__query_builder::Col, +} + +impl __sdk::__query_builder::HasCols for Event { + type Cols = EventCols; + fn cols(table_name: &'static str) -> Self::Cols { + EventCols { + start: __sdk::__query_builder::Col::new(table_name, "start"), + end: __sdk::__query_builder::Col::new(table_name, "end"), + activity: __sdk::__query_builder::Col::new(table_name, "activity"), + } + } +} + +/// Indexed column accessor struct for the table `Event`. +/// +/// Provides typed access to indexed columns for query building. +pub struct EventIxCols {} + +impl __sdk::__query_builder::HasIxCols for Event { + type IxCols = EventIxCols; + fn ix_cols(table_name: &'static str) -> Self::IxCols { + EventIxCols {} + } +} + +impl __sdk::__query_builder::CanBeLookupTable for Event {} diff --git a/packages/ppc/generated/events_table.rs b/packages/ppc/generated/events_table.rs new file mode 100644 index 0000000..82589a9 --- /dev/null +++ b/packages/ppc/generated/events_table.rs @@ -0,0 +1,112 @@ +// 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::activity_type::Activity; +use super::event_type::Event; +use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; + +/// Table handle for the table `events`. +/// +/// Obtain a handle from the [`EventsTableAccess::events`] method on [`super::RemoteTables`], +/// like `ctx.db.events()`. +/// +/// Users are encouraged not to explicitly reference this type, +/// but to directly chain method calls, +/// like `ctx.db.events().on_insert(...)`. +pub struct EventsTableHandle<'ctx> { + imp: __sdk::TableHandle, + ctx: std::marker::PhantomData<&'ctx super::RemoteTables>, +} + +#[allow(non_camel_case_types)] +/// Extension trait for access to the table `events`. +/// +/// Implemented for [`super::RemoteTables`]. +pub trait EventsTableAccess { + #[allow(non_snake_case)] + /// Obtain a [`EventsTableHandle`], which mediates access to the table `events`. + fn events(&self) -> EventsTableHandle<'_>; +} + +impl EventsTableAccess for super::RemoteTables { + fn events(&self) -> EventsTableHandle<'_> { + EventsTableHandle { + imp: self.imp.get_table::("events"), + ctx: std::marker::PhantomData, + } + } +} + +pub struct EventsInsertCallbackId(__sdk::CallbackId); +pub struct EventsDeleteCallbackId(__sdk::CallbackId); + +impl<'ctx> __sdk::Table for EventsTableHandle<'ctx> { + type Row = Event; + type EventContext = super::EventContext; + + fn count(&self) -> u64 { + self.imp.count() + } + fn iter(&self) -> impl Iterator + '_ { + self.imp.iter() + } + + type InsertCallbackId = EventsInsertCallbackId; + + fn on_insert( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, + ) -> EventsInsertCallbackId { + EventsInsertCallbackId(self.imp.on_insert(Box::new(callback))) + } + + fn remove_on_insert(&self, callback: EventsInsertCallbackId) { + self.imp.remove_on_insert(callback.0) + } + + type DeleteCallbackId = EventsDeleteCallbackId; + + fn on_delete( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, + ) -> EventsDeleteCallbackId { + EventsDeleteCallbackId(self.imp.on_delete(Box::new(callback))) + } + + fn remove_on_delete(&self, callback: EventsDeleteCallbackId) { + 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::("events"); +} + +#[doc(hidden)] +pub(super) fn parse_table_update( + raw_updates: __ws::v2::TableUpdate, +) -> __sdk::Result<__sdk::TableUpdate> { + __sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| { + __sdk::InternalError::failed_parse("TableUpdate", "TableUpdate") + .with_cause(e) + .into() + }) +} + +#[allow(non_camel_case_types)] +/// Extension trait for query builder access to the table `Event`. +/// +/// Implemented for [`__sdk::QueryTableAccessor`]. +pub trait eventsQueryTableAccess { + #[allow(non_snake_case)] + /// Get a query builder for the table `Event`. + fn events(&self) -> __sdk::__query_builder::Table; +} + +impl eventsQueryTableAccess for __sdk::QueryTableAccessor { + fn events(&self) -> __sdk::__query_builder::Table { + __sdk::__query_builder::Table::new("events") + } +} diff --git a/packages/spacetime-module-ppc/bindings/mod.rs b/packages/ppc/generated/mod.rs similarity index 73% rename from packages/spacetime-module-ppc/bindings/mod.rs rename to packages/ppc/generated/mod.rs index b55ceaf..b4f0124 100644 --- a/packages/spacetime-module-ppc/bindings/mod.rs +++ b/packages/ppc/generated/mod.rs @@ -1,28 +1,40 @@ // 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). +// This was generated using spacetimedb cli version 2.1.0 (commit refs/tags/v2.1.0). #![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 mod activities_table; +pub mod activity_type; +pub mod add_activity_reducer; +pub mod event_type; +pub mod events_table; +pub mod profile_type; +pub mod profiles_table; +pub mod remove_activity_reducer; +pub mod set_activity_name_reducer; +pub mod task_part_table; +pub mod task_part_type; +pub mod task_type; +pub mod tasks_table; +pub mod update_activity_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}; +pub use activities_table::*; +pub use activity_type::Activity; +pub use add_activity_reducer::add_activity; +pub use event_type::Event; +pub use events_table::*; +pub use profile_type::Profile; +pub use profiles_table::*; +pub use remove_activity_reducer::remove_activity; +pub use set_activity_name_reducer::set_activity_name; +pub use task_part_table::*; +pub use task_part_type::TaskPart; +pub use task_type::Task; +pub use tasks_table::*; +pub use update_activity_reducer::update_activity; #[derive(Clone, PartialEq, Debug)] @@ -32,10 +44,10 @@ pub use say_hello_reducer::{say_hello, set_flags_for_say_hello, SayHelloCallback /// to indicate which reducer caused the event. pub enum Reducer { - Add { username: String }, - IdentityConnected, - IdentityDisconnected, - SayHello, + AddActivity { name: String }, + RemoveActivity { activity: Activity }, + SetActivityName { id: u64, name: String }, + UpdateActivity { activity: Activity }, } impl __sdk::InModule for Reducer { @@ -45,62 +57,72 @@ impl __sdk::InModule for Reducer { 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", + Reducer::AddActivity { .. } => "add_activity", + Reducer::RemoveActivity { .. } => "remove_activity", + Reducer::SetActivityName { .. } => "set_activity_name", + Reducer::UpdateActivity { .. } => "update_activity", + _ => unreachable!(), + } + } + #[allow(clippy::clone_on_copy)] + fn args_bsatn(&self) -> Result, __sats::bsatn::EncodeError> { + match self { + Reducer::AddActivity { name } => { + __sats::bsatn::to_vec(&add_activity_reducer::AddActivityArgs { name: name.clone() }) + } + Reducer::RemoveActivity { activity } => { + __sats::bsatn::to_vec(&remove_activity_reducer::RemoveActivityArgs { + activity: activity.clone(), + }) + } + Reducer::SetActivityName { id, name } => { + __sats::bsatn::to_vec(&set_activity_name_reducer::SetActivityNameArgs { + id: id.clone(), + name: name.clone(), + }) + } + Reducer::UpdateActivity { activity } => { + __sats::bsatn::to_vec(&update_activity_reducer::UpdateActivityArgs { + activity: activity.clone(), + }) + } _ => 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)] +#[derive(Default, Debug)] #[allow(non_snake_case)] #[doc(hidden)] pub struct DbUpdate { - person: __sdk::TableUpdate, + activities: __sdk::TableUpdate, + events: __sdk::TableUpdate, + profiles: __sdk::TableUpdate, + task_part: __sdk::TableUpdate, + tasks: __sdk::TableUpdate, } -impl TryFrom<__ws::DatabaseUpdate<__ws::BsatnFormat>> for DbUpdate { +impl TryFrom<__ws::v2::TransactionUpdate> for DbUpdate { type Error = __sdk::Error; - fn try_from(raw: __ws::DatabaseUpdate<__ws::BsatnFormat>) -> Result { + fn try_from(raw: __ws::v2::TransactionUpdate) -> Result { let mut db_update = DbUpdate::default(); - for table_update in raw.tables { + for table_update in __sdk::transaction_update_iter_table_updates(raw) { match &table_update.table_name[..] { - "person" => db_update - .person - .append(person_table::parse_table_update(table_update)?), + "activities" => db_update + .activities + .append(activities_table::parse_table_update(table_update)?), + "events" => db_update + .events + .append(events_table::parse_table_update(table_update)?), + "profiles" => db_update + .profiles + .append(profiles_table::parse_table_update(table_update)?), + "task_part" => db_update + .task_part + .append(task_part_table::parse_table_update(table_update)?), + "tasks" => db_update + .tasks + .append(tasks_table::parse_table_update(table_update)?), unknown => { return Err(__sdk::InternalError::unknown_name( @@ -127,17 +149,89 @@ impl __sdk::DbUpdate for DbUpdate { ) -> AppliedDiff<'_> { let mut diff = AppliedDiff::default(); - diff.person = cache.apply_diff_to_table::("person", &self.person); + diff.activities = cache + .apply_diff_to_table::("activities", &self.activities) + .with_updates_by_pk(|row| &row.id); + diff.events = cache.apply_diff_to_table::("events", &self.events); + diff.profiles = cache + .apply_diff_to_table::("profiles", &self.profiles) + .with_updates_by_pk(|row| &row.identity); + diff.task_part = cache + .apply_diff_to_table::("task_part", &self.task_part) + .with_updates_by_pk(|row| &row.identity); + diff.tasks = cache + .apply_diff_to_table::("tasks", &self.tasks) + .with_updates_by_pk(|row| &row.id); diff } + fn parse_initial_rows(raw: __ws::v2::QueryRows) -> __sdk::Result { + let mut db_update = DbUpdate::default(); + for table_rows in raw.tables { + match &table_rows.table[..] { + "activities" => db_update + .activities + .append(__sdk::parse_row_list_as_inserts(table_rows.rows)?), + "events" => db_update + .events + .append(__sdk::parse_row_list_as_inserts(table_rows.rows)?), + "profiles" => db_update + .profiles + .append(__sdk::parse_row_list_as_inserts(table_rows.rows)?), + "task_part" => db_update + .task_part + .append(__sdk::parse_row_list_as_inserts(table_rows.rows)?), + "tasks" => db_update + .tasks + .append(__sdk::parse_row_list_as_inserts(table_rows.rows)?), + unknown => { + return Err( + __sdk::InternalError::unknown_name("table", unknown, "QueryRows").into(), + ); + } + } + } + Ok(db_update) + } + fn parse_unsubscribe_rows(raw: __ws::v2::QueryRows) -> __sdk::Result { + let mut db_update = DbUpdate::default(); + for table_rows in raw.tables { + match &table_rows.table[..] { + "activities" => db_update + .activities + .append(__sdk::parse_row_list_as_deletes(table_rows.rows)?), + "events" => db_update + .events + .append(__sdk::parse_row_list_as_deletes(table_rows.rows)?), + "profiles" => db_update + .profiles + .append(__sdk::parse_row_list_as_deletes(table_rows.rows)?), + "task_part" => db_update + .task_part + .append(__sdk::parse_row_list_as_deletes(table_rows.rows)?), + "tasks" => db_update + .tasks + .append(__sdk::parse_row_list_as_deletes(table_rows.rows)?), + unknown => { + return Err( + __sdk::InternalError::unknown_name("table", unknown, "QueryRows").into(), + ); + } + } + } + Ok(db_update) + } } #[derive(Default)] #[allow(non_snake_case)] #[doc(hidden)] pub struct AppliedDiff<'r> { - person: __sdk::TableAppliedDiff<'r, Person>, + activities: __sdk::TableAppliedDiff<'r, Activity>, + events: __sdk::TableAppliedDiff<'r, Event>, + profiles: __sdk::TableAppliedDiff<'r, Profile>, + task_part: __sdk::TableAppliedDiff<'r, TaskPart>, + tasks: __sdk::TableAppliedDiff<'r, Task>, __unused: std::marker::PhantomData<&'r ()>, } @@ -151,11 +245,16 @@ impl<'r> __sdk::AppliedDiff<'r> for AppliedDiff<'r> { event: &EventContext, callbacks: &mut __sdk::DbCallbacks, ) { - callbacks.invoke_table_row_callbacks::("person", &self.person, event); + callbacks.invoke_table_row_callbacks::("activities", &self.activities, event); + callbacks.invoke_table_row_callbacks::("events", &self.events, event); + callbacks.invoke_table_row_callbacks::("profiles", &self.profiles, event); + callbacks.invoke_table_row_callbacks::("task_part", &self.task_part, event); + callbacks.invoke_table_row_callbacks::("tasks", &self.tasks, event); } } #[doc(hidden)] +#[derive(Debug)] pub struct RemoteModule; impl __sdk::InModule for RemoteModule { @@ -182,20 +281,6 @@ 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 { @@ -214,10 +299,17 @@ impl __sdk::InModule for RemoteTables { /// You must explicitly advance the connection by calling any one of: /// /// - [`DbConnection::frame_tick`]. -/// - [`DbConnection::run_threaded`]. +#[cfg_attr(not(target_arch = "wasm32"), doc = "- [`DbConnection::run_threaded`].")] +#[cfg_attr( + target_arch = "wasm32", + doc = "- [`DbConnection::run_background_task`]." +)] /// - [`DbConnection::run_async`]. /// - [`DbConnection::advance_one_message`]. -/// - [`DbConnection::advance_one_message_blocking`]. +#[cfg_attr( + not(target_arch = "wasm32"), + doc = "- [`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, @@ -228,11 +320,6 @@ pub struct DbConnection { /// 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, @@ -248,7 +335,6 @@ impl __sdk::DbContext for DbConnection { type DbView = RemoteTables; type Reducers = RemoteReducers; type Procedures = RemoteProcedures; - type SetReducerFlags = SetReducerFlags; fn db(&self) -> &Self::DbView { &self.db @@ -259,9 +345,6 @@ impl __sdk::DbContext for DbConnection { 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() @@ -324,6 +407,7 @@ impl DbConnection { /// 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. + #[cfg(not(target_arch = "wasm32"))] pub fn advance_one_message_blocking(&self) -> __sdk::Result<()> { self.imp.advance_one_message_blocking() } @@ -349,10 +433,17 @@ impl DbConnection { } /// Spawn a thread which processes WebSocket messages as they are received. + #[cfg(not(target_arch = "wasm32"))] pub fn run_threaded(&self) -> std::thread::JoinHandle<()> { self.imp.run_threaded() } + /// Spawn a background task which processes WebSocket messages as they are received. + #[cfg(target_arch = "wasm32")] + pub fn run_background_task(&self) { + self.imp.run_background_task() + } + /// Run an `async` loop which processes WebSocket messages when polled. pub async fn run_async(&self) -> __sdk::Result<()> { self.imp.run_async().await @@ -365,7 +456,6 @@ impl __sdk::DbConnection for DbConnection { db: RemoteTables { imp: imp.clone() }, reducers: RemoteReducers { imp: imp.clone() }, procedures: RemoteProcedures { imp: imp.clone() }, - set_reducer_flags: SetReducerFlags { imp: imp.clone() }, imp, } } @@ -417,7 +507,6 @@ pub trait RemoteDbContext: __sdk::DbContext< DbView = RemoteTables, Reducers = RemoteReducers, - SetReducerFlags = SetReducerFlags, SubscriptionBuilder = __sdk::SubscriptionBuilder, > { @@ -426,7 +515,6 @@ impl< Ctx: __sdk::DbContext< DbView = RemoteTables, Reducers = RemoteReducers, - SetReducerFlags = SetReducerFlags, SubscriptionBuilder = __sdk::SubscriptionBuilder, >, > RemoteDbContext for Ctx @@ -440,11 +528,6 @@ pub struct EventContext { 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. @@ -461,7 +544,6 @@ impl __sdk::AbstractEventContext for EventContext { 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, @@ -477,7 +559,6 @@ impl __sdk::DbContext for EventContext { type DbView = RemoteTables; type Reducers = RemoteReducers; type Procedures = RemoteProcedures; - type SetReducerFlags = SetReducerFlags; fn db(&self) -> &Self::DbView { &self.db @@ -488,9 +569,6 @@ impl __sdk::DbContext for EventContext { 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() @@ -526,11 +604,6 @@ pub struct ReducerEventContext { 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. @@ -547,7 +620,6 @@ impl __sdk::AbstractEventContext for ReducerEventContext { 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, @@ -563,7 +635,6 @@ impl __sdk::DbContext for ReducerEventContext { type DbView = RemoteTables; type Reducers = RemoteReducers; type Procedures = RemoteProcedures; - type SetReducerFlags = SetReducerFlags; fn db(&self) -> &Self::DbView { &self.db @@ -574,9 +645,6 @@ impl __sdk::DbContext for ReducerEventContext { 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() @@ -611,11 +679,6 @@ pub struct ProcedureEventContext { 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, @@ -631,7 +694,6 @@ impl __sdk::AbstractEventContext for ProcedureEventContext { db: RemoteTables { imp: imp.clone() }, reducers: RemoteReducers { imp: imp.clone() }, procedures: RemoteProcedures { imp: imp.clone() }, - set_reducer_flags: SetReducerFlags { imp: imp.clone() }, imp, } } @@ -645,7 +707,6 @@ impl __sdk::DbContext for ProcedureEventContext { type DbView = RemoteTables; type Reducers = RemoteReducers; type Procedures = RemoteProcedures; - type SetReducerFlags = SetReducerFlags; fn db(&self) -> &Self::DbView { &self.db @@ -656,9 +717,6 @@ impl __sdk::DbContext for ProcedureEventContext { 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() @@ -693,11 +751,6 @@ pub struct SubscriptionEventContext { 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, @@ -713,7 +766,6 @@ impl __sdk::AbstractEventContext for SubscriptionEventContext { db: RemoteTables { imp: imp.clone() }, reducers: RemoteReducers { imp: imp.clone() }, procedures: RemoteProcedures { imp: imp.clone() }, - set_reducer_flags: SetReducerFlags { imp: imp.clone() }, imp, } } @@ -727,7 +779,6 @@ impl __sdk::DbContext for SubscriptionEventContext { type DbView = RemoteTables; type Reducers = RemoteReducers; type Procedures = RemoteProcedures; - type SetReducerFlags = SetReducerFlags; fn db(&self) -> &Self::DbView { &self.db @@ -738,9 +789,6 @@ impl __sdk::DbContext for SubscriptionEventContext { 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() @@ -776,11 +824,6 @@ pub struct ErrorContext { 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. @@ -797,7 +840,6 @@ impl __sdk::AbstractEventContext for ErrorContext { 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, @@ -813,7 +855,6 @@ impl __sdk::DbContext for ErrorContext { type DbView = RemoteTables; type Reducers = RemoteReducers; type Procedures = RemoteProcedures; - type SetReducerFlags = SetReducerFlags; fn db(&self) -> &Self::DbView { &self.db @@ -824,9 +865,6 @@ impl __sdk::DbContext for ErrorContext { 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() @@ -865,12 +903,19 @@ impl __sdk::SpacetimeModule for RemoteModule { type Reducer = Reducer; type DbView = RemoteTables; type Reducers = RemoteReducers; - type SetReducerFlags = SetReducerFlags; + type Procedures = RemoteProcedures; type DbUpdate = DbUpdate; type AppliedDiff<'r> = AppliedDiff<'r>; type SubscriptionHandle = SubscriptionHandle; + type QueryBuilder = __sdk::QueryBuilder; fn register_tables(client_cache: &mut __sdk::ClientCache) { - person_table::register_table(client_cache); + activities_table::register_table(client_cache); + events_table::register_table(client_cache); + profiles_table::register_table(client_cache); + task_part_table::register_table(client_cache); + tasks_table::register_table(client_cache); } + const ALL_TABLE_NAMES: &'static [&'static str] = + &["activities", "events", "profiles", "task_part", "tasks"]; } diff --git a/packages/ppc/generated/profile_type.rs b/packages/ppc/generated/profile_type.rs new file mode 100644 index 0000000..c6d2fba --- /dev/null +++ b/packages/ppc/generated/profile_type.rs @@ -0,0 +1,54 @@ +// 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 Profile { + pub identity: __sdk::Identity, + pub username: String, +} + +impl __sdk::InModule for Profile { + type Module = super::RemoteModule; +} + +/// Column accessor struct for the table `Profile`. +/// +/// Provides typed access to columns for query building. +pub struct ProfileCols { + pub identity: __sdk::__query_builder::Col, + pub username: __sdk::__query_builder::Col, +} + +impl __sdk::__query_builder::HasCols for Profile { + type Cols = ProfileCols; + fn cols(table_name: &'static str) -> Self::Cols { + ProfileCols { + identity: __sdk::__query_builder::Col::new(table_name, "identity"), + username: __sdk::__query_builder::Col::new(table_name, "username"), + } + } +} + +/// Indexed column accessor struct for the table `Profile`. +/// +/// Provides typed access to indexed columns for query building. +pub struct ProfileIxCols { + pub identity: __sdk::__query_builder::IxCol, + pub username: __sdk::__query_builder::IxCol, +} + +impl __sdk::__query_builder::HasIxCols for Profile { + type IxCols = ProfileIxCols; + fn ix_cols(table_name: &'static str) -> Self::IxCols { + ProfileIxCols { + identity: __sdk::__query_builder::IxCol::new(table_name, "identity"), + username: __sdk::__query_builder::IxCol::new(table_name, "username"), + } + } +} + +impl __sdk::__query_builder::CanBeLookupTable for Profile {} diff --git a/packages/ppc/generated/profiles_table.rs b/packages/ppc/generated/profiles_table.rs new file mode 100644 index 0000000..1f46b98 --- /dev/null +++ b/packages/ppc/generated/profiles_table.rs @@ -0,0 +1,192 @@ +// 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::profile_type::Profile; +use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; + +/// Table handle for the table `profiles`. +/// +/// Obtain a handle from the [`ProfilesTableAccess::profiles`] method on [`super::RemoteTables`], +/// like `ctx.db.profiles()`. +/// +/// Users are encouraged not to explicitly reference this type, +/// but to directly chain method calls, +/// like `ctx.db.profiles().on_insert(...)`. +pub struct ProfilesTableHandle<'ctx> { + imp: __sdk::TableHandle, + ctx: std::marker::PhantomData<&'ctx super::RemoteTables>, +} + +#[allow(non_camel_case_types)] +/// Extension trait for access to the table `profiles`. +/// +/// Implemented for [`super::RemoteTables`]. +pub trait ProfilesTableAccess { + #[allow(non_snake_case)] + /// Obtain a [`ProfilesTableHandle`], which mediates access to the table `profiles`. + fn profiles(&self) -> ProfilesTableHandle<'_>; +} + +impl ProfilesTableAccess for super::RemoteTables { + fn profiles(&self) -> ProfilesTableHandle<'_> { + ProfilesTableHandle { + imp: self.imp.get_table::("profiles"), + ctx: std::marker::PhantomData, + } + } +} + +pub struct ProfilesInsertCallbackId(__sdk::CallbackId); +pub struct ProfilesDeleteCallbackId(__sdk::CallbackId); + +impl<'ctx> __sdk::Table for ProfilesTableHandle<'ctx> { + type Row = Profile; + type EventContext = super::EventContext; + + fn count(&self) -> u64 { + self.imp.count() + } + fn iter(&self) -> impl Iterator + '_ { + self.imp.iter() + } + + type InsertCallbackId = ProfilesInsertCallbackId; + + fn on_insert( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, + ) -> ProfilesInsertCallbackId { + ProfilesInsertCallbackId(self.imp.on_insert(Box::new(callback))) + } + + fn remove_on_insert(&self, callback: ProfilesInsertCallbackId) { + self.imp.remove_on_insert(callback.0) + } + + type DeleteCallbackId = ProfilesDeleteCallbackId; + + fn on_delete( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, + ) -> ProfilesDeleteCallbackId { + ProfilesDeleteCallbackId(self.imp.on_delete(Box::new(callback))) + } + + fn remove_on_delete(&self, callback: ProfilesDeleteCallbackId) { + self.imp.remove_on_delete(callback.0) + } +} + +pub struct ProfilesUpdateCallbackId(__sdk::CallbackId); + +impl<'ctx> __sdk::TableWithPrimaryKey for ProfilesTableHandle<'ctx> { + type UpdateCallbackId = ProfilesUpdateCallbackId; + + fn on_update( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static, + ) -> ProfilesUpdateCallbackId { + ProfilesUpdateCallbackId(self.imp.on_update(Box::new(callback))) + } + + fn remove_on_update(&self, callback: ProfilesUpdateCallbackId) { + self.imp.remove_on_update(callback.0) + } +} + +/// Access to the `identity` unique index on the table `profiles`, +/// which allows point queries on the field of the same name +/// via the [`ProfilesIdentityUnique::find`] method. +/// +/// Users are encouraged not to explicitly reference this type, +/// but to directly chain method calls, +/// like `ctx.db.profiles().identity().find(...)`. +pub struct ProfilesIdentityUnique<'ctx> { + imp: __sdk::UniqueConstraintHandle, + phantom: std::marker::PhantomData<&'ctx super::RemoteTables>, +} + +impl<'ctx> ProfilesTableHandle<'ctx> { + /// Get a handle on the `identity` unique index on the table `profiles`. + pub fn identity(&self) -> ProfilesIdentityUnique<'ctx> { + ProfilesIdentityUnique { + imp: self + .imp + .get_unique_constraint::<__sdk::Identity>("identity"), + phantom: std::marker::PhantomData, + } + } +} + +impl<'ctx> ProfilesIdentityUnique<'ctx> { + /// Find the subscribed row whose `identity` column value is equal to `col_val`, + /// if such a row is present in the client cache. + pub fn find(&self, col_val: &__sdk::Identity) -> Option { + self.imp.find(col_val) + } +} + +/// Access to the `username` unique index on the table `profiles`, +/// which allows point queries on the field of the same name +/// via the [`ProfilesUsernameUnique::find`] method. +/// +/// Users are encouraged not to explicitly reference this type, +/// but to directly chain method calls, +/// like `ctx.db.profiles().username().find(...)`. +pub struct ProfilesUsernameUnique<'ctx> { + imp: __sdk::UniqueConstraintHandle, + phantom: std::marker::PhantomData<&'ctx super::RemoteTables>, +} + +impl<'ctx> ProfilesTableHandle<'ctx> { + /// Get a handle on the `username` unique index on the table `profiles`. + pub fn username(&self) -> ProfilesUsernameUnique<'ctx> { + ProfilesUsernameUnique { + imp: self.imp.get_unique_constraint::("username"), + phantom: std::marker::PhantomData, + } + } +} + +impl<'ctx> ProfilesUsernameUnique<'ctx> { + /// Find the subscribed row whose `username` column value is equal to `col_val`, + /// if such a row is present in the client cache. + pub fn find(&self, col_val: &String) -> Option { + self.imp.find(col_val) + } +} + +#[doc(hidden)] +pub(super) fn register_table(client_cache: &mut __sdk::ClientCache) { + let _table = client_cache.get_or_make_table::("profiles"); + _table.add_unique_constraint::<__sdk::Identity>("identity", |row| &row.identity); + _table.add_unique_constraint::("username", |row| &row.username); +} + +#[doc(hidden)] +pub(super) fn parse_table_update( + raw_updates: __ws::v2::TableUpdate, +) -> __sdk::Result<__sdk::TableUpdate> { + __sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| { + __sdk::InternalError::failed_parse("TableUpdate", "TableUpdate") + .with_cause(e) + .into() + }) +} + +#[allow(non_camel_case_types)] +/// Extension trait for query builder access to the table `Profile`. +/// +/// Implemented for [`__sdk::QueryTableAccessor`]. +pub trait profilesQueryTableAccess { + #[allow(non_snake_case)] + /// Get a query builder for the table `Profile`. + fn profiles(&self) -> __sdk::__query_builder::Table; +} + +impl profilesQueryTableAccess for __sdk::QueryTableAccessor { + fn profiles(&self) -> __sdk::__query_builder::Table { + __sdk::__query_builder::Table::new("profiles") + } +} diff --git a/packages/ppc/generated/remove_activity_reducer.rs b/packages/ppc/generated/remove_activity_reducer.rs new file mode 100644 index 0000000..ef22a7c --- /dev/null +++ b/packages/ppc/generated/remove_activity_reducer.rs @@ -0,0 +1,70 @@ +// 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}; + +use super::activity_type::Activity; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub(super) struct RemoveActivityArgs { + pub activity: Activity, +} + +impl From for super::Reducer { + fn from(args: RemoveActivityArgs) -> Self { + Self::RemoveActivity { + activity: args.activity, + } + } +} + +impl __sdk::InModule for RemoveActivityArgs { + type Module = super::RemoteModule; +} + +#[allow(non_camel_case_types)] +/// Extension trait for access to the reducer `remove_activity`. +/// +/// Implemented for [`super::RemoteReducers`]. +pub trait remove_activity { + /// Request that the remote module invoke the reducer `remove_activity` 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 this method provides no way to listen for its completion status. + /// /// Use [`remove_activity:remove_activity_then`] to run a callback after the reducer completes. + fn remove_activity(&self, activity: Activity) -> __sdk::Result<()> { + self.remove_activity_then(activity, |_, _| {}) + } + + /// Request that the remote module invoke the reducer `remove_activity` to run as soon as possible, + /// registering `callback` to run when we are notified that the reducer completed. + /// + /// 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 with the `callback`. + fn remove_activity_then( + &self, + activity: Activity, + + callback: impl FnOnce(&super::ReducerEventContext, Result, __sdk::InternalError>) + + Send + + 'static, + ) -> __sdk::Result<()>; +} + +impl remove_activity for super::RemoteReducers { + fn remove_activity_then( + &self, + activity: Activity, + + callback: impl FnOnce(&super::ReducerEventContext, Result, __sdk::InternalError>) + + Send + + 'static, + ) -> __sdk::Result<()> { + self.imp + .invoke_reducer_with_callback(RemoveActivityArgs { activity }, callback) + } +} diff --git a/packages/ppc/generated/set_activity_name_reducer.rs b/packages/ppc/generated/set_activity_name_reducer.rs new file mode 100644 index 0000000..784650d --- /dev/null +++ b/packages/ppc/generated/set_activity_name_reducer.rs @@ -0,0 +1,72 @@ +// 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 SetActivityNameArgs { + pub id: u64, + pub name: String, +} + +impl From for super::Reducer { + fn from(args: SetActivityNameArgs) -> Self { + Self::SetActivityName { + id: args.id, + name: args.name, + } + } +} + +impl __sdk::InModule for SetActivityNameArgs { + type Module = super::RemoteModule; +} + +#[allow(non_camel_case_types)] +/// Extension trait for access to the reducer `set_activity_name`. +/// +/// Implemented for [`super::RemoteReducers`]. +pub trait set_activity_name { + /// Request that the remote module invoke the reducer `set_activity_name` 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 this method provides no way to listen for its completion status. + /// /// Use [`set_activity_name:set_activity_name_then`] to run a callback after the reducer completes. + fn set_activity_name(&self, id: u64, name: String) -> __sdk::Result<()> { + self.set_activity_name_then(id, name, |_, _| {}) + } + + /// Request that the remote module invoke the reducer `set_activity_name` to run as soon as possible, + /// registering `callback` to run when we are notified that the reducer completed. + /// + /// 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 with the `callback`. + fn set_activity_name_then( + &self, + id: u64, + name: String, + + callback: impl FnOnce(&super::ReducerEventContext, Result, __sdk::InternalError>) + + Send + + 'static, + ) -> __sdk::Result<()>; +} + +impl set_activity_name for super::RemoteReducers { + fn set_activity_name_then( + &self, + id: u64, + name: String, + + callback: impl FnOnce(&super::ReducerEventContext, Result, __sdk::InternalError>) + + Send + + 'static, + ) -> __sdk::Result<()> { + self.imp + .invoke_reducer_with_callback(SetActivityNameArgs { id, name }, callback) + } +} diff --git a/packages/ppc/generated/task_part_table.rs b/packages/ppc/generated/task_part_table.rs new file mode 100644 index 0000000..2799230 --- /dev/null +++ b/packages/ppc/generated/task_part_table.rs @@ -0,0 +1,162 @@ +// 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::activity_type::Activity; +use super::task_part_type::TaskPart; +use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; + +/// Table handle for the table `task_part`. +/// +/// Obtain a handle from the [`TaskPartTableAccess::task_part`] method on [`super::RemoteTables`], +/// like `ctx.db.task_part()`. +/// +/// Users are encouraged not to explicitly reference this type, +/// but to directly chain method calls, +/// like `ctx.db.task_part().on_insert(...)`. +pub struct TaskPartTableHandle<'ctx> { + imp: __sdk::TableHandle, + ctx: std::marker::PhantomData<&'ctx super::RemoteTables>, +} + +#[allow(non_camel_case_types)] +/// Extension trait for access to the table `task_part`. +/// +/// Implemented for [`super::RemoteTables`]. +pub trait TaskPartTableAccess { + #[allow(non_snake_case)] + /// Obtain a [`TaskPartTableHandle`], which mediates access to the table `task_part`. + fn task_part(&self) -> TaskPartTableHandle<'_>; +} + +impl TaskPartTableAccess for super::RemoteTables { + fn task_part(&self) -> TaskPartTableHandle<'_> { + TaskPartTableHandle { + imp: self.imp.get_table::("task_part"), + ctx: std::marker::PhantomData, + } + } +} + +pub struct TaskPartInsertCallbackId(__sdk::CallbackId); +pub struct TaskPartDeleteCallbackId(__sdk::CallbackId); + +impl<'ctx> __sdk::Table for TaskPartTableHandle<'ctx> { + type Row = TaskPart; + type EventContext = super::EventContext; + + fn count(&self) -> u64 { + self.imp.count() + } + fn iter(&self) -> impl Iterator + '_ { + self.imp.iter() + } + + type InsertCallbackId = TaskPartInsertCallbackId; + + fn on_insert( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, + ) -> TaskPartInsertCallbackId { + TaskPartInsertCallbackId(self.imp.on_insert(Box::new(callback))) + } + + fn remove_on_insert(&self, callback: TaskPartInsertCallbackId) { + self.imp.remove_on_insert(callback.0) + } + + type DeleteCallbackId = TaskPartDeleteCallbackId; + + fn on_delete( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, + ) -> TaskPartDeleteCallbackId { + TaskPartDeleteCallbackId(self.imp.on_delete(Box::new(callback))) + } + + fn remove_on_delete(&self, callback: TaskPartDeleteCallbackId) { + self.imp.remove_on_delete(callback.0) + } +} + +pub struct TaskPartUpdateCallbackId(__sdk::CallbackId); + +impl<'ctx> __sdk::TableWithPrimaryKey for TaskPartTableHandle<'ctx> { + type UpdateCallbackId = TaskPartUpdateCallbackId; + + fn on_update( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static, + ) -> TaskPartUpdateCallbackId { + TaskPartUpdateCallbackId(self.imp.on_update(Box::new(callback))) + } + + fn remove_on_update(&self, callback: TaskPartUpdateCallbackId) { + self.imp.remove_on_update(callback.0) + } +} + +/// Access to the `identity` unique index on the table `task_part`, +/// which allows point queries on the field of the same name +/// via the [`TaskPartIdentityUnique::find`] method. +/// +/// Users are encouraged not to explicitly reference this type, +/// but to directly chain method calls, +/// like `ctx.db.task_part().identity().find(...)`. +pub struct TaskPartIdentityUnique<'ctx> { + imp: __sdk::UniqueConstraintHandle, + phantom: std::marker::PhantomData<&'ctx super::RemoteTables>, +} + +impl<'ctx> TaskPartTableHandle<'ctx> { + /// Get a handle on the `identity` unique index on the table `task_part`. + pub fn identity(&self) -> TaskPartIdentityUnique<'ctx> { + TaskPartIdentityUnique { + imp: self + .imp + .get_unique_constraint::<__sdk::Identity>("identity"), + phantom: std::marker::PhantomData, + } + } +} + +impl<'ctx> TaskPartIdentityUnique<'ctx> { + /// Find the subscribed row whose `identity` column value is equal to `col_val`, + /// if such a row is present in the client cache. + pub fn find(&self, col_val: &__sdk::Identity) -> Option { + self.imp.find(col_val) + } +} + +#[doc(hidden)] +pub(super) fn register_table(client_cache: &mut __sdk::ClientCache) { + let _table = client_cache.get_or_make_table::("task_part"); + _table.add_unique_constraint::<__sdk::Identity>("identity", |row| &row.identity); +} + +#[doc(hidden)] +pub(super) fn parse_table_update( + raw_updates: __ws::v2::TableUpdate, +) -> __sdk::Result<__sdk::TableUpdate> { + __sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| { + __sdk::InternalError::failed_parse("TableUpdate", "TableUpdate") + .with_cause(e) + .into() + }) +} + +#[allow(non_camel_case_types)] +/// Extension trait for query builder access to the table `TaskPart`. +/// +/// Implemented for [`__sdk::QueryTableAccessor`]. +pub trait task_partQueryTableAccess { + #[allow(non_snake_case)] + /// Get a query builder for the table `TaskPart`. + fn task_part(&self) -> __sdk::__query_builder::Table; +} + +impl task_partQueryTableAccess for __sdk::QueryTableAccessor { + fn task_part(&self) -> __sdk::__query_builder::Table { + __sdk::__query_builder::Table::new("task_part") + } +} diff --git a/packages/ppc/generated/task_part_type.rs b/packages/ppc/generated/task_part_type.rs new file mode 100644 index 0000000..3cd88eb --- /dev/null +++ b/packages/ppc/generated/task_part_type.rs @@ -0,0 +1,54 @@ +// 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}; + +use super::activity_type::Activity; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub struct TaskPart { + pub identity: __sdk::Identity, + pub current_activity: Activity, +} + +impl __sdk::InModule for TaskPart { + type Module = super::RemoteModule; +} + +/// Column accessor struct for the table `TaskPart`. +/// +/// Provides typed access to columns for query building. +pub struct TaskPartCols { + pub identity: __sdk::__query_builder::Col, + pub current_activity: __sdk::__query_builder::Col, +} + +impl __sdk::__query_builder::HasCols for TaskPart { + type Cols = TaskPartCols; + fn cols(table_name: &'static str) -> Self::Cols { + TaskPartCols { + identity: __sdk::__query_builder::Col::new(table_name, "identity"), + current_activity: __sdk::__query_builder::Col::new(table_name, "current_activity"), + } + } +} + +/// Indexed column accessor struct for the table `TaskPart`. +/// +/// Provides typed access to indexed columns for query building. +pub struct TaskPartIxCols { + pub identity: __sdk::__query_builder::IxCol, +} + +impl __sdk::__query_builder::HasIxCols for TaskPart { + type IxCols = TaskPartIxCols; + fn ix_cols(table_name: &'static str) -> Self::IxCols { + TaskPartIxCols { + identity: __sdk::__query_builder::IxCol::new(table_name, "identity"), + } + } +} + +impl __sdk::__query_builder::CanBeLookupTable for TaskPart {} diff --git a/packages/ppc/generated/task_type.rs b/packages/ppc/generated/task_type.rs new file mode 100644 index 0000000..a6c9315 --- /dev/null +++ b/packages/ppc/generated/task_type.rs @@ -0,0 +1,58 @@ +// 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 Task { + pub id: u64, + pub done: bool, + pub name: String, + pub parent: Option, +} + +impl __sdk::InModule for Task { + type Module = super::RemoteModule; +} + +/// Column accessor struct for the table `Task`. +/// +/// Provides typed access to columns for query building. +pub struct TaskCols { + pub id: __sdk::__query_builder::Col, + pub done: __sdk::__query_builder::Col, + pub name: __sdk::__query_builder::Col, + pub parent: __sdk::__query_builder::Col>, +} + +impl __sdk::__query_builder::HasCols for Task { + type Cols = TaskCols; + fn cols(table_name: &'static str) -> Self::Cols { + TaskCols { + id: __sdk::__query_builder::Col::new(table_name, "id"), + done: __sdk::__query_builder::Col::new(table_name, "done"), + name: __sdk::__query_builder::Col::new(table_name, "name"), + parent: __sdk::__query_builder::Col::new(table_name, "parent"), + } + } +} + +/// Indexed column accessor struct for the table `Task`. +/// +/// Provides typed access to indexed columns for query building. +pub struct TaskIxCols { + pub id: __sdk::__query_builder::IxCol, +} + +impl __sdk::__query_builder::HasIxCols for Task { + type IxCols = TaskIxCols; + fn ix_cols(table_name: &'static str) -> Self::IxCols { + TaskIxCols { + id: __sdk::__query_builder::IxCol::new(table_name, "id"), + } + } +} + +impl __sdk::__query_builder::CanBeLookupTable for Task {} diff --git a/packages/ppc/generated/tasks_table.rs b/packages/ppc/generated/tasks_table.rs new file mode 100644 index 0000000..3d18b77 --- /dev/null +++ b/packages/ppc/generated/tasks_table.rs @@ -0,0 +1,159 @@ +// 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::task_type::Task; +use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; + +/// Table handle for the table `tasks`. +/// +/// Obtain a handle from the [`TasksTableAccess::tasks`] method on [`super::RemoteTables`], +/// like `ctx.db.tasks()`. +/// +/// Users are encouraged not to explicitly reference this type, +/// but to directly chain method calls, +/// like `ctx.db.tasks().on_insert(...)`. +pub struct TasksTableHandle<'ctx> { + imp: __sdk::TableHandle, + ctx: std::marker::PhantomData<&'ctx super::RemoteTables>, +} + +#[allow(non_camel_case_types)] +/// Extension trait for access to the table `tasks`. +/// +/// Implemented for [`super::RemoteTables`]. +pub trait TasksTableAccess { + #[allow(non_snake_case)] + /// Obtain a [`TasksTableHandle`], which mediates access to the table `tasks`. + fn tasks(&self) -> TasksTableHandle<'_>; +} + +impl TasksTableAccess for super::RemoteTables { + fn tasks(&self) -> TasksTableHandle<'_> { + TasksTableHandle { + imp: self.imp.get_table::("tasks"), + ctx: std::marker::PhantomData, + } + } +} + +pub struct TasksInsertCallbackId(__sdk::CallbackId); +pub struct TasksDeleteCallbackId(__sdk::CallbackId); + +impl<'ctx> __sdk::Table for TasksTableHandle<'ctx> { + type Row = Task; + type EventContext = super::EventContext; + + fn count(&self) -> u64 { + self.imp.count() + } + fn iter(&self) -> impl Iterator + '_ { + self.imp.iter() + } + + type InsertCallbackId = TasksInsertCallbackId; + + fn on_insert( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, + ) -> TasksInsertCallbackId { + TasksInsertCallbackId(self.imp.on_insert(Box::new(callback))) + } + + fn remove_on_insert(&self, callback: TasksInsertCallbackId) { + self.imp.remove_on_insert(callback.0) + } + + type DeleteCallbackId = TasksDeleteCallbackId; + + fn on_delete( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, + ) -> TasksDeleteCallbackId { + TasksDeleteCallbackId(self.imp.on_delete(Box::new(callback))) + } + + fn remove_on_delete(&self, callback: TasksDeleteCallbackId) { + self.imp.remove_on_delete(callback.0) + } +} + +pub struct TasksUpdateCallbackId(__sdk::CallbackId); + +impl<'ctx> __sdk::TableWithPrimaryKey for TasksTableHandle<'ctx> { + type UpdateCallbackId = TasksUpdateCallbackId; + + fn on_update( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static, + ) -> TasksUpdateCallbackId { + TasksUpdateCallbackId(self.imp.on_update(Box::new(callback))) + } + + fn remove_on_update(&self, callback: TasksUpdateCallbackId) { + self.imp.remove_on_update(callback.0) + } +} + +/// Access to the `id` unique index on the table `tasks`, +/// which allows point queries on the field of the same name +/// via the [`TasksIdUnique::find`] method. +/// +/// Users are encouraged not to explicitly reference this type, +/// but to directly chain method calls, +/// like `ctx.db.tasks().id().find(...)`. +pub struct TasksIdUnique<'ctx> { + imp: __sdk::UniqueConstraintHandle, + phantom: std::marker::PhantomData<&'ctx super::RemoteTables>, +} + +impl<'ctx> TasksTableHandle<'ctx> { + /// Get a handle on the `id` unique index on the table `tasks`. + pub fn id(&self) -> TasksIdUnique<'ctx> { + TasksIdUnique { + imp: self.imp.get_unique_constraint::("id"), + phantom: std::marker::PhantomData, + } + } +} + +impl<'ctx> TasksIdUnique<'ctx> { + /// Find the subscribed row whose `id` column value is equal to `col_val`, + /// if such a row is present in the client cache. + pub fn find(&self, col_val: &u64) -> Option { + self.imp.find(col_val) + } +} + +#[doc(hidden)] +pub(super) fn register_table(client_cache: &mut __sdk::ClientCache) { + let _table = client_cache.get_or_make_table::("tasks"); + _table.add_unique_constraint::("id", |row| &row.id); +} + +#[doc(hidden)] +pub(super) fn parse_table_update( + raw_updates: __ws::v2::TableUpdate, +) -> __sdk::Result<__sdk::TableUpdate> { + __sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| { + __sdk::InternalError::failed_parse("TableUpdate", "TableUpdate") + .with_cause(e) + .into() + }) +} + +#[allow(non_camel_case_types)] +/// Extension trait for query builder access to the table `Task`. +/// +/// Implemented for [`__sdk::QueryTableAccessor`]. +pub trait tasksQueryTableAccess { + #[allow(non_snake_case)] + /// Get a query builder for the table `Task`. + fn tasks(&self) -> __sdk::__query_builder::Table; +} + +impl tasksQueryTableAccess for __sdk::QueryTableAccessor { + fn tasks(&self) -> __sdk::__query_builder::Table { + __sdk::__query_builder::Table::new("tasks") + } +} diff --git a/packages/ppc/generated/update_activity_reducer.rs b/packages/ppc/generated/update_activity_reducer.rs new file mode 100644 index 0000000..61624d7 --- /dev/null +++ b/packages/ppc/generated/update_activity_reducer.rs @@ -0,0 +1,70 @@ +// 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}; + +use super::activity_type::Activity; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub(super) struct UpdateActivityArgs { + pub activity: Activity, +} + +impl From for super::Reducer { + fn from(args: UpdateActivityArgs) -> Self { + Self::UpdateActivity { + activity: args.activity, + } + } +} + +impl __sdk::InModule for UpdateActivityArgs { + type Module = super::RemoteModule; +} + +#[allow(non_camel_case_types)] +/// Extension trait for access to the reducer `update_activity`. +/// +/// Implemented for [`super::RemoteReducers`]. +pub trait update_activity { + /// Request that the remote module invoke the reducer `update_activity` 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 this method provides no way to listen for its completion status. + /// /// Use [`update_activity:update_activity_then`] to run a callback after the reducer completes. + fn update_activity(&self, activity: Activity) -> __sdk::Result<()> { + self.update_activity_then(activity, |_, _| {}) + } + + /// Request that the remote module invoke the reducer `update_activity` to run as soon as possible, + /// registering `callback` to run when we are notified that the reducer completed. + /// + /// 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 with the `callback`. + fn update_activity_then( + &self, + activity: Activity, + + callback: impl FnOnce(&super::ReducerEventContext, Result, __sdk::InternalError>) + + Send + + 'static, + ) -> __sdk::Result<()>; +} + +impl update_activity for super::RemoteReducers { + fn update_activity_then( + &self, + activity: Activity, + + callback: impl FnOnce(&super::ReducerEventContext, Result, __sdk::InternalError>) + + Send + + 'static, + ) -> __sdk::Result<()> { + self.imp + .invoke_reducer_with_callback(UpdateActivityArgs { activity }, callback) + } +} diff --git a/packages/ppc/lib.rs b/packages/ppc/lib.rs index 7e68b20..8ceb410 100644 --- a/packages/ppc/lib.rs +++ b/packages/ppc/lib.rs @@ -1,3 +1,5 @@ +#![feature(oneshot_channel)] + mod platform { #[cfg(feature = "target-obsidian")] pub mod obsidian; @@ -21,3 +23,10 @@ pub mod auth { pub mod client; } pub use auth::client::client_auth; + +pub mod spacetime; +pub mod timetrack; + +// the generated source +// right now only from spacetimedb +mod generated; diff --git a/packages/ppc/platform/os/main.rs b/packages/ppc/platform/os/main.rs index 9afab57..34e2c74 100644 --- a/packages/ppc/platform/os/main.rs +++ b/packages/ppc/platform/os/main.rs @@ -17,12 +17,34 @@ fn main() { #[cfg(feature = "target-os")] fn os_main(mize: &mut Mize) -> MizeResult<()> { + use ppc::spacetime::spacetime; + marts::cli(mize)?; //marts::js(mize)?; - marts::habitica(mize)?; + + #[cfg(feature = "client")] + { + use ppc::timetrack::timetrack; + + ppc::client_auth(mize)?; + if let Err(err) = spacetime(mize) { + println!("spacetime part failed to initialize: {:?}", err); + }; + timetrack(mize)?; + } + + //marts::habitica(mize)?; marts::c2vi(mize)?; + + #[cfg(feature = "server")] ppc::server(mize)?; - ppc::client_auth(mize)?; + + #[cfg(feature = "client")] + #[cfg(feature = "desktop")] + cli.subcommand(Command::new("gui"), |_, _| { + ppc::ui::launch_desktop_app(); + Ok(()) + }); let mut cli = mize.get_part_native::("cli")?; @@ -31,7 +53,7 @@ fn os_main(mize: &mut Mize) -> MizeResult<()> { .version(crate_version!()) .name("ppc") .author("ppc") - .about("the ppc desktop program")) + .about("the ppc app")) })?; cli.subcommand(Command::new("test"), |_, _| { @@ -39,11 +61,6 @@ fn os_main(mize: &mut Mize) -> MizeResult<()> { Ok(()) }); - cli.subcommand(Command::new("gui"), |_, _| { - ppc::ui::launch_desktop_app(); - Ok(()) - }); - drop(cli); mize.run() } diff --git a/packages/ppc/platform/os/server.rs b/packages/ppc/platform/os/server.rs index 0b8fd26..3ddba73 100644 --- a/packages/ppc/platform/os/server.rs +++ b/packages/ppc/platform/os/server.rs @@ -54,6 +54,9 @@ pub fn server(mize: &mut Mize) -> MizeResult<()> { pub async fn start_server(mize: &mut Mize) -> MizeResult<()> { dioxus::logger::initialize_default(); + let issuer = mize.get_config("auth.issuer")?.value_string()?; + let listen_addr = mize.get_config("server.listen_addr")?.value_string()?; + let port = mize.get_config("server.port")?.value_string()?; let issuer = mize.get_config("auth.issuer")?.value_string()?; let client_id = mize.get_config("auth.client_id")?.value_string()?; let client_secret = mize.get_config("auth.client_secret")?.value_string()?; @@ -107,9 +110,11 @@ pub async fn start_server(mize: &mut Mize) -> MizeResult<()> { .route("/", get(ppc_main_page)) .route("/oidc_display_code_and_state", get(display_code_and_state)); - tracing::info!("Running on http://localhost:3000"); + tracing::info!("Running on http://{listen_addr}:{port}"); - let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap(); + let listener = tokio::net::TcpListener::bind(format!("{listen_addr}:{port}")) + .await + .unwrap(); axum::serve(listener, app.into_make_service()) .await .unwrap(); diff --git a/packages/ppc/spacetime.rs b/packages/ppc/spacetime.rs new file mode 100644 index 0000000..af38e39 --- /dev/null +++ b/packages/ppc/spacetime.rs @@ -0,0 +1,44 @@ +use mize::{Mize, MizeError, MizePart, MizeResult, mize_part}; + +use crate::{auth::client::ClientAuth, generated::DbConnection}; + +#[mize_part] +#[derive(Default)] +pub struct SpacetimePart { + mize: Mize, + con: Option, +} + +impl MizePart for SpacetimePart { + fn name(&self) -> &'static str { + "spacetime" + } +} + +impl SpacetimePart { + pub fn con(&mut self) -> &mut DbConnection { + self.con.as_mut().unwrap() + } +} + +pub fn spacetime(mize: &mut Mize) -> MizeResult<()> { + let auth = mize.get_part_native::("client_auth")?; + let db_url = mize.get_config("spacetime.url")?.value_string()?; + + let con = DbConnection::builder() + .with_token(Some(auth.id_token()?)) + .with_database_name("ppc") + .with_uri(db_url) + //.on_connect(callback) + //.on_disconnect(callback) + //.on_connect_error(callback) + //.with_compression(...) + .build()?; + + con.run_threaded(); + + mize.register_part(Box::new(SpacetimePart { + mize: mize.clone(), + con: Some(con), + })) +} diff --git a/packages/spacetime-module-ppc/Cargo.toml b/packages/ppc/spacetimedb/Cargo.toml similarity index 89% rename from packages/spacetime-module-ppc/Cargo.toml rename to packages/ppc/spacetimedb/Cargo.toml index 0c83781..b653f8c 100644 --- a/packages/spacetime-module-ppc/Cargo.toml +++ b/packages/ppc/spacetimedb/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "quickstart_chat" +name = "ppc-spacetime" version = "0.1.0" edition = "2021" diff --git a/packages/spacetime-module-ppc/src/lib.rs b/packages/ppc/spacetimedb/src/lib.rs similarity index 72% rename from packages/spacetime-module-ppc/src/lib.rs rename to packages/ppc/spacetimedb/src/lib.rs index dae8f12..15a605f 100644 --- a/packages/spacetime-module-ppc/src/lib.rs +++ b/packages/ppc/spacetimedb/src/lib.rs @@ -9,6 +9,13 @@ pub struct Profile { username: String, } +#[table(accessor = task_part, public)] +pub struct TaskPart { + #[primary_key] + identity: Identity, + current_activity: Activity, +} + #[table(accessor = activities, public)] pub struct Activity { #[primary_key] @@ -16,6 +23,7 @@ pub struct Activity { id: u64, name: String, task: Option, + parents_ids: Vec, } #[table(accessor = tasks, public)] @@ -85,5 +93,29 @@ pub fn add_activity(ctx: &ReducerContext, name: String) { name, task: None, id: 0, // auto-increments + parents_ids: Vec::new(), }); } + +#[reducer] +pub fn set_activity_name(ctx: &ReducerContext, id: u64, name: String) { + if let Some(old_ac) = ctx.db.activities().id().find(id) { + ctx.db.activities().id().update(Activity { name, ..old_ac }); + } else { + return (); + } +} + +#[reducer] +pub fn update_activity(ctx: &ReducerContext, activity: Activity) { + if activity.id == 0 { + ctx.db.activities().insert(activity); + } else { + ctx.db.activities().id().update(activity); + } +} + +#[reducer] +pub fn remove_activity(ctx: &ReducerContext, activity: Activity) { + ctx.db.activities().delete(activity); +} diff --git a/packages/ppc/timetrack/mod.rs b/packages/ppc/timetrack/mod.rs new file mode 100644 index 0000000..e7cd7ab --- /dev/null +++ b/packages/ppc/timetrack/mod.rs @@ -0,0 +1,257 @@ +use std::{io::Read, sync::oneshot, thread, time::Duration}; + +use clap::{ArgMatches, Command}; +use mize::{Mize, MizeError, MizePart, MizePartGuard, MizeResult, mize_err, mize_part}; +use spacetimedb_sdk::{ + DbContext, Error, Event, Identity, Status, SubscriptionHandle, Table, TableWithPrimaryKey, + credentials, +}; + +use crate::{ + generated::{ + ActivitiesTableAccess, Activity, DbConnection, activitiesQueryTableAccess, remove_activity, + update_activity, + }, + spacetime::SpacetimePart, +}; + +#[mize_part] +#[derive(Default)] +pub struct TimeTrack { + mize: Mize, +} + +pub fn timetrack(mize: &mut Mize) -> MizeResult<()> { + let mut cli = mize.get_part_native::("cli")?; + + cli.subcommand( + Command::new("listActivities").alias("lac"), + command_list_activities, + ); + cli.subcommand( + Command::new("editActivities").alias("eac"), + command_edit_activities, + ); + + mize.register_part(Box::new(TimeTrack { mize: mize.clone() })); + Ok(()) +} + +impl MizePart for TimeTrack { + fn name(&self) -> &'static str { + "timetrack" + } +} + +fn command_list_activities(_: &ArgMatches, mut mize: Mize) -> MizeResult<()> { + let mut spacetime = mize.get_part_native::("spacetime")?; + let activities = get_activities(&mut mize, spacetime.con())?; + for ac in activities.clone() { + print!("ac {}: {}", ac.id, ac.name); + if !ac.parents_ids.is_empty() { + print!(" -"); + } + for child_id in ac.parents_ids { + let child_ac = activities.iter().find(|ac| ac.id == child_id).unwrap(); + print!(" {}", child_ac.name); + } + print!("\n") + } + Ok(()) +} + +fn command_edit_activities(_: &ArgMatches, mut mize: Mize) -> MizeResult<()> { + let mut spacetime = mize.get_part_native::("spacetime")?; + + // get list of activities + let activities = get_activities(&mut mize, spacetime.con())?; + + let con = spacetime.con(); + + // write to tmp file + let mut tmp_file_content = String::new(); + for ac in activities.iter() { + tmp_file_content.push_str(format!("{} {}", ac.id, ac.name).as_str()); + if !ac.parents_ids.is_empty() { + tmp_file_content.push_str(" -"); + for parent_id in ac.parents_ids.iter() { + let parent_ac = activities.iter().find(|ac| ac.id == *parent_id).unwrap(); + tmp_file_content.push_str(" "); + tmp_file_content.push_str(&parent_ac.name); + } + } + tmp_file_content.push_str("\n"); + } + let tmp_file = std::env::temp_dir().join(format!( + "ppc-edit-activities-{}.txt", + chrono::Utc::now().timestamp() + )); + std::fs::write(&tmp_file, tmp_file_content) + .map_err(|e| mize_err!("Failed to write temp file: {}", e))?; + + loop { + // open $EDITOR blocking + std::process::Command::new("nvim") + .arg(&tmp_file) + .status() + .map_err(|e| mize_err!("Failed to run nvim: {}", e))?; + + let new_file_content = std::fs::read_to_string(&tmp_file) + .map_err(|e| mize_err!("Failed to read temp file: {}", e))?; + + let mut input = String::new(); + + let old_activities = get_activities(&mut mize, con)?; + if let Err(err) = + parse_activities_from_text(&mut mize, con, new_file_content, old_activities) + { + println!("error parsing the activities from the file: {:?}", err); + println!("press ENTER to open the file again"); + + // wait for user input + // so that they can se the err msg, before running nvim again + std::io::stdin().read_line(&mut input)?; + } else { + break; + } + } + + // delete tmpfile + let _ = std::fs::remove_file(&tmp_file); + + Ok(()) +} + +fn get_activities(mize: &mut Mize, con: &mut DbConnection) -> MizeResult> { + let (exit_tx, exit_rx) = std::sync::oneshot::channel::>(); + con.subscription_builder() + .on_applied(|ctx| { + exit_tx.send(ctx.db.activities().iter().collect()).unwrap(); + }) + .add_query(|q| q.from.activities()) + .subscribe(); + let activities = exit_rx.recv().unwrap(); + Ok(activities) +} + +fn parse_activities_from_text( + mize: &mut Mize, + con: &mut DbConnection, + text: String, + old_activities: Vec, +) -> MizeResult<()> { + let mut activities_to_delete = old_activities.clone(); + let mut wait_revievers = Vec::new(); + for line in text.lines() { + if line == "" { + continue; + } + + // split + let mut parts = line.split(" "); + let id: u64 = parts.next().ok_or(mize_err!(".."))?.parse()?; + let name = parts.next().ok_or(mize_err!(".."))?.to_string(); + + // remove from to-delete list + if let Some(pos) = activities_to_delete.iter().position(|ac| ac.id == id) { + activities_to_delete.remove(pos); + } + + // wait rx + let (wait_tx, wait_rx) = oneshot::channel::<()>(); + wait_revievers.push(wait_rx); + + // update or create activity + if let Some(old_activity) = old_activities.iter().find(|ac| ac.id == id) { + con.reducers.update_activity_then( + Activity { + id, + name, + task: old_activity.task, + parents_ids: old_activity.parents_ids.clone(), + }, + move |_, _| { + wait_tx.send(()); + }, + )?; + } else { + con.reducers.update_activity_then( + Activity { + id: 0, + name, + task: None, + parents_ids: Vec::new(), + }, + move |_, _| { + wait_tx.send(()); + }, + )?; + } + } + + // remove deleted activities + for activity in activities_to_delete { + let (wait_tx, wait_rx) = oneshot::channel::<()>(); + wait_revievers.push(wait_rx); + con.reducers.remove_activity_then(activity, move |_, _| { + wait_tx.send(()); + })?; + } + + // wait for db stuff to finish + for wait_rx in wait_revievers { + wait_rx.recv().unwrap(); + } + let mut wait_revievers = Vec::new(); + + // check for declared parents + let new_activities = get_activities(mize, con)?; + println!("new_activities: {:?}", new_activities); + for line in text.lines() { + if line == "" { + continue; + } + + // split + let mut parts = line.split(" "); + let id: u64 = parts.next().ok_or(mize_err!(".."))?.parse()?; + let name = parts.next().ok_or(mize_err!(".."))?.to_string(); + + // parse parents + let seperator = parts.next(); + if seperator.is_some() && seperator.unwrap() == "-" { + let mut parents_ids = Vec::new(); + for parent_name in parts { + // find id from old_parts by this name + let res_from_old = old_activities.iter().find(|ac| ac.name == parent_name); + let res_from_new = new_activities.iter().find(|ac| ac.name == parent_name); + let parent_activity = res_from_old.or(res_from_new).ok_or(mize_err!( + "activity '{name}' declares parent '{parent_name}'" + ))?; + parents_ids.push(parent_activity.id); + } + let child_activity = new_activities + .iter() + .find(|ac| ac.name == name) + .ok_or(mize_err!(".."))?; + let (wait_tx, wait_rx) = oneshot::channel::<()>(); + wait_revievers.push(wait_rx); + con.reducers.update_activity_then( + Activity { + parents_ids, + ..child_activity.to_owned() + }, + move |_, _| { + wait_tx.send(()); + }, + ); + } + } + + // wait for db stuff to finish + for wait_rx in wait_revievers { + wait_rx.recv().unwrap(); + } + + Ok(()) +} diff --git a/packages/spacetime-module-ppc/bindings/add_reducer.rs b/packages/spacetime-module-ppc/bindings/add_reducer.rs deleted file mode 100644 index 4fa3f62..0000000 --- a/packages/spacetime-module-ppc/bindings/add_reducer.rs +++ /dev/null @@ -1,104 +0,0 @@ -// 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 deleted file mode 100644 index 2eaaab0..0000000 --- a/packages/spacetime-module-ppc/bindings/identity_connected_reducer.rs +++ /dev/null @@ -1,101 +0,0 @@ -// 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 deleted file mode 100644 index c2892ed..0000000 --- a/packages/spacetime-module-ppc/bindings/identity_disconnected_reducer.rs +++ /dev/null @@ -1,103 +0,0 @@ -// 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/person_table.rs b/packages/spacetime-module-ppc/bindings/person_table.rs deleted file mode 100644 index da3f64b..0000000 --- a/packages/spacetime-module-ppc/bindings/person_table.rs +++ /dev/null @@ -1,95 +0,0 @@ -// 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 deleted file mode 100644 index 7e627a2..0000000 --- a/packages/spacetime-module-ppc/bindings/person_type.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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 deleted file mode 100644 index d326602..0000000 --- a/packages/spacetime-module-ppc/bindings/say_hello_reducer.rs +++ /dev/null @@ -1,100 +0,0 @@ -// 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); - } -}