From 5955cd945c9eb1118862680ac733cca80fe0581e Mon Sep 17 00:00:00 2001 From: Orual Date: Tue, 20 May 2025 15:17:12 -0400 Subject: [PATCH] Removed the lazy submodules Also some new lexicons related to loro CRDT format --- .zed/settings.json | 5 - Cargo.lock | 355 ++++++++---------- Cargo.toml | 2 +- atproto | 1 - crates/weaver-cli/Cargo.toml | 3 +- crates/weaver-cli/src/main.rs | 164 +++++--- crates/weaver-common/Cargo.toml | 6 +- crates/weaver-common/src/error.rs | 3 + crates/weaver-common/src/filestore.rs | 187 +++++++++ .../lexicons/app/bsky/unspecced/get_config.rs | 9 + crates/weaver-common/src/lexicons/record.rs | 36 ++ .../weaver-common/src/lexicons/sh/weaver.rs | 1 + .../src/lexicons/sh/weaver/edit.rs | 24 ++ .../src/lexicons/sh/weaver/edit/cursor.rs | 61 +++ .../src/lexicons/sh/weaver/edit/defs.rs | 28 ++ .../src/lexicons/sh/weaver/edit/diff.rs | 16 + .../src/lexicons/sh/weaver/edit/root.rs | 17 + .../src/lexicons/sh/weaver/notebook/book.rs | 7 +- .../src/lexicons/sh/weaver/notebook/defs.rs | 23 ++ .../src/lexicons/sh/weaver/notebook/entry.rs | 13 +- crates/weaver-common/src/lib.rs | 3 + crates/weaver-common/src/oauth.rs | 85 ++++- crates/weaver-common/src/resolver.rs | 5 +- crates/weaver-renderer/Cargo.toml | 2 + crates/weaver-renderer/src/lib.rs | 2 +- crates/weaver-renderer/src/types.rs | 38 +- crates/weaver-workspace-hack/Cargo.toml | 5 +- lexicon-codegen.sh | 14 +- lexicons/sh/weaver/edit/cursor.json | 81 ++++ lexicons/sh/weaver/edit/defs.json | 36 ++ lexicons/sh/weaver/edit/diff.json | 30 ++ lexicons/sh/weaver/edit/root.json | 28 ++ lexicons/sh/weaver/notebook/book.json | 12 +- lexicons/sh/weaver/notebook/defs.json | 33 ++ lexicons/sh/weaver/notebook/entry.json | 29 +- tangled/core | 1 - test.html | 8 + 37 files changed, 1060 insertions(+), 313 deletions(-) delete mode 160000 atproto create mode 100644 crates/weaver-common/src/filestore.rs create mode 100644 crates/weaver-common/src/lexicons/sh/weaver/edit.rs create mode 100644 crates/weaver-common/src/lexicons/sh/weaver/edit/cursor.rs create mode 100644 crates/weaver-common/src/lexicons/sh/weaver/edit/defs.rs create mode 100644 crates/weaver-common/src/lexicons/sh/weaver/edit/diff.rs create mode 100644 crates/weaver-common/src/lexicons/sh/weaver/edit/root.rs create mode 100644 lexicons/sh/weaver/edit/cursor.json create mode 100644 lexicons/sh/weaver/edit/defs.json create mode 100644 lexicons/sh/weaver/edit/diff.json create mode 100644 lexicons/sh/weaver/edit/root.json delete mode 160000 tangled/core diff --git a/.zed/settings.json b/.zed/settings.json index 9d2a917..5d2482d 100644 --- a/.zed/settings.json +++ b/.zed/settings.json @@ -12,10 +12,5 @@ } } } - }, - "rust-analyzer": { - "binary": { - "path_lookup": true - } } } diff --git a/Cargo.lock b/Cargo.lock index b8a5ba5..96540d8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -429,9 +429,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.9.0" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" [[package]] name = "block-buffer" @@ -497,12 +497,6 @@ version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" -[[package]] -name = "camino" -version = "1.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3" - [[package]] name = "castaway" version = "0.2.3" @@ -523,9 +517,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.22" +version = "1.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32db95edf998450acc7881c932f94cd9b05c87b4b2599e8bab064753da4acfd1" +checksum = "5f4ac86a9e5bc1e2b3449ab9d7d3a6a405e3d1bb28d7b9be8614f55846ae3766" dependencies = [ "shlex", ] @@ -968,7 +962,7 @@ version = "2.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff3e1edb1f37b4953dd5176916347289ed43d7119cc2e6c7c3f7849ff44ea506" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "byteorder", "chrono", "diesel_derives", @@ -1039,6 +1033,27 @@ dependencies = [ "subtle", ] +[[package]] +name = "dirs" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.59.0", +] + [[package]] name = "displaydoc" version = "0.2.5" @@ -1165,9 +1180,9 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" -version = "0.3.11" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e" +checksum = "cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18" dependencies = [ "libc", "windows-sys 0.59.0", @@ -1216,18 +1231,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" -[[package]] -name = "fallible-iterator" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" - -[[package]] -name = "fallible-streaming-iterator" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" - [[package]] name = "fastrand" version = "2.3.0" @@ -1415,10 +1418,11 @@ dependencies = [ [[package]] name = "generator" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc6bd114ceda131d3b1d665eba35788690ad37f5916457286b32ab6fd3c438dd" +checksum = "d18470a76cb7f8ff746cf1f7470914f900252ec36bbc40b569d74b1258446827" dependencies = [ + "cc", "cfg-if", "libc", "log", @@ -1467,9 +1471,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" dependencies = [ "cfg-if", + "js-sys", "libc", "r-efi", "wasi 0.14.2+wasi-0.2.4", + "wasm-bindgen", ] [[package]] @@ -1560,15 +1566,6 @@ dependencies = [ "hashbrown 0.14.5", ] -[[package]] -name = "hashlink" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af" -dependencies = [ - "hashbrown 0.14.5", -] - [[package]] name = "heck" version = "0.4.1" @@ -1938,7 +1935,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f37dccff2791ab604f9babef0ba14fbe0be30bd368dc541e2b08d07c8aa908f3" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "inotify-sys", "libc", ] @@ -2137,36 +2134,6 @@ dependencies = [ "spin 0.9.8", ] -[[package]] -name = "lexical-parse-float" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683b3a5ebd0130b8fb52ba0bdc718cc56815b6a097e28ae5a6997d0ad17dc05f" -dependencies = [ - "lexical-parse-integer", - "lexical-util", - "static_assertions", -] - -[[package]] -name = "lexical-parse-integer" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d0994485ed0c312f6d965766754ea177d07f9c00c9b82a5ee62ed5b47945ee9" -dependencies = [ - "lexical-util", - "static_assertions", -] - -[[package]] -name = "lexical-util" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5255b9ff16ff898710eb9eb63cb39248ea8a5bb036bea8085b1a767ff6c4e3fc" -dependencies = [ - "static_assertions", -] - [[package]] name = "libc" version = "0.2.172" @@ -2185,7 +2152,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "libc", "redox_syscall", ] @@ -2196,7 +2163,6 @@ version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149" dependencies = [ - "cc", "pkg-config", "vcpkg", ] @@ -2266,23 +2232,28 @@ dependencies = [ "linked-hash-map", ] +[[package]] +name = "lru-slab" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" + [[package]] name = "markdown-weaver" version = "0.13.0" -source = "git+https://github.com/rsform/markdown-weaver#34bc7ad2d7e6e9b9604ba61602b68589f271404e" +source = "git+https://github.com/rsform/markdown-weaver#593f968ec3c4515c23273715eaeb33801342439b" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "getopts", "markdown-weaver-escape", "memchr", - "serde", "unicase", ] [[package]] name = "markdown-weaver-escape" version = "0.11.0" -source = "git+https://github.com/rsform/markdown-weaver#34bc7ad2d7e6e9b9604ba61602b68589f271404e" +source = "git+https://github.com/rsform/markdown-weaver#593f968ec3c4515c23273715eaeb33801342439b" [[package]] name = "matchers" @@ -2326,58 +2297,31 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "merde" -version = "10.0.6" +version = "10.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ec14139b169a3bb101da2dd8c0c2e47ddaf63000075662635c64c985bb5ae7b" +checksum = "edd8dc7668eb89ede52dc09d4b21a8c2f7c9cd47168ea1f82550f705615d9b99" dependencies = [ "merde_core", - "merde_json", - "merde_msgpack", "merde_yaml", ] [[package]] name = "merde_core" -version = "10.0.5" +version = "10.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "714d8f25279d095f8d23392476e2e82427e8689348e34f90ddc0712497e157de" +checksum = "e937026f22a5a3567bc402f1edf871ecab0e0222cd6f829ea58abae0185e759c" dependencies = [ - "camino", "compact_bytes", "compact_str", - "ordered-float 4.6.0", - "rusqlite", + "ordered-float 5.0.0", "serde", - "time", -] - -[[package]] -name = "merde_json" -version = "10.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d354c179fe95a0568c8ffb95c276f73556ecb95edca76f742505320e7545cea9" -dependencies = [ - "itoa", - "lexical-parse-float", - "merde_core", - "ryu", -] - -[[package]] -name = "merde_msgpack" -version = "10.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2b710370fee77ca3cb8e6666a2586f26f3a653d7b2e338ede77a13c99108c5e" -dependencies = [ - "merde_core", - "rmp", ] [[package]] name = "merde_yaml" -version = "10.0.5" +version = "10.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb581c31249876b3b385a2cc50fafc666adc9c316874819b7aac7266b3c26c17" +checksum = "7c36f61da594ecad0ed986ceeb5061eba47a36fcf839576ce525c7e4ff08f3fa" dependencies = [ "merde_core", "yaml-rust2", @@ -2597,7 +2541,7 @@ version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2fee8403b3d66ac7b26aee6e40a897d85dc5ce26f44da36b8b73e987cc52e943" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "filetime", "fsevent-sys", "inotify", @@ -2741,7 +2685,7 @@ version = "0.10.72" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fedfea7d58a1f73118430a55da6a286e7b044961736ce96a16a17068ea25e5da" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "cfg-if", "foreign-types", "libc", @@ -2779,6 +2723,12 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + [[package]] name = "ordered-float" version = "2.10.1" @@ -2790,9 +2740,9 @@ dependencies = [ [[package]] name = "ordered-float" -version = "4.6.0" +version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bb71e1b3fa6ca1c61f383464aaf2bb0e2f8e772a1f01d486832464de363b951" +checksum = "e2c1f9f56e534ac6a9b8a4600bdf0f530fb393b5f393e7b4d03489c3cf0c3f01" dependencies = [ "num-traits", ] @@ -2805,9 +2755,9 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "owo-colors" -version = "4.2.0" +version = "4.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1036865bb9422d3300cf723f657c2851d0e9ab12567854b1f4eba3d77decf564" +checksum = "26995317201fa17f3656c36716aed4a7c81743a9634ac4c99c0eeda495db0cec" [[package]] name = "p256" @@ -2862,12 +2812,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - [[package]] name = "pem-rfc7468" version = "0.7.0" @@ -2988,7 +2932,7 @@ dependencies = [ "base64 0.22.1", "byteorder", "bytes", - "fallible-iterator 0.2.0", + "fallible-iterator", "hmac", "md-5", "memchr", @@ -3004,7 +2948,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613283563cd90e1dfc3518d548caee47e0e725455ed619881f5cf21f36de4b48" dependencies = [ "bytes", - "fallible-iterator 0.2.0", + "fallible-iterator", "postgres-protocol", ] @@ -3087,11 +3031,12 @@ dependencies = [ [[package]] name = "quinn" -version = "0.11.6" +version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62e96808277ec6f97351a2380e6c25114bc9e67037775464979f3037c92d05ef" +checksum = "626214629cda6781b6dc1d316ba307189c85ba657213ce642d9c77670f8202c8" dependencies = [ "bytes", + "cfg_aliases", "pin-project-lite", "quinn-proto", "quinn-udp", @@ -3101,17 +3046,19 @@ dependencies = [ "thiserror 2.0.12", "tokio", "tracing", + "web-time", ] [[package]] name = "quinn-proto" -version = "0.11.9" +version = "0.11.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2fe5ef3495d7d2e377ff17b1a8ce2ee2ec2a18cde8b6ad6619d65d0701c135d" +checksum = "49df843a9161c85bb8aae55f101bc0bac8bcafd637a620d9122fd7e0b2f7422e" dependencies = [ "bytes", - "getrandom 0.2.16", - "rand 0.8.5", + "getrandom 0.3.3", + "lru-slab", + "rand 0.9.1", "ring 0.17.14", "rustc-hash", "rustls 0.23.27", @@ -3125,9 +3072,9 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.5.9" +version = "0.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c40286217b4ba3a71d644d752e6a0b71f13f1b6a2c5311acfcbe0c2418ed904" +checksum = "ee4e529991f949c5e25755532370b8af5d114acae52326361d68d47af64aa842" dependencies = [ "cfg_aliases", "libc", @@ -3217,7 +3164,18 @@ version = "0.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "928fca9cf2aa042393a8325b9ead81d2f0df4cb12e1e24cef072922ccd99c5af" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", +] + +[[package]] +name = "redox_users" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b" +dependencies = [ + "getrandom 0.2.16", + "libredox", + "thiserror 2.0.12", ] [[package]] @@ -3380,17 +3338,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "rmp" -version = "0.8.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "228ed7c16fa39782c3b3468e974aec2795e9089153cd08ee2e9aefb3613334c4" -dependencies = [ - "byteorder", - "num-traits", - "paste", -] - [[package]] name = "rouille" version = "3.6.2" @@ -3435,20 +3382,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "rusqlite" -version = "0.32.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7753b721174eb8ff87a9a0e799e2d7bc3749323e773db92e0984debb00019d6e" -dependencies = [ - "bitflags 2.9.0", - "fallible-iterator 0.3.0", - "fallible-streaming-iterator", - "hashlink 0.9.1", - "libsqlite3-sys", - "smallvec", -] - [[package]] name = "rustc-demangle" version = "0.1.24" @@ -3476,7 +3409,7 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "errno", "libc", "linux-raw-sys", @@ -3646,7 +3579,7 @@ version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "core-foundation", "core-foundation-sys", "libc", @@ -4061,7 +3994,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "core-foundation", "system-configuration-sys", ] @@ -4295,7 +4228,7 @@ dependencies = [ "async-trait", "byteorder", "bytes", - "fallible-iterator 0.2.0", + "fallible-iterator", "futures-channel", "futures-util", "log", @@ -4417,7 +4350,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fdb0c213ca27a9f57ab69ddb290fd80d970922355b83ae380b395d3986b8a2e" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "bytes", "futures-util", "http", @@ -4858,6 +4791,7 @@ dependencies = [ "atrium-oauth", "atrium-xrpc-client", "clap", + "dirs", "esquema-codegen", "hickory-resolver", "miette", @@ -4878,11 +4812,11 @@ dependencies = [ "atrium-identity", "atrium-oauth", "atrium-xrpc", + "dirs", "esquema-codegen", "hickory-resolver", "http", "jose-jwk", - "libsqlite3-sys", "markdown-weaver", "merde", "miette", @@ -4912,7 +4846,9 @@ version = "0.1.0" dependencies = [ "atrium-api", "compact_string", + "http", "n0-future", + "url", "weaver-common", "weaver-workspace-hack", ] @@ -4951,7 +4887,6 @@ dependencies = [ "group", "hashbrown 0.15.3", "idna", - "libsqlite3-sys", "log", "memchr", "miette", @@ -5081,32 +5016,55 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows" -version = "0.58.0" +version = "0.61.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" +checksum = "c5ee8f3d025738cb02bad7868bbb5f8a6327501e870bf51f1b455b0a2454a419" +dependencies = [ + "windows-collections", + "windows-core", + "windows-future", + "windows-link", + "windows-numerics", +] + +[[package]] +name = "windows-collections" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" dependencies = [ "windows-core", - "windows-targets 0.52.6", ] [[package]] name = "windows-core" -version = "0.58.0" +version = "0.61.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" +checksum = "46ec44dc15085cea82cf9c78f85a9114c463a369786585ad2882d1ff0b0acf40" dependencies = [ "windows-implement", "windows-interface", - "windows-result 0.2.0", - "windows-strings 0.1.0", - "windows-targets 0.52.6", + "windows-link", + "windows-result", + "windows-strings 0.4.1", +] + +[[package]] +name = "windows-future" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" +dependencies = [ + "windows-core", + "windows-link", + "windows-threading", ] [[package]] name = "windows-implement" -version = "0.58.0" +version = "0.60.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" +checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" dependencies = [ "proc-macro2", "quote", @@ -5115,9 +5073,9 @@ dependencies = [ [[package]] name = "windows-interface" -version = "0.58.0" +version = "0.59.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" +checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" dependencies = [ "proc-macro2", "quote", @@ -5131,49 +5089,49 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" [[package]] -name = "windows-registry" -version = "0.4.0" +name = "windows-numerics" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3" +checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" dependencies = [ - "windows-result 0.3.2", - "windows-strings 0.3.1", - "windows-targets 0.53.0", + "windows-core", + "windows-link", ] [[package]] -name = "windows-result" -version = "0.2.0" +name = "windows-registry" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3" dependencies = [ - "windows-targets 0.52.6", + "windows-result", + "windows-strings 0.3.1", + "windows-targets 0.53.0", ] [[package]] name = "windows-result" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252" +checksum = "4b895b5356fc36103d0f64dd1e94dfa7ac5633f1c9dd6e80fe9ec4adef69e09d" dependencies = [ "windows-link", ] [[package]] name = "windows-strings" -version = "0.1.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319" dependencies = [ - "windows-result 0.2.0", - "windows-targets 0.52.6", + "windows-link", ] [[package]] name = "windows-strings" -version = "0.3.1" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319" +checksum = "2a7ab927b2637c19b3dbe0965e75d8f2d30bdd697a1516191cad2ec4df8fb28a" dependencies = [ "windows-link", ] @@ -5252,6 +5210,15 @@ dependencies = [ "windows_x86_64_msvc 0.53.0", ] +[[package]] +name = "windows-threading" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" +dependencies = [ + "windows-link", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -5415,7 +5382,7 @@ version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", ] [[package]] @@ -5440,7 +5407,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8902160c4e6f2fb145dbe9d6760a75e3c9522d8bf796ed7047c85919ac7115f8" dependencies = [ "arraydeque", - "hashlink 0.8.4", + "hashlink", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index b0838d4..d68c61d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,7 @@ name = "weaver-workspace" [workspace.dependencies] serde = { version = "1.0", features = ["derive"] } -merde = { version = "10.0.6", features = ["full"] } +merde = { version = "10.0.6" } minijinja = { version = "2.9.0", default-features = false } minijinja-contrib = { version = "2.9.0", default-features = false } diff --git a/atproto b/atproto deleted file mode 160000 index efc64ba..0000000 --- a/atproto +++ /dev/null @@ -1 +0,0 @@ -Subproject commit efc64ba92511933c2100b45c0e7f4bcae9199240 diff --git a/crates/weaver-cli/Cargo.toml b/crates/weaver-cli/Cargo.toml index d88a908..83a5e4f 100644 --- a/crates/weaver-cli/Cargo.toml +++ b/crates/weaver-cli/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies] clap = { version = "4.5", features = ["derive", "env", "cargo", "unicode"] } n0-future = { workspace = true } -weaver-common = { path = "../weaver-common" } +weaver-common = { path = "../weaver-common", features = ["native"] } weaver-workspace-hack = { version = "0.1", path = "../weaver-workspace-hack" } miette = { workspace = true, features = ["fancy"] } @@ -27,3 +27,4 @@ serde_html_form = "0.2.7" # temp for testing tokio = { version = "1.45.0", features = ["full"] } rouille = { version = "3.6.2", features = ["rustls"] } +dirs = "6.0.0" diff --git a/crates/weaver-cli/src/main.rs b/crates/weaver-cli/src/main.rs index 5d34b18..793a7e6 100644 --- a/crates/weaver-cli/src/main.rs +++ b/crates/weaver-cli/src/main.rs @@ -1,68 +1,94 @@ -use atrium_api::agent::Agent; +use atrium_api::types::string::Did; use atrium_oauth::AuthorizeOptions; use atrium_oauth::CallbackParams; use atrium_oauth::KnownScope; use atrium_oauth::Scope; +use miette::miette; +use miette::{IntoDiagnostic, Result}; use rouille::Server; -use std::error; +use std::path::Path; +use std::path::PathBuf; use tokio::sync::mpsc; use weaver_common::agent::WeaverAgent; +use clap::{Args, Parser, Subcommand}; + +#[derive(Parser)] +#[command(version, about, long_about = None)] +#[command(propagate_version = true)] +struct Cli { + #[command(subcommand)] + command: Option, +} + +#[derive(Subcommand)] +enum Commands { + /// Authenticate with your atproto PDS, using your handle or the URL of the PDS. You can also set the HANDLE environment variable. + Auth(AuthArgs), + /// Test the native oauth client + Run, +} + +#[derive(Args)] +struct AuthArgs { + handle: Option, +} + #[tokio::main] -async fn main() -> Result<(), Box> { - let (tx, mut rx) = mpsc::channel(5); - let server = Server::new("0.0.0.0:4000", move |request| { - create_callback_router(request, tx.clone()) - }) - .expect("Could not start server"); - let (server_handle, server_stop) = server.stoppable(); - let client = weaver_common::oauth::default_native_oauth_client()?; - println!( - "To authenticate with your PDS, visit:\r\n\t {}", - client - .authorize( - std::env::var("HANDLE").unwrap_or(String::from("https://atproto.systems")), - AuthorizeOptions { - scopes: vec![ - Scope::Known(KnownScope::Atproto), - Scope::Known(KnownScope::TransitionGeneric) - ], - ..Default::default() - } - ) - .await? - ); +async fn main() -> Result<()> { + init_miette(); + let args = Cli::parse(); + let base_dir = weaver_common::filestore::config_dir(); + tokio::fs::create_dir_all(&base_dir) + .await + .into_diagnostic()?; + let client = weaver_common::oauth::test_native_oauth_client().into_diagnostic()?; + let (session, server_handle) = if let Some(Commands::Auth(AuthArgs { handle })) = args.command { + let handle = handle.unwrap_or(String::from("https://atproto.systems")); + let (tx, mut rx) = mpsc::channel(5); + let server = Server::new("0.0.0.0:4000", move |request| { + create_callback_router(request, tx.clone()) + }) + .expect("Could not start server"); + let (server_handle, server_stop) = server.stoppable(); + + println!( + "To authenticate with your PDS, visit:\r\n\t {}", + client + .authorize( + handle, + AuthorizeOptions { + scopes: vec![ + Scope::Known(KnownScope::Atproto), + Scope::Known(KnownScope::TransitionGeneric) + ], + ..Default::default() + } + ) + .await + .into_diagnostic()? + ); + + let params = rx.recv().await.unwrap(); + let (session, _) = client.callback(params).await.into_diagnostic()?; + server_stop + .send(()) + .expect("Failed to stop callback server"); + Ok::<_, weaver_common::Error>((session, Some(server_handle))) + } else { + let did = find_session_did(base_dir).await?; + let session = client.restore(&did).await.into_diagnostic()?; + Ok((session, None)) + }?; - let params = rx.recv().await.unwrap(); - let (session, _) = client.callback(params).await?; - server_stop - .send(()) - .expect("Failed to stop callback server"); let agent = WeaverAgent::new(session); let output = agent .get_profile_pds(agent.did().await.unwrap().into()) .await?; println!("{output:?}"); - - // let agent = Agent::new(session); - // let output = agent - // .api - // .app - // .bsky - // .feed - // .get_timeline( - // weaver_common::app::bsky::feed::get_timeline::ParametersData { - // algorithm: None, - // cursor: None, - // limit: 3.try_into().ok(), - // } - // .into(), - // ) - // .await?; - // for feed in &output.feed { - // println!("{feed:?}"); - // } - server_handle.join().unwrap(); + if let Some(server_handle) = server_handle { + server_handle.join().unwrap(); + } Ok(()) } @@ -86,3 +112,41 @@ pub fn create_callback_router( _ => rouille::Response::empty_404() ) } + +pub async fn find_session_did(path: impl AsRef) -> Result { + let path = path.as_ref(); + let mut dir = tokio::fs::read_dir(path).await.into_diagnostic()?; + while let Some(entry) = dir.next_entry().await.into_diagnostic()? { + let file_name = entry.file_name(); + if let Some(file_name) = file_name.to_str() { + if file_name.ends_with("_session.json") { + let did_string = file_name + .strip_suffix("_session.json") + .expect("we JUST checked the suffix lol") + .to_string(); + let did = Did::new(did_string).expect("we should only be writing valid dids"); + return Ok(did); + } + } + } + Err(miette!("couldn't find any existing sessions!")) +} + +fn init_miette() { + miette::set_hook(Box::new(|_| { + Box::new( + miette::MietteHandlerOpts::new() + .terminal_links(true) + //.rgb_colors(miette::RgbColors::) + .with_cause_chain() + .with_syntax_highlighting(miette::highlighters::SyntectHighlighter::default()) + .color(true) + .context_lines(5) + .tab_width(2) + .break_words(true) + .build(), + ) + })) + .expect("couldn't set the miette hook"); + miette::set_panic_hook(); +} diff --git a/crates/weaver-common/Cargo.toml b/crates/weaver-common/Cargo.toml index 78da97a..9e1393e 100644 --- a/crates/weaver-common/Cargo.toml +++ b/crates/weaver-common/Cargo.toml @@ -8,12 +8,13 @@ publish = false [features] default = ["dev"] dev = [] +native = ["tokio"] [dependencies] n0-future = { workspace = true } weaver-workspace-hack = { version = "0.1", path = "../weaver-workspace-hack" } markdown-weaver = { workspace = true } -libsqlite3-sys = { version = "0.30.1", features = ["bundled"] } +#libsqlite3-sys = { version = "0.30.1", features = ["bundled"] } http = "1.3.1" @@ -53,11 +54,12 @@ toml = "0.8.22" #jose = { version = "0.0.2", features = ["crypto-rustcrypto"] } jose-jwk = "0.1.2" reqwest = "0.12.15" - +tokio = { version = "1.44", features = ["full"], optional = true } tower-service = "0.3.3" tower-layer = "0.3.3" multibase = "0.9.1" +dirs = "6.0.0" diff --git a/crates/weaver-common/src/error.rs b/crates/weaver-common/src/error.rs index a10da3b..0c903c1 100644 --- a/crates/weaver-common/src/error.rs +++ b/crates/weaver-common/src/error.rs @@ -75,6 +75,9 @@ pub enum NetworkError { #[error("HTTP client error: {0}")] #[diagnostic_source] HttpClient(Box), + #[error("DNS TXT resolver error: {0}")] + #[diagnostic_source] + DnsTxtResolver(#[from] hickory_resolver::error::ResolveError), } /// Generic error type for XRPC errors. diff --git a/crates/weaver-common/src/filestore.rs b/crates/weaver-common/src/filestore.rs new file mode 100644 index 0000000..9fb3092 --- /dev/null +++ b/crates/weaver-common/src/filestore.rs @@ -0,0 +1,187 @@ +use crate::Error; +use crate::error::WeaverErrorKind; +use crate::error::{IoError, SerDeError}; +use atrium_api::types::string::Did; +use atrium_common::store::Store; +use atrium_oauth::store::session::Session; +use atrium_oauth::store::state::InternalStateData; +use std::path::{Path, PathBuf}; + +pub struct SimpleJsonFileSessionStore +where + T: AsRef, +{ + path: T, +} + +impl SimpleJsonFileSessionStore +where + T: AsRef, +{ + pub fn new(path: T) -> Self { + Self { path } + } + + pub async fn get_session(&self, did: &Did) -> Result, Error> { + let path = self + .path + .as_ref() + .join(format!("{}_session.json", did.as_str())); + let file = tokio::fs::read_to_string(path) + .await + .map_err(|e| Error::new(vec![WeaverErrorKind::from(IoError::from(e))])); + let file = if let Err(e) = &file { + println!("Failed to read session file: {e}"); + return Ok(None); + } else { + file? + }; + + let session = serde_json::from_str(&file) + .map_err(|e| Error::new(vec![WeaverErrorKind::from(SerDeError::from(e))]))?; + Ok(Some(session)) + } + + pub async fn set_session(&self, did: Did, session: Session) -> Result<(), Error> { + let path = self + .path + .as_ref() + .join(format!("{}_session.json", did.as_str())); + let file = serde_json::to_string(&session) + .map_err(|e| Error::new(vec![WeaverErrorKind::from(SerDeError::from(e))]))?; + + tokio::fs::write(path, file) + .await + .map_err(|e| Error::new(vec![WeaverErrorKind::from(IoError::from(e))]))?; + + Ok(()) + } + + pub async fn get_state(&self, key: &str) -> Result, Error> { + let path = self.path.as_ref().join(format!("{}_state.json", key)); + let file = tokio::fs::read_to_string(path) + .await + .map_err(|e| Error::new(vec![WeaverErrorKind::from(IoError::from(e))])); + let file = if let Err(e) = &file { + println!("Failed to read state file: {e}"); + return Ok(None); + } else { + file? + }; + let state = serde_json::from_str(&file) + .map_err(|e| Error::new(vec![WeaverErrorKind::from(SerDeError::from(e))]))?; + Ok(Some(state)) + } + + pub async fn set_state(&self, key: String, state: InternalStateData) -> Result<(), Error> { + let path = self.path.as_ref().join(format!("{}_state.json", key)); + + let file = serde_json::to_string(&state) + .map_err(|e| Error::new(vec![WeaverErrorKind::from(SerDeError::from(e))]))?; + + tokio::fs::write(path, file) + .await + .map_err(|e| Error::new(vec![WeaverErrorKind::from(IoError::from(e))]))?; + + Ok(()) + } +} + +impl Store for SimpleJsonFileSessionStore { + type Error = crate::Error; + + async fn get(&self, key: &Did) -> Result, Self::Error> { + self.get_session(key).await + } + + async fn set(&self, key: Did, value: Session) -> Result<(), Self::Error> { + self.set_session(key, value).await + } + + async fn del(&self, key: &Did) -> Result<(), Self::Error> { + let path = self.path.join(format!("{}_session.json", key.as_str())); + tokio::fs::remove_file(path) + .await + .map_err(|e| Error::new(vec![WeaverErrorKind::from(IoError::from(e))])) + } + + async fn clear(&self) -> Result<(), Self::Error> { + let mut files = tokio::fs::read_dir(&self.path) + .await + .map_err(|e| Error::new(vec![WeaverErrorKind::from(IoError::from(e))]))?; + while let Some(entry) = files + .next_entry() + .await + .map_err(|e| Error::new(vec![WeaverErrorKind::from(IoError::from(e))]))? + { + let file_name = entry.file_name(); + if let Some(file_name) = file_name.to_str() { + if file_name.ends_with("_session.json") { + tokio::fs::remove_file(entry.path()) + .await + .map_err(|e| Error::new(vec![WeaverErrorKind::from(IoError::from(e))]))?; + } + } + } + Ok(()) + } +} + +impl Store for SimpleJsonFileSessionStore { + type Error = crate::Error; + + async fn get(&self, key: &String) -> Result, Self::Error> { + self.get_state(key.as_str()).await + } + + async fn set(&self, key: String, value: InternalStateData) -> Result<(), Self::Error> { + self.set_state(key, value).await + } + + async fn del(&self, key: &String) -> Result<(), Self::Error> { + let path = self.path.join(format!("{}_state.json", key.as_str())); + tokio::fs::remove_file(path) + .await + .map_err(|e| Error::new(vec![WeaverErrorKind::from(IoError::from(e))])) + } + + async fn clear(&self) -> Result<(), Self::Error> { + let mut files = tokio::fs::read_dir(&self.path) + .await + .map_err(|e| Error::new(vec![WeaverErrorKind::from(IoError::from(e))]))?; + while let Some(entry) = files + .next_entry() + .await + .map_err(|e| Error::new(vec![WeaverErrorKind::from(IoError::from(e))]))? + { + let file_name = &entry.file_name(); + if let Some(file_name) = file_name.to_str() { + if file_name.ends_with("_state.json") { + tokio::fs::remove_file(entry.path()) + .await + .map_err(|e| Error::new(vec![WeaverErrorKind::from(IoError::from(e))]))?; + } + } + } + Ok(()) + } +} + +impl atrium_oauth::store::session::SessionStore for SimpleJsonFileSessionStore {} + +impl atrium_oauth::store::state::StateStore for SimpleJsonFileSessionStore {} + +impl Default for SimpleJsonFileSessionStore { + fn default() -> Self { + let path = dirs::config_dir() + .unwrap_or_else(|| PathBuf::from("./")) + .join("weaver/sessions"); + Self { path } + } +} + +pub fn config_dir() -> PathBuf { + dirs::config_dir() + .unwrap_or_else(|| PathBuf::from("./")) + .join("weaver/sessions") +} diff --git a/crates/weaver-common/src/lexicons/app/bsky/unspecced/get_config.rs b/crates/weaver-common/src/lexicons/app/bsky/unspecced/get_config.rs index 306245c..63fcd94 100644 --- a/crates/weaver-common/src/lexicons/app/bsky/unspecced/get_config.rs +++ b/crates/weaver-common/src/lexicons/app/bsky/unspecced/get_config.rs @@ -6,6 +6,8 @@ pub const NSID: &str = "app.bsky.unspecced.getConfig"; pub struct OutputData { #[serde(skip_serializing_if = "core::option::Option::is_none")] pub check_email_confirmed: core::option::Option, + #[serde(skip_serializing_if = "core::option::Option::is_none")] + pub live_now: core::option::Option>, } pub type Output = atrium_api::types::Object; #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] @@ -16,3 +18,10 @@ impl std::fmt::Display for Error { Ok(()) } } +#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct LiveNowConfigData { + pub did: atrium_api::types::string::Did, + pub domains: Vec, +} +pub type LiveNowConfig = atrium_api::types::Object; diff --git a/crates/weaver-common/src/lexicons/record.rs b/crates/weaver-common/src/lexicons/record.rs index 82d6503..e8b3126 100644 --- a/crates/weaver-common/src/lexicons/record.rs +++ b/crates/weaver-common/src/lexicons/record.rs @@ -65,6 +65,12 @@ pub enum KnownRecord { LexiconsShWeaverActorProfile( Box, ), + #[serde(rename = "sh.weaver.edit.cursor")] + LexiconsShWeaverEditCursor(Box), + #[serde(rename = "sh.weaver.edit.diff")] + LexiconsShWeaverEditDiff(Box), + #[serde(rename = "sh.weaver.edit.root")] + LexiconsShWeaverEditRoot(Box), #[serde(rename = "sh.weaver.notebook.authors")] LexiconsShWeaverNotebookAuthors( Box, @@ -304,6 +310,36 @@ impl From for KnownReco KnownRecord::LexiconsShWeaverActorProfile(Box::new(record_data.into())) } } +impl From for KnownRecord { + fn from(record: crate::lexicons::sh::weaver::edit::cursor::Record) -> Self { + KnownRecord::LexiconsShWeaverEditCursor(Box::new(record)) + } +} +impl From for KnownRecord { + fn from(record_data: crate::lexicons::sh::weaver::edit::cursor::RecordData) -> Self { + KnownRecord::LexiconsShWeaverEditCursor(Box::new(record_data.into())) + } +} +impl From for KnownRecord { + fn from(record: crate::lexicons::sh::weaver::edit::diff::Record) -> Self { + KnownRecord::LexiconsShWeaverEditDiff(Box::new(record)) + } +} +impl From for KnownRecord { + fn from(record_data: crate::lexicons::sh::weaver::edit::diff::RecordData) -> Self { + KnownRecord::LexiconsShWeaverEditDiff(Box::new(record_data.into())) + } +} +impl From for KnownRecord { + fn from(record: crate::lexicons::sh::weaver::edit::root::Record) -> Self { + KnownRecord::LexiconsShWeaverEditRoot(Box::new(record)) + } +} +impl From for KnownRecord { + fn from(record_data: crate::lexicons::sh::weaver::edit::root::RecordData) -> Self { + KnownRecord::LexiconsShWeaverEditRoot(Box::new(record_data.into())) + } +} impl From for KnownRecord { fn from(record: crate::lexicons::sh::weaver::notebook::authors::Record) -> Self { KnownRecord::LexiconsShWeaverNotebookAuthors(Box::new(record)) diff --git a/crates/weaver-common/src/lexicons/sh/weaver.rs b/crates/weaver-common/src/lexicons/sh/weaver.rs index 25ebf64..6c98d69 100644 --- a/crates/weaver-common/src/lexicons/sh/weaver.rs +++ b/crates/weaver-common/src/lexicons/sh/weaver.rs @@ -1,5 +1,6 @@ // @generated - This file is generated by esquema-codegen (forked from atrium-codegen). DO NOT EDIT. //!Definitions for the `sh.weaver` namespace. pub mod actor; +pub mod edit; pub mod embed; pub mod notebook; diff --git a/crates/weaver-common/src/lexicons/sh/weaver/edit.rs b/crates/weaver-common/src/lexicons/sh/weaver/edit.rs new file mode 100644 index 0000000..04c7939 --- /dev/null +++ b/crates/weaver-common/src/lexicons/sh/weaver/edit.rs @@ -0,0 +1,24 @@ +// @generated - This file is generated by esquema-codegen (forked from atrium-codegen). DO NOT EDIT. +//!Definitions for the `sh.weaver.edit` namespace. +pub mod cursor; +pub mod defs; +pub mod diff; +pub mod root; +#[derive(Debug)] +pub struct Cursor; +impl atrium_api::types::Collection for Cursor { + const NSID: &'static str = "sh.weaver.edit.cursor"; + type Record = cursor::Record; +} +#[derive(Debug)] +pub struct Diff; +impl atrium_api::types::Collection for Diff { + const NSID: &'static str = "sh.weaver.edit.diff"; + type Record = diff::Record; +} +#[derive(Debug)] +pub struct Root; +impl atrium_api::types::Collection for Root { + const NSID: &'static str = "sh.weaver.edit.root"; + type Record = root::Record; +} diff --git a/crates/weaver-common/src/lexicons/sh/weaver/edit/cursor.rs b/crates/weaver-common/src/lexicons/sh/weaver/edit/cursor.rs new file mode 100644 index 0000000..f95c410 --- /dev/null +++ b/crates/weaver-common/src/lexicons/sh/weaver/edit/cursor.rs @@ -0,0 +1,61 @@ +// @generated - This file is generated by esquema-codegen (forked from atrium-codegen). DO NOT EDIT. +//!Definitions for the `sh.weaver.edit.cursor` namespace. +use atrium_api::types::TryFromUnknown; +#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct RecordData { + pub container: ContainerId, + #[serde(skip_serializing_if = "core::option::Option::is_none")] + pub id: core::option::Option, + #[serde(skip_serializing_if = "core::option::Option::is_none")] + pub side: core::option::Option, +} +pub type Record = atrium_api::types::Object; +impl From for RecordData { + fn from(value: atrium_api::types::Unknown) -> Self { + Self::try_from_unknown(value).unwrap() + } +} +#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct ContainerIdData { + pub value: atrium_api::types::Union, +} +pub type ContainerId = atrium_api::types::Object; +#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct CursorSideData { + ///The side of an item the cursor is on (left = -1, right = 1, middle = 0) + pub value: i64, +} +pub type CursorSide = atrium_api::types::Object; +#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct IdData { + pub counter: i64, + pub peer: i64, +} +pub type Id = atrium_api::types::Object; +#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct NormalContainerIdData { + pub container_type: String, + pub counter: i64, + pub peer: i64, +} +pub type NormalContainerId = atrium_api::types::Object; +#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct RootContainerIdData { + pub container_type: String, + pub name: String, +} +pub type RootContainerId = atrium_api::types::Object; +#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] +#[serde(tag = "$type")] +pub enum ContainerIdValueRefs { + #[serde(rename = "sh.weaver.edit.cursor#normalContainerId")] + NormalContainerId(Box), + #[serde(rename = "sh.weaver.edit.cursor#rootContainerId")] + RootContainerId(Box), +} diff --git a/crates/weaver-common/src/lexicons/sh/weaver/edit/defs.rs b/crates/weaver-common/src/lexicons/sh/weaver/edit/defs.rs new file mode 100644 index 0000000..f691ada --- /dev/null +++ b/crates/weaver-common/src/lexicons/sh/weaver/edit/defs.rs @@ -0,0 +1,28 @@ +// @generated - This file is generated by esquema-codegen (forked from atrium-codegen). DO NOT EDIT. +//!Definitions for the `sh.weaver.edit.defs` namespace. +#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct DocRefData { + pub value: atrium_api::types::Union, +} +pub type DocRef = atrium_api::types::Object; +#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct EntryRefData { + pub notebook: crate::com::atproto::repo::strong_ref::Main, +} +pub type EntryRef = atrium_api::types::Object; +#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct NotebookRefData { + pub notebook: crate::com::atproto::repo::strong_ref::Main, +} +pub type NotebookRef = atrium_api::types::Object; +#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] +#[serde(tag = "$type")] +pub enum DocRefValueRefs { + #[serde(rename = "sh.weaver.edit.defs#notebookRef")] + NotebookRef(Box), + #[serde(rename = "sh.weaver.edit.defs#entryRef")] + EntryRef(Box), +} diff --git a/crates/weaver-common/src/lexicons/sh/weaver/edit/diff.rs b/crates/weaver-common/src/lexicons/sh/weaver/edit/diff.rs new file mode 100644 index 0000000..4f2f82b --- /dev/null +++ b/crates/weaver-common/src/lexicons/sh/weaver/edit/diff.rs @@ -0,0 +1,16 @@ +// @generated - This file is generated by esquema-codegen (forked from atrium-codegen). DO NOT EDIT. +//!Definitions for the `sh.weaver.edit.diff` namespace. +use atrium_api::types::TryFromUnknown; +#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct RecordData { + pub doc: crate::sh::weaver::edit::defs::DocRef, + pub root: crate::com::atproto::repo::strong_ref::Main, + pub snapshot: atrium_api::types::BlobRef, +} +pub type Record = atrium_api::types::Object; +impl From for RecordData { + fn from(value: atrium_api::types::Unknown) -> Self { + Self::try_from_unknown(value).unwrap() + } +} diff --git a/crates/weaver-common/src/lexicons/sh/weaver/edit/root.rs b/crates/weaver-common/src/lexicons/sh/weaver/edit/root.rs new file mode 100644 index 0000000..e9188c7 --- /dev/null +++ b/crates/weaver-common/src/lexicons/sh/weaver/edit/root.rs @@ -0,0 +1,17 @@ +// @generated - This file is generated by esquema-codegen (forked from atrium-codegen). DO NOT EDIT. +//!Definitions for the `sh.weaver.edit.root` namespace. +use atrium_api::types::TryFromUnknown; +#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct RecordData { + pub cid: atrium_api::types::string::Cid, + pub doc: crate::sh::weaver::edit::defs::DocRef, + pub snapshot: atrium_api::types::BlobRef, + pub uri: String, +} +pub type Record = atrium_api::types::Object; +impl From for RecordData { + fn from(value: atrium_api::types::Unknown) -> Self { + Self::try_from_unknown(value).unwrap() + } +} diff --git a/crates/weaver-common/src/lexicons/sh/weaver/notebook/book.rs b/crates/weaver-common/src/lexicons/sh/weaver/notebook/book.rs index 6433281..aa2bcea 100644 --- a/crates/weaver-common/src/lexicons/sh/weaver/notebook/book.rs +++ b/crates/weaver-common/src/lexicons/sh/weaver/notebook/book.rs @@ -5,11 +5,14 @@ use atrium_api::types::TryFromUnknown; #[serde(rename_all = "camelCase")] pub struct RecordData { pub authors: crate::sh::weaver::notebook::defs::AuthorListView, - pub cid: atrium_api::types::string::Cid, + ///Client-declared timestamp when this was originally created. #[serde(skip_serializing_if = "core::option::Option::is_none")] pub created_at: core::option::Option, pub entry_list: Vec, - pub uri: String, + #[serde(skip_serializing_if = "core::option::Option::is_none")] + pub tags: core::option::Option, + #[serde(skip_serializing_if = "core::option::Option::is_none")] + pub title: core::option::Option, } pub type Record = atrium_api::types::Object; impl From for RecordData { diff --git a/crates/weaver-common/src/lexicons/sh/weaver/notebook/defs.rs b/crates/weaver-common/src/lexicons/sh/weaver/notebook/defs.rs index 6070299..d5eb121 100644 --- a/crates/weaver-common/src/lexicons/sh/weaver/notebook/defs.rs +++ b/crates/weaver-common/src/lexicons/sh/weaver/notebook/defs.rs @@ -40,9 +40,28 @@ pub struct EntryViewData { pub record: atrium_api::types::Unknown, #[serde(skip_serializing_if = "core::option::Option::is_none")] pub rendered_view: core::option::Option, + #[serde(skip_serializing_if = "core::option::Option::is_none")] + pub tags: core::option::Option, + #[serde(skip_serializing_if = "core::option::Option::is_none")] + pub title: core::option::Option, pub uri: String, } pub type EntryView = atrium_api::types::Object<EntryViewData>; +#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct NotebookViewData { + #[serde(skip_serializing_if = "core::option::Option::is_none")] + pub authors: core::option::Option<AuthorListView>, + pub cid: atrium_api::types::string::Cid, + pub indexed_at: atrium_api::types::string::Datetime, + pub record: atrium_api::types::Unknown, + #[serde(skip_serializing_if = "core::option::Option::is_none")] + pub tags: core::option::Option<Tags>, + #[serde(skip_serializing_if = "core::option::Option::is_none")] + pub title: core::option::Option<Title>, + pub uri: String, +} +pub type NotebookView = atrium_api::types::Object<NotebookViewData>; ///View of a rendered and cached notebook entry #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] #[serde(rename_all = "camelCase")] @@ -52,3 +71,7 @@ pub struct RenderedViewData { pub html: atrium_api::types::BlobRef, } pub type RenderedView = atrium_api::types::Object<RenderedViewData>; +///An array of tags associated with the notebook entry. Tags can help categorize and organize entries. +pub type Tags = Vec<String>; +///The title of the notebook entry. +pub type Title = String; diff --git a/crates/weaver-common/src/lexicons/sh/weaver/notebook/entry.rs b/crates/weaver-common/src/lexicons/sh/weaver/notebook/entry.rs index 987385b..f24ffa9 100644 --- a/crates/weaver-common/src/lexicons/sh/weaver/notebook/entry.rs +++ b/crates/weaver-common/src/lexicons/sh/weaver/notebook/entry.rs @@ -6,13 +6,14 @@ use atrium_api::types::TryFromUnknown; pub struct RecordData { ///The content of the notebook entry. This should be some flavor of Markdown. pub content: String, - pub created_at: CreatedAt, + ///Client-declared timestamp when this was originally created. + pub created_at: atrium_api::types::string::Datetime, ///The set of images, if any, embedded in the notebook entry. #[serde(skip_serializing_if = "core::option::Option::is_none")] pub images: core::option::Option<crate::sh::weaver::embed::images::Main>, #[serde(skip_serializing_if = "core::option::Option::is_none")] - pub tags: core::option::Option<Tags>, - pub title: Title, + pub tags: core::option::Option<crate::sh::weaver::notebook::defs::Tags>, + pub title: crate::sh::weaver::notebook::defs::Title, } pub type Record = atrium_api::types::Object<RecordData>; impl From<atrium_api::types::Unknown> for RecordData { @@ -20,9 +21,3 @@ impl From<atrium_api::types::Unknown> for RecordData { Self::try_from_unknown(value).unwrap() } } -///The date and time when the notebook entry was created. This is used for sorting and displaying the entry's creation date. -pub type CreatedAt = String; -///An array of tags associated with the notebook entry. Tags can help categorize and organize entries. -pub type Tags = Vec<String>; -///The title of the notebook entry. -pub type Title = String; diff --git a/crates/weaver-common/src/lib.rs b/crates/weaver-common/src/lib.rs index 0e2f72a..d173e9a 100644 --- a/crates/weaver-common/src/lib.rs +++ b/crates/weaver-common/src/lib.rs @@ -1,6 +1,9 @@ pub mod agent; pub mod config; pub mod error; +/// This filestore is very much not production ready +#[cfg(all(feature = "native", feature = "dev"))] +pub mod filestore; pub mod lexicons; pub mod oauth; pub mod resolver; diff --git a/crates/weaver-common/src/oauth.rs b/crates/weaver-common/src/oauth.rs index 377add3..b7866c8 100644 --- a/crates/weaver-common/src/oauth.rs +++ b/crates/weaver-common/src/oauth.rs @@ -28,6 +28,23 @@ pub struct NativeOAuthClient { pub http_client: Arc<WeaverHttpClient>, } +pub type NativeBasicOAuthSession = OAuthSession< + DefaultHttpClient, + CommonDidResolver<WeaverHttpClient>, + AtprotoHandleResolver<HickoryDnsTxtResolver, WeaverHttpClient>, + MemoryStore<Did, Session>, +>; + +pub struct NativeWeaverOAuthClient<STATE, SESS> +where + STATE: StateStore + Send + Sync + 'static, + SESS: SessionStore + Send + Sync + 'static, + STATE::Error: std::error::Error + Send + Sync + 'static, + SESS::Error: std::error::Error + Send + Sync + 'static, +{ + oauth: WeaverOAuthClient<STATE, SESS>, + pub http_client: Arc<WeaverHttpClient>, +} impl NativeOAuthClient { pub async fn authorize( &self, @@ -45,11 +62,39 @@ impl NativeOAuthClient { } } -pub type NativeBasicOAuthSession = OAuthSession< +#[cfg(all(feature = "native", feature = "dev"))] +impl + NativeWeaverOAuthClient< + crate::filestore::SimpleJsonFileSessionStore<std::path::PathBuf>, + crate::filestore::SimpleJsonFileSessionStore<std::path::PathBuf>, + > +{ + pub async fn authorize( + &self, + input: impl AsRef<str>, + options: AuthorizeOptions, + ) -> Result<String, atrium_oauth::Error> { + self.oauth.authorize(input, options).await + } + + pub async fn callback( + &self, + params: CallbackParams, + ) -> Result<(WeaverOAuthSession, Option<String>), atrium_oauth::Error> { + self.oauth.callback(params).await + } + + pub async fn restore(&self, did: &Did) -> Result<WeaverOAuthSession, atrium_oauth::Error> { + self.oauth.restore(did).await + } +} + +#[cfg(all(feature = "native", feature = "dev"))] +pub type WeaverOAuthSession = OAuthSession< DefaultHttpClient, CommonDidResolver<WeaverHttpClient>, AtprotoHandleResolver<HickoryDnsTxtResolver, WeaverHttpClient>, - MemoryStore<Did, Session>, + crate::filestore::SimpleJsonFileSessionStore<std::path::PathBuf>, >; pub type NativeBasicOAuthClient = atrium_oauth::OAuthClient< @@ -138,6 +183,42 @@ pub fn default_oauth_client( Ok(client) } +#[cfg(all(feature = "native", feature = "dev"))] +pub fn test_native_oauth_client() -> Result< + NativeWeaverOAuthClient< + crate::filestore::SimpleJsonFileSessionStore<std::path::PathBuf>, + crate::filestore::SimpleJsonFileSessionStore<std::path::PathBuf>, + >, + atrium_oauth::Error, +> { + use crate::filestore::SimpleJsonFileSessionStore; + + let http_client = Arc::new(WeaverHttpClient::default()); + let config = OAuthClientConfig { + client_metadata: default_native_client_metadata(), + keys: None, + resolver: OAuthResolverConfig { + did_resolver: CommonDidResolver::new(CommonDidResolverConfig { + plc_directory_url: DEFAULT_PLC_DIRECTORY_URL.to_string(), + http_client: Arc::clone(&http_client), + }), + handle_resolver: AtprotoHandleResolver::new(AtprotoHandleResolverConfig { + dns_txt_resolver: HickoryDnsTxtResolver::default(), + http_client: Arc::clone(&http_client), + }), + authorization_server_metadata: Default::default(), + protected_resource_metadata: Default::default(), + }, + state_store: SimpleJsonFileSessionStore::default(), + session_store: SimpleJsonFileSessionStore::default(), + }; + let client = NativeWeaverOAuthClient { + oauth: OAuthClient::new(config)?, + http_client: Arc::clone(&http_client), + }; + Ok(client) +} + pub fn default_native_oauth_client() -> Result<NativeOAuthClient, atrium_oauth::Error> { let http_client = Arc::new(WeaverHttpClient::default()); let config = OAuthClientConfig { diff --git a/crates/weaver-common/src/resolver.rs b/crates/weaver-common/src/resolver.rs index 2840645..2f4a716 100644 --- a/crates/weaver-common/src/resolver.rs +++ b/crates/weaver-common/src/resolver.rs @@ -18,11 +18,12 @@ impl DnsTxtResolver for HickoryDnsTxtResolver { async fn resolve( &self, query: &str, - ) -> core::result::Result<Vec<String>, Box<dyn std::error::Error + Send + Sync + 'static>> { + ) -> core::result::Result<Vec<String>, Box<dyn std::error::Error + Send + Sync>> { Ok(self .resolver .txt_lookup(query) - .await? + .await + .map_err(crate::error::NetworkError::from)? .iter() .map(|txt| txt.to_string()) .collect()) diff --git a/crates/weaver-renderer/Cargo.toml b/crates/weaver-renderer/Cargo.toml index 8aa77b2..6133bd9 100644 --- a/crates/weaver-renderer/Cargo.toml +++ b/crates/weaver-renderer/Cargo.toml @@ -13,3 +13,5 @@ weaver-common = { path = "../weaver-common" } weaver-workspace-hack = { version = "0.1", path = "../weaver-workspace-hack" } compact_string = "0.1.0" +http = "1.3.1" +url = "2.5.4" diff --git a/crates/weaver-renderer/src/lib.rs b/crates/weaver-renderer/src/lib.rs index 288422d..c5c42c3 100644 --- a/crates/weaver-renderer/src/lib.rs +++ b/crates/weaver-renderer/src/lib.rs @@ -1,6 +1,6 @@ //! Weaver renderer //! -//! This crate works with the weaver-markdown crate to render and optionally upload markdown notebooks to your ATProto PDS. +//! This crate works with the weaver-markdown crate to render and optionally upload markdown notebooks to your Atproto PDS. //! pub mod types; diff --git a/crates/weaver-renderer/src/types.rs b/crates/weaver-renderer/src/types.rs index f620d6a..bb24079 100644 --- a/crates/weaver-renderer/src/types.rs +++ b/crates/weaver-renderer/src/types.rs @@ -1,5 +1,11 @@ use atrium_api::types::string::{Cid, Did}; use compact_string::CompactString; +use http::Uri; + +pub struct Link { + pub uri: Uri, + pub blob: BlobLink, +} pub type MimeType = CompactString; @@ -24,14 +30,30 @@ pub enum CdnLink { impl std::fmt::Display for BlobLink { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!( - f, - "{}{}/{}@{}", - self.url_prefix(), - self.did().as_str(), - self.cid().as_ref(), - self.mime_type().rsplit('/').next().unwrap() - ) + match self { + BlobLink::PDS { + pds_host, + did, + cid, + mime_type: _, + } => { + write!( + f, + "{}/xrpc/com.atproto.sync.getBlob?did={}&cid={}", + pds_host, + did.as_str(), + cid.as_ref() + ) + } + _ => write!( + f, + "{}{}/{}@{}", + self.url_prefix(), + self.did().as_str(), + self.cid().as_ref(), + self.mime_type().rsplit('/').next().unwrap() + ), + } } } diff --git a/crates/weaver-workspace-hack/Cargo.toml b/crates/weaver-workspace-hack/Cargo.toml index 106e16d..31a07cf 100644 --- a/crates/weaver-workspace-hack/Cargo.toml +++ b/crates/weaver-workspace-hack/Cargo.toml @@ -33,7 +33,6 @@ generic-array = { version = "0.14", default-features = false, features = ["more_ group = { version = "0.13", default-features = false, features = ["alloc"] } hashbrown = { version = "0.15", features = ["serde"] } idna = { version = "1" } -libsqlite3-sys = { version = "0.30", features = ["bundled"] } log = { version = "0.4", default-features = false, features = ["std"] } memchr = { version = "2", features = ["use_std"] } miette = { version = "7", features = ["fancy", "syntect-highlighter"] } @@ -43,7 +42,7 @@ num-traits = { version = "0.2", default-features = false, features = ["i128", "l p384 = { version = "0.13", default-features = false, features = ["ecdsa"] } percent-encoding = { version = "2" } pkcs8 = { version = "0.10", default-features = false, features = ["pem"] } -proc-macro2 = { version = "1", features = ["span-locations"] } +proc-macro2 = { version = "1" } quote = { version = "1" } rand_core = { version = "0.6", default-features = false, features = ["std"] } reqwest = { version = "0.12", features = ["gzip", "json", "rustls-tls"] } @@ -69,7 +68,7 @@ data-encoding = { version = "2" } diesel_derives = { version = "2", features = ["32-column-tables", "chrono", "postgres", "sqlite", "with-deprecated"] } either = { version = "1", features = ["use_std"] } hashbrown = { version = "0.15", features = ["serde"] } -proc-macro2 = { version = "1", features = ["span-locations"] } +proc-macro2 = { version = "1" } quote = { version = "1" } serde = { version = "1", features = ["alloc", "derive"] } syn = { version = "2", features = ["extra-traits", "fold", "full", "visit", "visit-mut"] } diff --git a/lexicon-codegen.sh b/lexicon-codegen.sh index 3e5375b..5fa05c2 100755 --- a/lexicon-codegen.sh +++ b/lexicon-codegen.sh @@ -2,11 +2,19 @@ #cargo install esquema-cli --locked --git https://github.com/fatfingers23/esquema.git + rm -rf ./target/lexicons mkdir -p ./target/lexicons +cd target +git clone -n --depth=1 --filter=tree:0 \ +https://github.com/bluesky-social/atproto.git +cd atproto +git sparse-checkout set --no-cone /lexicons +git checkout +cd .. -cp -r ./lexicons ./target/lexicons -cp -r ./atproto/lexicons ./target/lexicons +cp -r ../lexicons ./ +cp -r ./atproto/lexicons ./ -~/.cargo/bin/esquema-cli generate local --lexdir ./target/lexicons/ --outdir ./crates/weaver-common/src/ --module lexicons +~/.cargo/bin/esquema-cli generate local --lexdir ./lexicons/ --outdir ../crates/weaver-common/src/ --module lexicons diff --git a/lexicons/sh/weaver/edit/cursor.json b/lexicons/sh/weaver/edit/cursor.json new file mode 100644 index 0000000..da84639 --- /dev/null +++ b/lexicons/sh/weaver/edit/cursor.json @@ -0,0 +1,81 @@ +{ + "lexicon": 1, + "id": "sh.weaver.edit.cursor", + "defs": { + "main": { + "type": "record", + "description": "An edit record for a notebook.", + "key": "tid", + "record": { + "type": "object", + "required": ["container", "die"], + "properties": { + "id": { + "type": "ref", + "ref": "#id" + }, + "container": { + "type": "ref", + "ref": "#containerId" + }, + "side": { + "type": "ref", + "ref": "#cursorSide" + } + } + } + }, + "id": { + "type": "object", + "required": ["peer", "counter"], + "properties": { + "peer": { "type": "integer" }, + "counter": { "type": "integer" } + } + }, + "cursorSide": { + "type": "object", + "required": ["value"], + "properties": { + "value": { + "type": "integer", + "description": "The side of an item the cursor is on (left = -1, right = 1, middle = 0)", + "enum": [-1, 0, 1] + } + } + }, + "containerId": { + "type": "object", + "required": ["value"], + "properties": { + "value": { + "type": "union", + "refs": ["#normalContainerId", "#rootContainerId"] + } + } + }, + "normalContainerId": { + "type": "object", + "required": ["peer", "counter", "container_type"], + "properties": { + "peer": { "type": "integer" }, + "counter": { "type": "integer" }, + "container_type": { + "type": "string", + "enum": ["Map", "List", "Text", "Tree", "MovableList", "Counter"] + } + } + }, + "rootContainerId": { + "type": "object", + "required": ["name", "container_type"], + "properties": { + "name": { "type": "string" }, + "container_type": { + "type": "string", + "enum": ["Map", "List", "Text", "Tree", "MovableList", "Counter"] + } + } + } + } +} diff --git a/lexicons/sh/weaver/edit/defs.json b/lexicons/sh/weaver/edit/defs.json new file mode 100644 index 0000000..9a8fd9c --- /dev/null +++ b/lexicons/sh/weaver/edit/defs.json @@ -0,0 +1,36 @@ +{ + "lexicon": 1, + "id": "sh.weaver.edit.defs", + "defs": { + "docRef": { + "type": "object", + "required": ["value"], + "properties": { + "value": { + "type": "union", + "refs": ["#notebookRef", "#entryRef"] + } + } + }, + "notebookRef": { + "type": "object", + "required": ["notebook"], + "properties": { + "notebook": { + "type": "ref", + "ref": "com.atproto.repo.strongRef" + } + } + }, + "entryRef": { + "type": "object", + "required": ["notebook"], + "properties": { + "notebook": { + "type": "ref", + "ref": "com.atproto.repo.strongRef" + } + } + } + } +} diff --git a/lexicons/sh/weaver/edit/diff.json b/lexicons/sh/weaver/edit/diff.json new file mode 100644 index 0000000..9cd13ee --- /dev/null +++ b/lexicons/sh/weaver/edit/diff.json @@ -0,0 +1,30 @@ +{ + "lexicon": 1, + "id": "sh.weaver.edit.diff", + "defs": { + "main": { + "type": "record", + "description": "An edit record for a notebook.", + "key": "tid", + "record": { + "type": "object", + "required": ["snapshot", "root", "doc"], + "properties": { + "snapshot": { + "type": "blob", + "accept": ["*/*"], + "maxSize": 3000000 + }, + "root": { + "type": "ref", + "ref": "com.atproto.repo.strongRef" + }, + "doc": { + "type": "ref", + "ref": "sh.weaver.edit.defs#docRef" + } + } + } + } + } +} diff --git a/lexicons/sh/weaver/edit/root.json b/lexicons/sh/weaver/edit/root.json new file mode 100644 index 0000000..a14366b --- /dev/null +++ b/lexicons/sh/weaver/edit/root.json @@ -0,0 +1,28 @@ +{ + "lexicon": 1, + "id": "sh.weaver.edit.root", + "defs": { + "main": { + "type": "record", + "description": "The starting point for edit history on a notebook.", + "key": "tid", + "record": { + "type": "object", + "required": ["cid", "uri", "doc", "snapshot"], + "properties": { + "uri": { "type": "string", "format": "at-uri" }, + "cid": { "type": "string", "format": "cid" }, + "snapshot": { + "type": "blob", + "accept": ["*/*"], + "maxSize": 30000000 + }, + "doc": { + "type": "ref", + "ref": "sh.weaver.edit.defs#docRef" + } + } + } + } + } +} diff --git a/lexicons/sh/weaver/notebook/book.json b/lexicons/sh/weaver/notebook/book.json index 7fd541e..71fd85e 100644 --- a/lexicons/sh/weaver/notebook/book.json +++ b/lexicons/sh/weaver/notebook/book.json @@ -8,10 +8,10 @@ "key": "tid", "record": { "type": "object", - "required": ["cid", "uri", "authors", "entryList"], + "required": ["authors", "entryList"], "properties": { - "uri": { "type": "string", "format": "at-uri" }, - "cid": { "type": "string", "format": "cid" }, + "title": { "type": "ref", "ref": "sh.weaver.notebook.defs#title" }, + "tags": { "type": "ref", "ref": "sh.weaver.notebook.defs#tags" }, "authors": { "type": "ref", "ref": "sh.weaver.notebook.defs#authorListView" @@ -23,7 +23,11 @@ "ref": "sh.weaver.notebook.defs#bookEntryView" } }, - "createdAt": { "type": "string", "format": "datetime" } + "createdAt": { + "type": "string", + "format": "datetime", + "description": "Client-declared timestamp when this was originally created." + } } } } diff --git a/lexicons/sh/weaver/notebook/defs.json b/lexicons/sh/weaver/notebook/defs.json index 3b9c9e0..ed73fc9 100644 --- a/lexicons/sh/weaver/notebook/defs.json +++ b/lexicons/sh/weaver/notebook/defs.json @@ -2,11 +2,30 @@ "lexicon": 1, "id": "sh.weaver.notebook.defs", "defs": { + "notebookView": { + "type": "object", + "required": ["uri", "cid", "author", "record", "indexedAt"], + + "properties": { + "title": { "type": "ref", "ref": "#title" }, + "tags": { "type": "ref", "ref": "#tags" }, + "uri": { "type": "string", "format": "at-uri" }, + "cid": { "type": "string", "format": "cid" }, + "authors": { + "type": "ref", + "ref": "#authorListView" + }, + "record": { "type": "unknown" }, + "indexedAt": { "type": "string", "format": "datetime" } + } + }, "entryView": { "type": "object", "required": ["uri", "cid", "author", "record", "indexedAt"], "properties": { + "title": { "type": "ref", "ref": "#title" }, + "tags": { "type": "ref", "ref": "#tags" }, "uri": { "type": "string", "format": "at-uri" }, "cid": { "type": "string", "format": "cid" }, "authors": { @@ -79,6 +98,20 @@ "ref": "#entryView" } } + }, + "title": { + "type": "string", + "maxLength": 420, + "description": "The title of the notebook entry." + }, + "tags": { + "type": "array", + "items": { + "type": "string", + "maxLength": 64 + }, + "maxLength": 10, + "description": "An array of tags associated with the notebook entry. Tags can help categorize and organize entries." } } } diff --git a/lexicons/sh/weaver/notebook/entry.json b/lexicons/sh/weaver/notebook/entry.json index 7a3b1e6..3a96d0a 100644 --- a/lexicons/sh/weaver/notebook/entry.json +++ b/lexicons/sh/weaver/notebook/entry.json @@ -10,8 +10,8 @@ "type": "object", "required": ["content", "title", "createdAt"], "properties": { - "title": { "type": "ref", "ref": "#title" }, - "tags": { "type": "ref", "ref": "#tags" }, + "title": { "type": "ref", "ref": "sh.weaver.notebook.defs#title" }, + "tags": { "type": "ref", "ref": "sh.weaver.notebook.defs#tags" }, "content": { "type": "string", @@ -20,8 +20,9 @@ }, "createdAt": { - "type": "ref", - "ref": "#createdAt" + "type": "string", + "format": "datetime", + "description": "Client-declared timestamp when this was originally created." }, "images": { "type": "ref", @@ -30,26 +31,6 @@ } } } - }, - - "createdAt": { - "type": "string", - "format": "datetime", - "description": "The date and time when the notebook entry was created. This is used for sorting and displaying the entry's creation date." - }, - "title": { - "type": "string", - "maxLength": 420, - "description": "The title of the notebook entry." - }, - "tags": { - "type": "array", - "items": { - "type": "string", - "maxLength": 64 - }, - "maxLength": 10, - "description": "An array of tags associated with the notebook entry. Tags can help categorize and organize entries." } } } diff --git a/tangled/core b/tangled/core deleted file mode 160000 index c1b5f8a..0000000 --- a/tangled/core +++ /dev/null @@ -1 +0,0 @@ -Subproject commit c1b5f8af08545deb46da789c376be2309fa40355 diff --git a/test.html b/test.html index 5126da7..e9b9d3e 100644 --- a/test.html +++ b/test.html @@ -3,6 +3,13 @@ <head> <meta charset="utf-8"> </head> + <script> + console.log( window.location.href ); // whatever your current location href is +window.history.replaceState( {} , 'foo', './LICENSE' ); +console.log( window.location.href ); // oh, hey, it replaced the path with /foo + + +</script> <body> <h1>Main Title & "Special Chars"</h1> <p>This is a paragraph with <em>emphasis</em>, <strong>strong emphasis</strong>, <del>strikethrough</del>, and <code>inline code</code>. @@ -15,6 +22,7 @@ multiple lines.</p> </blockquote> </blockquote> <hr /> + <h2>Lists and Links</h2> <ul> <li><p>Unordered item 1</p> -- knotmirror 0.0.1