diff --git a/.cargo/audit.toml b/.cargo/audit.toml index 0663fe8..436b172 100644 --- a/.cargo/audit.toml +++ b/.cargo/audit.toml @@ -16,4 +16,20 @@ ignore = [ # Copal deserializes no rkyv archive on any path. Re-evaluate # whenever surrealdb moves to a rust_decimal built on rkyv 0.8. "RUSTSEC-2026-0235", + # RUSTSEC-2026-0194 and RUSTSEC-2026-0195 (quick-xml < 0.41: + # quadratic duplicate-attribute check, unbounded namespace + # allocation in NsReader) reach the lockfile as quick-xml 0.39 + # through object_store 0.13.2's `aws` backend, which surrealdb-core + # 3.3.0 enables on native targets; object_store 0.14 takes the + # fixed quick-xml, but surrealdb-core pins 0.13. Unlike in kayak, + # it IS compiled into the shipped server: the embedded tier is a + # default feature (`cargo tree -i quick-xml@0.39.4 -e normal`). It + # runs only when the engine talks to an S3-backed SurrealDB + # bucket, and Copal defines none: no `DEFINE BUCKET` exists here, + # and the blob tiers reach S3 through opendal, which resolves the + # fixed quick-xml. Tracked upstream as surrealdb/surrealdb#7568; + # remove both entries when surrealdb-core moves to object_store + # 0.14 or stops enabling `aws`. + "RUSTSEC-2026-0194", + "RUSTSEC-2026-0195", ] diff --git a/CHANGELOG.md b/CHANGELOG.md index bd77d5f..3089c17 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -246,6 +246,49 @@ Copal has not cut a release yet. Everything below is the road to 0.1.0. ### Changed +- **surql 0.34 and SurrealDB 3.3.** The workspace takes oneiriq-surql + 0.34 and kayak at the commit that moved to it, the minimum Rust + version rises to 1.95 with surql's, the `surrealdb` floors to 3.3, + and the compose, conformance, and scale-bench engines to v3.3.0. + Three behaviours moved with it: + + - A changed index now arrives from surql's diff as `ModifyIndex` + rather than as an add, and boot routed only adds through the + backgrounded `CONCURRENTLY` path, so a new embedding width would + have rebuilt the HNSW index synchronously and held boot for the + length of the rebuild. Both now take the backgrounded path. + - SurrealDB 3.3 can refuse a `DEFINE INDEX` while it reclaims the + table's document ids after an index was removed or overwritten + ("still being reclaimed"). Boot now retries that refusal on a + backoff of about half a minute in all, and applies its schema + statement by statement, so the retry repeats only the refused + statement rather than overwriting the indexes ahead of it again, + which would start another reclaim. + - A schemafull `option` field takes object items on 3.3. The + engine assumption that pinned the refusal now pins acceptance; + `file_version.markers` and `file_text.withheld` stay `TYPE any` + until a migration moves them. + + `.cargo/audit.toml` carries the two quick-xml advisories + (RUSTSEC-2026-0194/0195) that SurrealDB 3.3's engine brings in + through object_store 0.13. The embedded tier compiles them into the + server, but they parse only an S3 bucket backend's replies, and + Copal defines no SurrealDB bucket. + + Kayak's newer generators came with it, and the artifacts are + re-blessed: + + - The MCP manifest lists each sub-collection as a tool, + `file_versions_list` and `webhook_deliveries_list`, and the MCP + face now routes them through the dispatcher's sub-list, so an agent + can page a file's versions or a webhook's deliveries. + - The TypeScript client, and so the TypeScript SDK, names fields the + way the wire does (`content_type`, `created_at`, ...). The + camelCase names it carried before were never on any response, so + code reading them got `undefined`. + - `docs/openapi.json` lists the values the files `state` filter + takes. + - **Copal is licensed under Apache-2.0.** The repository moves from AGPL-3.0-only to the Apache License, Version 2.0, the license Kayak already ships under, so Copal can be embedded, modified, and run as diff --git a/Cargo.lock b/Cargo.lock index 15e5996..3315da6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -71,19 +71,17 @@ dependencies = [ [[package]] name = "affinitypool" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a46f56d354df11b6bcd8ca4f84fa03ac816cc41c72568a1b337d8f7e5af90e" +checksum = "a487a26c23775316bc010e9425fd7cf046c384ab37efbb2cfd4ba87a58f68c6d" dependencies = [ "arc-swap", "async-task", "crossbeam-deque", "crossbeam-utils", - "libc", "num_cpus", "parking_lot", "thiserror 2.0.21", - "winapi", ] [[package]] @@ -349,28 +347,6 @@ dependencies = [ "windows-sys 0.61.2", ] -[[package]] -name = "async-stream" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" -dependencies = [ - "async-stream-impl", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-stream-impl" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.119", -] - [[package]] name = "async-task" version = "4.7.1" @@ -704,6 +680,29 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64fa3c856b712db6612c019f14756e64e4bcea13337a6b33b696333a9eaa2d06" +[[package]] +name = "bytecheck" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26333eeac754f0ad8a6bcd0eb0ac012156302e4e16b852b72ee399aea4f12c29" +dependencies = [ + "bytecheck_derive", + "ptr_meta", + "rancor", + "simdutf8", +] + +[[package]] +name = "bytecheck_derive" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46d07918caa9eeaaf06b7873925c53a61daac173539b4f7715090745e44e4e69" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.6", +] + [[package]] name = "bytemuck" version = "1.25.2" @@ -1145,16 +1144,6 @@ dependencies = [ "ulid 3.0.0", ] -[[package]] -name = "core-foundation" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "core-foundation" version = "0.10.1" @@ -1201,6 +1190,12 @@ dependencies = [ "libc", ] +[[package]] +name = "crawdad" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abed0ad19907fc8472dae05f0418dfa82fdf0eaef18427c7c7cc4e42db41534b" + [[package]] name = "crc-fast" version = "1.10.0" @@ -1357,6 +1352,27 @@ dependencies = [ "smallvec", ] +[[package]] +name = "csv" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52cd9d68cf7efc6ddfaaee42e7288d3a99d613d4b50f76ce9827ae0c6e14f938" +dependencies = [ + "csv-core", + "itoa", + "ryu", + "serde_core", +] + +[[package]] +name = "csv-core" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "704a3c26996a80471189265814dbc2c257598b96b8a7feae2d31ace646bb9782" +dependencies = [ + "memchr", +] + [[package]] name = "ctr" version = "0.10.1" @@ -1402,6 +1418,12 @@ dependencies = [ "syn 2.0.119", ] +[[package]] +name = "daachorse" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd10668980c9e7ba8aa2e616207d9ec52f7db66ebb47db857ed1f3c342530dad" + [[package]] name = "darling" version = "0.20.11" @@ -1664,9 +1686,9 @@ dependencies = [ [[package]] name = "diskann" -version = "0.54.0" +version = "0.56.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "421c6cf955c6cb1451d36c8a3740ab2a22880265d0fa93d8ea22cbc425c90479" +checksum = "3ead115d8a4f3917c1ae9c3db0aa4dd56251841864ef8637329969f8e5145dd3" dependencies = [ "anyhow", "bytemuck", @@ -1684,9 +1706,9 @@ dependencies = [ [[package]] name = "diskann-utils" -version = "0.54.0" +version = "0.56.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cdf7d491910fbff13338e07460c9197a3c172268cfd4d8f8e69e5cec5a256d9" +checksum = "ac627181d402b5dd63318e434fc2e7107843be0a10cf0a6a99a24666453239bc" dependencies = [ "bytemuck", "cfg-if", @@ -1701,9 +1723,9 @@ dependencies = [ [[package]] name = "diskann-vector" -version = "0.54.0" +version = "0.56.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de1643bbece645f03527ef120bc7dd5e4e40557980dbe52ee51129adfb58a851" +checksum = "0ee9ba401eba2a12cea01aba7ee2ba7c755019f2b73c2417fecc49a2da26dd4c" dependencies = [ "cfg-if", "diskann-wide", @@ -1712,9 +1734,9 @@ dependencies = [ [[package]] name = "diskann-wide" -version = "0.54.0" +version = "0.56.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "421f02c42e57a2153dc65b66b4b95fe2be56e14bf9f95253b663abcac8521166" +checksum = "343f4ea154bad7f8a9c6936746379faa880899165740a20092775bec97c9a141" dependencies = [ "cfg-if", "half", @@ -1780,16 +1802,6 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" -[[package]] -name = "earcutr" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79127ed59a85d7687c409e9978547cffb7dc79675355ed22da6b66fd5f6ead01" -dependencies = [ - "itertools 0.11.0", - "num-traits", -] - [[package]] name = "ecdsa" version = "0.16.9" @@ -1869,6 +1881,15 @@ dependencies = [ "simdutf8", ] +[[package]] +name = "encoding_rs_io" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fba3fe847045ecff794b9c138293a80db914678c453ad63fbf0c6a9eb6e00b22" +dependencies = [ + "encoding_rs", +] + [[package]] name = "equivalent" version = "1.0.2" @@ -1882,7 +1903,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -2230,7 +2251,6 @@ version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f3901269ec6d4f6068d3f09e5f02f995bd076398dcd1dfec407cd230b02d11b" dependencies = [ - "earcutr", "float_next_after", "geo-types", "geographiclib-rs", @@ -2242,7 +2262,6 @@ dependencies = [ "rstar 0.12.2", "serde", "sif-itree", - "spade", ] [[package]] @@ -2253,7 +2272,6 @@ checksum = "777d18aa0f12f8b285331cd867133ee14422b3f023f6d388034c47d43e28786a" dependencies = [ "approx", "num-traits", - "rayon", "rstar 0.10.0", "rstar 0.11.0", "rstar 0.12.2", @@ -2333,6 +2351,12 @@ dependencies = [ "weezl", ] +[[package]] +name = "glob" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4eba85ea1d0a966a983acd07deee566e67395d2d96b6fb39e62b5a833f1eb0b" + [[package]] name = "group" version = "0.13.0" @@ -2677,6 +2701,7 @@ dependencies = [ "hyper", "hyper-util", "rustls", + "rustls-native-certs", "tokio", "tokio-rustls", "tower-service", @@ -2715,11 +2740,9 @@ dependencies = [ "percent-encoding", "pin-project-lite", "socket2", - "system-configuration", "tokio", "tower-service", "tracing", - "windows-registry", ] [[package]] @@ -2747,7 +2770,6 @@ dependencies = [ "i_key_sort", "i_shape", "i_tree", - "rayon", ] [[package]] @@ -2998,15 +3020,6 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" -[[package]] -name = "itertools" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" -dependencies = [ - "either", -] - [[package]] name = "itertools" version = "0.13.0" @@ -3229,6 +3242,50 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" +[[package]] +name = "lindera" +version = "6.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acdfde95c0360c7214c7f97cbd52f293c41da5c7f215979b065b2b41772d199f" +dependencies = [ + "anyhow", + "lindera-dictionary", + "log", + "percent-encoding", + "serde", + "serde_json", + "strum 0.28.0", + "strum_macros 0.28.0", + "url", +] + +[[package]] +name = "lindera-dictionary" +version = "6.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e68a62cebe5344df42b4458f603c973a4b2ad997af4a0d55d72a9def1ac47701" +dependencies = [ + "anyhow", + "byteorder", + "crawdad", + "csv", + "daachorse", + "encoding_rs", + "encoding_rs_io", + "glob", + "log", + "memchr", + "memmap2", + "once_cell", + "rayon", + "rkyv", + "serde", + "serde_json", + "strum 0.28.0", + "strum_macros 0.28.0", + "thiserror 2.0.21", +] + [[package]] name = "line-clipping" version = "0.3.8" @@ -3271,6 +3328,38 @@ version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6" +[[package]] +name = "logos" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb2c55a318a87600ea870ff8c2012148b44bf18b74fad48d0f835c38c7d07c5f" +dependencies = [ + "logos-derive", +] + +[[package]] +name = "logos-codegen" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58b3ffaa284e1350d017a57d04ada118c4583cf260c8fb01e0fe28a2e9cf8970" +dependencies = [ + "fnv", + "proc-macro2", + "quote", + "regex-automata", + "regex-syntax", + "syn 2.0.119", +] + +[[package]] +name = "logos-derive" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52d3a9855747c17eaf4383823f135220716ab49bea5fbea7dd42cc9a92f8aa31" +dependencies = [ + "logos-codegen", +] + [[package]] name = "lru" version = "0.18.5" @@ -3414,6 +3503,15 @@ version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" +[[package]] +name = "memmap2" +version = "0.9.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1219ed1b7f229ee7104d281dd01d6802fe28bb6e95d292942c4daacdeb798c0" +dependencies = [ + "libc", +] + [[package]] name = "memmem" version = "0.1.1" @@ -3516,6 +3614,26 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "743fb55ba31b18fb1ecef6bdc9aa2743314978ac084044301a7eee33fb99a20d" +[[package]] +name = "munge" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e17401f259eba956ca16491461b6e8f72913a0a114e39736ce404410f915a0c" +dependencies = [ + "munge_macro", +] + +[[package]] +name = "munge_macro" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4568f25ccbd45ab5d5603dc34318c1ec56b117531781260002151b8530a9f931" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "ndarray" version = "0.17.2" @@ -3743,16 +3861,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "622acbc9100d3c10e2ee15804b0caa40e55c933d5aa53814cd520805b7958a49" dependencies = [ "async-trait", + "base64 0.22.1", "bytes", "chrono", + "form_urlencoded", "futures-channel", "futures-core", "futures-util", "http", + "http-body-util", + "httparse", "humantime", + "hyper", "itertools 0.14.0", + "md-5 0.10.6", "parking_lot", "percent-encoding", + "quick-xml 0.39.4", + "rand 0.10.3", + "reqwest 0.12.28", + "ring", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", "thiserror 2.0.21", "tokio", "tracing", @@ -3777,7 +3909,7 @@ checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" [[package]] name = "oneiriq-kayak" version = "0.1.0" -source = "git+ssh://git@github.com/Oneiriq/kayak.git?branch=main#29f24b0a9df5ec243dd057162005482a0525ff40" +source = "git+ssh://git@github.com/Oneiriq/kayak.git?branch=main#268ac8d5a109df2e375b0d4300043a00679e1e2b" dependencies = [ "async-graphql", "futures-core", @@ -3791,15 +3923,14 @@ dependencies = [ [[package]] name = "oneiriq-surql" -version = "0.33.1" +version = "0.34.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "848847dfe6e4dcd68023544c22716cef7dc9b3228f3a40317fbdb3c33bf5c854" +checksum = "a76bfda83732851be70c4721c0cedd5bba9769eb45159cc946c781ce0959a667" dependencies = [ "chrono", "futures", "getrandom 0.4.3", "regex", - "reqwest 0.12.28", "serde", "serde_json", "sha2 0.11.0", @@ -4600,19 +4731,30 @@ dependencies = [ ] [[package]] -name = "prost-types" -version = "0.14.4" +name = "psl-types" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac" + +[[package]] +name = "ptr_meta" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f94967dc7688f3054c7fac87473ffae4cc4c3904800e2d9f5b857246d8963b0a" +checksum = "743da816b98c921cdbe8628ef7381b76f25ecf4da599fc80aca90eae7ef70cc0" dependencies = [ - "prost", + "ptr_meta_derive", ] [[package]] -name = "psl-types" -version = "2.0.11" +name = "ptr_meta_derive" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac" +checksum = "1c8d9ca532f185d5d4db7a7c9d51420b452168ea1c2b913953281bd6fe1fcbd0" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.6", +] [[package]] name = "pxfm" @@ -4626,6 +4768,16 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" +[[package]] +name = "quick-xml" +version = "0.39.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdcc8dd4e2f670d309a5f0e83fe36dfdc05af317008fea29144da1a2ac858e5e" +dependencies = [ + "memchr", + "serde", +] + [[package]] name = "quick-xml" version = "0.41.0" @@ -4712,7 +4864,7 @@ dependencies = [ "once_cell", "socket2", "tracing", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -4736,6 +4888,15 @@ version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" +[[package]] +name = "rancor" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b534442d0fcdb55d66f373d9cac6d33b6293a2335bc2136dbd06ce0e87d2572" +dependencies = [ + "ptr_meta", +] + [[package]] name = "rand" version = "0.8.8" @@ -5002,6 +5163,15 @@ version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" +[[package]] +name = "rend" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "663ba70707f96e871406fe10d68128412e619b06d1d47cb91c3a4c6501176240" +dependencies = [ + "bytecheck", +] + [[package]] name = "reqsign-aws-core" version = "3.2.0" @@ -5122,8 +5292,8 @@ checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" dependencies = [ "base64 0.22.1", "bytes", - "encoding_rs", "futures-core", + "futures-util", "h2", "http", "http-body", @@ -5133,11 +5303,11 @@ dependencies = [ "hyper-util", "js-sys", "log", - "mime", "percent-encoding", "pin-project-lite", "quinn", "rustls", + "rustls-native-certs", "rustls-pki-types", "serde", "serde_json", @@ -5145,12 +5315,14 @@ dependencies = [ "sync_wrapper", "tokio", "tokio-rustls", + "tokio-util", "tower", "tower-http 0.6.11", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", + "wasm-streams 0.4.2", "web-sys", "webpki-roots 1.0.9", ] @@ -5193,7 +5365,7 @@ dependencies = [ "url", "wasm-bindgen", "wasm-bindgen-futures", - "wasm-streams", + "wasm-streams 0.5.0", "web-sys", ] @@ -5248,6 +5420,36 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rkyv" +version = "0.8.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9776093b7ca170454ab1406954f7b7d97a57c51dc6c0642957fb2ef25c2d399" +dependencies = [ + "bytecheck", + "bytes", + "hashbrown 0.17.1", + "indexmap", + "munge", + "ptr_meta", + "rancor", + "rend", + "rkyv_derive", + "tinyvec", + "uuid", +] + +[[package]] +name = "rkyv_derive" +version = "0.8.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c25ef604ac7dd839d44d64648952ea23c97866f124ff671b0ed2cf3ad9bb06e" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.6", +] + [[package]] name = "rmp" version = "0.8.15" @@ -5440,7 +5642,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -5487,7 +5689,7 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1167586491e2b18b8bfbb293e8180ec17c201c4f076d7cb3070ca964e7598f98" dependencies = [ - "core-foundation 0.10.1", + "core-foundation", "core-foundation-sys", "jni", "log", @@ -5499,7 +5701,7 @@ dependencies = [ "security-framework", "security-framework-sys", "webpki-root-certs", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -5598,7 +5800,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" dependencies = [ "bitflags 2.13.2", - "core-foundation 0.10.1", + "core-foundation", "core-foundation-sys", "libc", "security-framework-sys", @@ -5621,7 +5823,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b55fb86dfd3a2f5f76ea78310a88f96c4ea21a3031f8d212443d56123fd0521" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -5878,18 +6080,6 @@ dependencies = [ "windows-sys 0.61.2", ] -[[package]] -name = "spade" -version = "2.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9699399fd9349b00b184f5635b074f9ec93afffef30c853f8c875b32c0f8c7fa" -dependencies = [ - "hashbrown 0.16.1", - "num-traits", - "robust", - "smallvec", -] - [[package]] name = "spin" version = "0.9.9" @@ -5979,6 +6169,17 @@ dependencies = [ "quote", ] +[[package]] +name = "stringprep" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1" +dependencies = [ + "unicode-bidi", + "unicode-normalization", + "unicode-properties", +] + [[package]] name = "strsim" version = "0.11.1" @@ -6035,9 +6236,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "surrealdb" -version = "3.2.4" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01fef5cc04dd6cb042391d48c0f78a586c56042e999f8cb17f0b97b0a147e2c0" +checksum = "f04b42991e6a01e2d01f1ea6183714cf364d3c40fa2197bd8993ec7834e0b4c4" dependencies = [ "anyhow", "async-channel", @@ -6055,13 +6256,18 @@ dependencies = [ "semver", "serde", "serde_json", - "surrealdb-core", + "surrealdb-engine-api", + "surrealdb-engine-local", + "surrealdb-iam", + "surrealdb-kvs", + "surrealdb-rpc", "surrealdb-types", "surrealdb-types-derive", "tokio", "tokio-tungstenite", "tokio-tungstenite-wasm", "tokio-util", + "tonic", "tracing", "url", "uuid", @@ -6071,70 +6277,112 @@ dependencies = [ "web-sys", ] +[[package]] +name = "surrealdb-catalog" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "467526a3b49854f7ea1fb1d5948eee35973700791018a093b62ae366de87df4e" +dependencies = [ + "ahash", + "anyhow", + "chrono", + "md-5 0.10.6", + "revision", + "serde", + "sha2 0.10.9", + "storekey", + "surrealdb-collections", + "surrealdb-common", + "surrealdb-expr", + "surrealdb-iam", + "surrealdb-kvs", + "surrealdb-sql", + "surrealdb-strand", + "surrealdb-syn", + "surrealdb-types", + "thiserror 2.0.21", + "tracing", + "uuid", +] + +[[package]] +name = "surrealdb-cnf" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcdec4b7e7287d812c48b58e3495f7204524a2b31d51c20dbca6eff2d32d36e" +dependencies = [ + "num-traits", + "path-clean", + "surrealdb-common", + "surrealdb-parse-common", + "tracing", +] + [[package]] name = "surrealdb-collections" -version = "3.2.4" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3472955f9692427583e78476d5b03c6f750bf11dc8a04383e0d365d7bd5d99" +checksum = "90aed29a6512c5974634412cb3ad07c91a5b99353ec9bc7d96f4ae7491f243cf" dependencies = [ "revision", "storekey", ] +[[package]] +name = "surrealdb-common" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a1273ef6215f5b40c78a3e43a4ada9c0cb7199d839f25745b71fee57dae0ca0" +dependencies = [ + "chrono", + "futures", + "hashbrown 0.16.1", + "parking_lot", + "phf 0.13.1", + "rust_decimal", + "surrealdb-types", + "sysinfo", + "thiserror 2.0.21", + "tokio", + "unicase", + "wasmtimer", +] + [[package]] name = "surrealdb-core" -version = "3.2.4" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cd76c36f8b545a9371eec050bb2ae83750a6f60bae8c6d92d06956943348f4c" +checksum = "1490b831b5090b9bdbdacec5e8060d9dbc1944574809d157fabb4de25e53b1aa" dependencies = [ - "addr", - "affinitypool", "ahash", - "ammonia", "anyhow", + "arc-swap", "argon2", "async-channel", - "async-stream", "base64 0.22.1", "bcrypt", - "blake3", "bytes", "chrono", "ciborium", "dashmap", - "deunicode", - "diskann", - "diskann-utils", - "diskann-vector", - "dmp", "ext-sort", - "fastnum", - "fst", "futures", - "fuzzy-matcher", "geo", "geo-types", "getrandom 0.3.4", - "half", "headers", "hex", "http", - "humantime", "ipnet", "jsonwebtoken", - "lexicmp", "md-5 0.10.6", "memchr", "mime", - "ndarray", - "ndarray-stats", - "num-traits", "num_cpus", "object_store", "parking_lot", "path-clean", "pbkdf2", - "phf 0.13.1", "pin-project-lite", "quick_cache", "rand 0.9.5", @@ -6145,7 +6393,6 @@ dependencies = [ "revision", "ring", "roaring", - "rust-stemmers", "rust_decimal", "scrypt", "semver", @@ -6154,70 +6401,464 @@ dependencies = [ "sha1 0.10.7", "sha2 0.10.9", "storekey", - "strsim", "subtle", + "surrealdb-catalog", + "surrealdb-cnf", "surrealdb-collections", - "surrealdb-protocol", + "surrealdb-common", + "surrealdb-datastore", + "surrealdb-expr", + "surrealdb-iam", + "surrealdb-idx", + "surrealdb-kvs", + "surrealdb-kvs-any", + "surrealdb-observe", + "surrealdb-rpc", + "surrealdb-runtime", + "surrealdb-sql", "surrealdb-strand", + "surrealdb-syn", "surrealdb-types", - "surrealkv", - "surrealmx", "sysinfo", "tempfile", "thiserror 2.0.21", "tokio", "tokio-util", "tracing", - "ulid 1.2.1", - "unicase", "url", "uuid", - "vart", "wasm-bindgen-futures", "wasmtimer", "web-time", ] +[[package]] +name = "surrealdb-datastore" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c36f4accb0bf3f90f4072dc4e3ada965c2fe2a5adbde1b18be55ddbd62703f7c" +dependencies = [ + "anyhow", + "blake3", + "bytes", + "chrono", + "parking_lot", + "quick_cache", + "rand 0.9.5", + "revision", + "roaring", + "semver", + "serde", + "storekey", + "surrealdb-catalog", + "surrealdb-cnf", + "surrealdb-collections", + "surrealdb-common", + "surrealdb-expr", + "surrealdb-iam", + "surrealdb-keyspace-macro", + "surrealdb-kvs", + "surrealdb-observe", + "surrealdb-rpc", + "surrealdb-strand", + "surrealdb-types", + "thiserror 2.0.21", + "tokio", + "tokio-util", + "tracing", + "uuid", + "web-time", +] + +[[package]] +name = "surrealdb-engine-api" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff233f2d7c1b5b0eac9f54abb01aaaa42dc466c381095d6b16588ae95482383" +dependencies = [ + "async-channel", + "surrealdb-rpc", + "surrealdb-types", + "tokio", + "uuid", +] + +[[package]] +name = "surrealdb-engine-local" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a354808ead8cdaead6ba4bc00318405739d869cf249911e16013f35cd927cbfd" +dependencies = [ + "anyhow", + "async-channel", + "futures", + "surrealdb-cnf", + "surrealdb-core", + "surrealdb-datastore", + "surrealdb-engine-api", + "surrealdb-iam", + "surrealdb-kvs", + "surrealdb-rpc", + "surrealdb-types", + "tokio", + "tokio-util", + "tracing", + "uuid", + "wasm-bindgen-futures", + "wasmtimer", +] + +[[package]] +name = "surrealdb-expr" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e494e4696ac372ead8c0a8b38f830db056a34c8f4192be4cfadeea3089c8687" +dependencies = [ + "anyhow", + "bytes", + "chrono", + "dmp", + "fastnum", + "geo", + "geo-types", + "half", + "hex", + "http", + "jsonwebtoken", + "lexicmp", + "quick_cache", + "rand 0.9.5", + "reblessive", + "regex", + "revision", + "rust_decimal", + "serde", + "serde_json", + "storekey", + "surrealdb-cnf", + "surrealdb-collections", + "surrealdb-common", + "surrealdb-iam", + "surrealdb-kvs", + "surrealdb-sql", + "surrealdb-strand", + "surrealdb-syn", + "surrealdb-types", + "thiserror 2.0.21", + "tracing", + "ulid 1.2.1", + "uuid", +] + +[[package]] +name = "surrealdb-iam" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ebf02070f99ebcdeb672b8ca8ca1ebe6b7f287c399ff868c1ac15a9e9702bc" +dependencies = [ + "anyhow", + "argon2", + "base64 0.22.1", + "hmac 0.12.1", + "pbkdf2", + "rand_core 0.6.4", + "revision", + "serde", + "sha2 0.10.9", + "stringprep", + "subtle", + "thiserror 2.0.21", + "tracing", +] + +[[package]] +name = "surrealdb-idx" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1871d2912896d5ae39d04e3989a20f3a69b8286b95a86a9c8ba2831fbb938e49" +dependencies = [ + "ahash", + "anyhow", + "bytes", + "dashmap", + "deunicode", + "diskann", + "diskann-utils", + "diskann-vector", + "fst", + "half", + "lindera", + "ndarray", + "ndarray-stats", + "parking_lot", + "quick_cache", + "rand 0.9.5", + "reblessive", + "roaring", + "rust-stemmers", + "storekey", + "surrealdb-catalog", + "surrealdb-cnf", + "surrealdb-common", + "surrealdb-datastore", + "surrealdb-expr", + "surrealdb-kvs", + "surrealdb-runtime", + "surrealdb-strand", + "surrealdb-types", + "thiserror 2.0.21", + "tokio", + "tracing", + "uuid", + "vart", + "web-time", +] + +[[package]] +name = "surrealdb-keyspace-macro" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "911cd40a40f9ed6372c6b462157a4249a1fde0a0648b713805a5884018afdda2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "surrealdb-kvs" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0b95075a800cc6c566506440ec2febde31e0ee21f48bc5fc1f2bc7c3bb6ea6e" +dependencies = [ + "affinitypool", + "anyhow", + "chrono", + "num_cpus", + "revision", + "roaring", + "surrealdb-cnf", + "surrealdb-common", + "surrealdb-types", + "thiserror 2.0.21", + "tracing", + "web-time", +] + +[[package]] +name = "surrealdb-kvs-any" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d40f18b879bce7ce4c1017dfdbd84feba9fc4a46a15e68084239ba498cb24b" +dependencies = [ + "surrealdb-cnf", + "surrealdb-kvs", + "surrealdb-kvs-mem", + "surrealdb-kvs-surrealkv", + "tokio-util", + "tracing", +] + +[[package]] +name = "surrealdb-kvs-mem" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27a9c2f9830dcb58a208c9ee18b2720b80e614821ea370b386f706bb1df336c1" +dependencies = [ + "affinitypool", + "chrono", + "surrealdb-cnf", + "surrealdb-kvs", + "surrealmx", + "tokio", + "tracing", +] + +[[package]] +name = "surrealdb-kvs-surrealkv" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d9f5f0b906db793730a7ee6baa0512189b4c07593b80b0f59e38b225c9c5b14" +dependencies = [ + "affinitypool", + "chrono", + "parking_lot", + "surrealdb-cnf", + "surrealdb-common", + "surrealdb-kvs", + "surrealkv", + "tokio", + "tracing", +] + +[[package]] +name = "surrealdb-observe" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09954bd399347da4ac4edaa9462f5074838648eac032c9b815edb1a2dee91815" +dependencies = [ + "surrealdb-iam", + "surrealdb-rpc", + "surrealdb-types", + "uuid", +] + +[[package]] +name = "surrealdb-parse-common" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01b6b07e5e179c8993ddcf3bcddd34d8c781846df0b37157a4f37cfddf7c9257" +dependencies = [ + "chrono", + "logos", + "uuid", +] + [[package]] name = "surrealdb-protocol" -version = "0.10.2" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f4e06f586c9179a02349b88b0c18e3a0850c55431aa513e0cd66529c00da1af" +checksum = "d53501c853fe88d5ead8e50612d310b43389f3c66fda7ef323a1af6c393809c6" dependencies = [ "anyhow", "async-trait", "bytes", "chrono", "flatbuffers", - "futures", "geo", - "prost", - "prost-types", "rust_decimal", "semver", "serde", "serde_json", - "tonic", - "tonic-prost", + "uuid", +] + +[[package]] +name = "surrealdb-rpc" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e6d64c1a7783562566122795d56da73f83647fc7229f944b0558817bbe897b0" +dependencies = [ + "anyhow", + "humantime", + "ipnet", + "revision", + "serde", + "surrealdb-cnf", + "surrealdb-common", + "surrealdb-iam", + "surrealdb-types", + "thiserror 2.0.21", + "tracing", + "url", + "uuid", + "web-time", +] + +[[package]] +name = "surrealdb-runtime" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e9d6ee0def941387d16dbf3730e1fc8faa38d477102035e6d8ba7f3f112676c" +dependencies = [ + "addr", + "ammonia", + "anyhow", + "argon2", + "bcrypt", + "blake3", + "chrono", + "deunicode", + "fuzzy-matcher", + "geo", + "md-5 0.10.6", + "pbkdf2", + "rand 0.9.5", + "rand_core 0.6.4", + "reblessive", + "regex", + "rust_decimal", + "scrypt", + "semver", + "sha1 0.10.7", + "sha2 0.10.9", + "strsim", + "surrealdb-cnf", + "surrealdb-common", + "surrealdb-expr", + "surrealdb-strand", + "surrealdb-syn", + "surrealdb-types", + "ulid 1.2.1", + "url", + "uuid", +] + +[[package]] +name = "surrealdb-sql" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6397f3b9141dbceca638116045b525c9f31bea3a6b374ab3546fa052bfb07e33" +dependencies = [ + "bytes", + "chrono", + "geo", + "getrandom 0.3.4", + "hex", + "phf 0.13.1", + "rand 0.9.5", + "regex", + "rust_decimal", + "serde", + "surrealdb-common", + "surrealdb-iam", + "surrealdb-strand", + "surrealdb-types", + "unicase", "uuid", ] [[package]] name = "surrealdb-strand" -version = "3.2.4" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a86f53e307b6b8275b15eaff2b718add63605cb804395d156589770c3bf38e56" +checksum = "adc99fc8f56f55b3bcadd4ee4fe6ec4811dc04a3e686099fd0c69af7ee4edde0" dependencies = [ "revision", "serde", "storekey", ] +[[package]] +name = "surrealdb-syn" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab01f470fa61bc45a4c46286f7ba94297d6ec7c46708845d9e164311fb8e443" +dependencies = [ + "bytes", + "chrono", + "geo", + "phf 0.13.1", + "reblessive", + "regex", + "rust_decimal", + "surrealdb-cnf", + "surrealdb-common", + "surrealdb-iam", + "surrealdb-sql", + "surrealdb-strand", + "surrealdb-types", + "thiserror 2.0.21", + "tracing", + "unicase", + "uuid", +] + [[package]] name = "surrealdb-types" -version = "3.2.4" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0d70c7f4dbf1198521282a171a03f2f77f38a1225a149f7c0175e758f773b8a" +checksum = "18cd057ad378914c5c32701d8e2298fc0b717dd07b087d895627832d7c834051" dependencies = [ "anyhow", "async-channel", @@ -6226,6 +6867,8 @@ dependencies = [ "chrono", "flatbuffers", "geo", + "getrandom 0.2.17", + "getrandom 0.3.4", "hex", "http", "papaya", @@ -6235,6 +6878,7 @@ dependencies = [ "semver", "serde", "serde_json", + "surrealdb-parse-common", "surrealdb-protocol", "surrealdb-types-derive", "tracing", @@ -6245,9 +6889,9 @@ dependencies = [ [[package]] name = "surrealdb-types-derive" -version = "3.2.4" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc11310bfc0ae3e546cd14788f8d36e7616dbe41fa68b4b265b29fea34a7d7e1" +checksum = "f53d89700a64a5c249a23a3436e4b2091099d9074ace28effa757421ea37f0b9" dependencies = [ "heck 0.4.1", "proc-macro2", @@ -6286,9 +6930,9 @@ dependencies = [ [[package]] name = "surrealmx" -version = "0.22.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e8a87f050a4860832ccf4a53e43ea264e98d27618983602b5c575e6df296054" +checksum = "1b5f1002984c1c3918014d924435a7280a6de620dadd51d4db59de4f56e7202c" dependencies = [ "arc-swap", "bincode", @@ -6373,27 +7017,6 @@ dependencies = [ "windows", ] -[[package]] -name = "system-configuration" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" -dependencies = [ - "bitflags 2.13.2", - "core-foundation 0.9.4", - "system-configuration-sys", -] - -[[package]] -name = "system-configuration-sys" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "tempfile" version = "3.27.0" @@ -6404,7 +7027,7 @@ dependencies = [ "getrandom 0.4.3", "once_cell", "rustix", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -6749,22 +7372,13 @@ dependencies = [ "socket2", "sync_wrapper", "tokio", + "tokio-rustls", "tokio-stream", "tower", "tower-layer", "tower-service", "tracing", -] - -[[package]] -name = "tonic-prost" -version = "0.14.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50849f68853be452acf590cde0b146665b8d507b3b8af17261df47e02c209ea0" -dependencies = [ - "bytes", - "prost", - "tonic", + "webpki-roots 1.0.9", ] [[package]] @@ -6994,12 +7608,33 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142" +[[package]] +name = "unicode-bidi" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" + [[package]] name = "unicode-ident" version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d245f478577f809a851594d02313b640fb437e0bb33866753cff937863096954" +[[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-properties" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7df058c713841ad818f1dc5d3fd88063241cc61f49f5fbea4b951e8cf5a8d71d" + [[package]] name = "unicode-segmentation" version = "1.13.3" @@ -7224,6 +7859,19 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "wasm-streams" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "wasm-streams" version = "0.5.0" @@ -7409,7 +8057,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -7449,8 +8097,8 @@ dependencies = [ "windows-implement", "windows-interface", "windows-link 0.1.3", - "windows-result 0.3.4", - "windows-strings 0.4.2", + "windows-result", + "windows-strings", ] [[package]] @@ -7508,17 +8156,6 @@ dependencies = [ "windows-link 0.1.3", ] -[[package]] -name = "windows-registry" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720" -dependencies = [ - "windows-link 0.2.1", - "windows-result 0.4.1", - "windows-strings 0.5.1", -] - [[package]] name = "windows-result" version = "0.3.4" @@ -7528,15 +8165,6 @@ dependencies = [ "windows-link 0.1.3", ] -[[package]] -name = "windows-result" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" -dependencies = [ - "windows-link 0.2.1", -] - [[package]] name = "windows-strings" version = "0.4.2" @@ -7546,15 +8174,6 @@ dependencies = [ "windows-link 0.1.3", ] -[[package]] -name = "windows-strings" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" -dependencies = [ - "windows-link 0.2.1", -] - [[package]] name = "windows-sys" version = "0.52.0" diff --git a/Cargo.toml b/Cargo.toml index 5a8ac33..f6b3cd1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ members = [ [workspace.package] version = "0.1.0" edition = "2021" -rust-version = "1.94" +rust-version = "1.95" license = "Apache-2.0" repository = "https://github.com/Oneiriq/copal" authors = ["Shon Thomas "] @@ -26,9 +26,10 @@ copal-sign = { path = "crates/copal-sign" } copal-flow = { path = "crates/copal-flow" } # Schema, query building, and the SurrealDB client all come from -# surql-rs, taken from the registry. 0.32 is the batched release the -# adoption work was written against. -oneiriq-surql = { version = "0.33", default-features = false, features = ["client-rustls"] } +# surql-rs, taken from the registry. 0.34 is the release that follows +# SurrealDB 3.3. Kayak (git, below in copal-server) must name the same +# minor, or its schema types and these are two different crates. +oneiriq-surql = { version = "0.34", default-features = false, features = ["client-rustls"] } serde = { version = "1", features = ["derive"] } serde_json = "1" diff --git a/bench/scale.sh b/bench/scale.sh index 9408098..7aeb0ec 100644 --- a/bench/scale.sh +++ b/bench/scale.sh @@ -80,7 +80,7 @@ if [ -z "$COPAL_BENCH_DB_URL" ]; then ENGINE_VERSION=$(sed -n 's/.*surrealdb\/surrealdb:\(v[0-9.]*\).*/\1/p' \ ../conformance/docker-compose.yml | head -1) if docker run --rm -d --name copal-scale-engine -p 127.0.0.1:18000:8000 \ - "surrealdb/surrealdb:${ENGINE_VERSION:-v3.2.4}" \ + "surrealdb/surrealdb:${ENGINE_VERSION:-v3.3.0}" \ start --user root --pass root > /dev/null 2>&1; then STARTED_ENGINE=1 COPAL_BENCH_DB_URL=ws://127.0.0.1:18000 diff --git a/clients/client.ts b/clients/client.ts index 8a09e55..6b3ba79 100644 --- a/clients/client.ts +++ b/clients/client.ts @@ -5,13 +5,13 @@ export interface File { path: string state: string access: string - contentType: string + content_type: string size?: number digest?: string metadata: unknown - versionCount: number - createdAt: string - updatedAt: string + version_count: number + created_at: string + updated_at: string } export interface FilePage { @@ -22,12 +22,12 @@ export interface FilePage { export interface FileVersion { id: string number: number - contentType: string + content_type: string size: number digest: string - metadataSnapshot: unknown - createdBy?: string - createdAt: string + metadata_snapshot: unknown + created_by?: string + created_at: string } export interface FileVersionPage { @@ -37,10 +37,10 @@ export interface FileVersionPage { export interface Webhook { id: string - targetUrl: string + target_url: string events: string active: boolean - createdAt: string + created_at: string } export interface WebhookPage { @@ -52,9 +52,9 @@ export interface WebhookDelivery { id: string state: string attempts: number - lastStatus?: number - nextAttemptAt?: string - createdAt: string + last_status?: number + next_attempt_at?: string + created_at: string } export interface WebhookDeliveryPage { @@ -66,7 +66,7 @@ export interface Event { id: string action: string payload: unknown - createdAt: string + created_at: string } export interface EventPage { @@ -80,8 +80,8 @@ export interface Run { status: string output?: unknown error?: string - createdAt: string - endedAt?: string + created_at: string + ended_at?: string } export interface RunPage { diff --git a/conformance/docker-compose.yml b/conformance/docker-compose.yml index 6b177e4..c6fc4af 100644 --- a/conformance/docker-compose.yml +++ b/conformance/docker-compose.yml @@ -6,7 +6,7 @@ services: surrealdb: - image: surrealdb/surrealdb:v3.2.4 + image: surrealdb/surrealdb:v3.3.0 command: start --user root --pass root minio: diff --git a/crates/copal-flow/Cargo.toml b/crates/copal-flow/Cargo.toml index 3e9d4e3..4342f6f 100644 --- a/crates/copal-flow/Cargo.toml +++ b/crates/copal-flow/Cargo.toml @@ -16,4 +16,4 @@ tracing = { workspace = true } tokio = { workspace = true } [dev-dependencies] -surrealdb = { version = "3", default-features = false, features = ["kv-mem"] } +surrealdb = { version = "3.3", default-features = false, features = ["kv-mem"] } diff --git a/crates/copal-server/Cargo.toml b/crates/copal-server/Cargo.toml index 3b910a6..cb4fb0c 100644 --- a/crates/copal-server/Cargo.toml +++ b/crates/copal-server/Cargo.toml @@ -86,4 +86,4 @@ tempfile = { workspace = true } ulid = { workspace = true } tower = { version = "0.5", features = ["util"] } http-body-util = "0.1" -surrealdb = { version = "3", default-features = false, features = ["kv-mem"] } +surrealdb = { version = "3.3", default-features = false, features = ["kv-mem"] } diff --git a/crates/copal-server/src/mcp.rs b/crates/copal-server/src/mcp.rs index 01816c3..e3fd50d 100644 --- a/crates/copal-server/src/mcp.rs +++ b/crates/copal-server/src/mcp.rs @@ -19,7 +19,7 @@ use axum::Json; use serde_json::{json, Map, Value}; use copal_core::TenantId; -use kayak::runtime::{ActionArgs, GetArgs, ListArgs, QueryArgs, SortDirection}; +use kayak::runtime::{ActionArgs, GetArgs, ListArgs, QueryArgs, SortDirection, SubListArgs}; use copal_blob::BlobStore; @@ -37,6 +37,13 @@ enum Route { Get { resource: String, }, + /// One parent's sub-collection; `identity` names the input that + /// carries the parent's id, the resource's wire identity. + SubList { + resource: String, + sub: String, + identity: String, + }, Action { resource: String, action: String, @@ -94,6 +101,20 @@ fn routes() -> &'static BTreeMap { resource: resource.name.clone(), }, ); + // The manifest refuses to generate a sub-collection tool for + // a resource with no wire identity, so one always exists here. + if let Some(identity) = resource.wire_identity() { + for sub in &resource.sub_resources { + map.insert( + format!("{singular}_{}_list", sub.name), + Route::SubList { + resource: resource.name.clone(), + sub: sub.name.clone(), + identity: identity.to_owned(), + }, + ); + } + } for action in &resource.actions { map.insert( format!("{singular}_{}", action.name), @@ -230,21 +251,7 @@ async fn call_tool( let value = match route { Route::List { resource } => { - let limit = arguments - .remove("limit") - .and_then(|v| v.as_i64()) - .unwrap_or(50) - .clamp(1, 1_000) as u32; - let cursor = arguments - .remove("cursor") - .and_then(|v| v.as_str().map(str::to_owned)); - let sort = arguments - .remove("sort") - .and_then(|v| v.as_str().map(str::to_owned)) - .map(|raw| match raw.split_once(":desc") { - Some((column, _)) => (column.to_owned(), SortDirection::Desc), - None => (raw, SortDirection::Asc), - }); + let (limit, cursor, sort) = page_arguments(&mut arguments); let filters: BTreeMap = arguments.into_iter().collect(); let output = dispatcher .list( @@ -274,6 +281,34 @@ async fn call_tool( // successful call whose text reads null. row.ok_or_else(|| (-32000, format!("not found: {resource} {id}")))? } + Route::SubList { + resource, + sub, + identity, + } => { + let parent_id = arguments + .remove(&identity) + .and_then(|v| v.as_str().map(str::to_owned)) + .ok_or((-32602, format!("{identity} is required")))?; + let (limit, cursor, sort) = page_arguments(&mut arguments); + let filters: BTreeMap = arguments.into_iter().collect(); + let output = dispatcher + .sub_list( + &resource, + &sub, + ctx, + SubListArgs { + parent_id, + limit, + cursor, + filters, + sort, + }, + ) + .await + .map_err(kayak_to_rpc)?; + json!({ "items": output.items, "next_cursor": output.next_cursor }) + } Route::Action { resource, action, @@ -311,6 +346,31 @@ async fn call_tool( })) } +/// The paging inputs a listing tool takes, removed from `arguments` so +/// what remains is its filters: the page size (50 when absent, held to +/// 1..=1000 before the dispatcher applies the declared ceiling), the +/// resume cursor, and `sort` as `column` or `column:desc`. +fn page_arguments( + arguments: &mut Map, +) -> (u32, Option, Option<(String, SortDirection)>) { + let limit = arguments + .remove("limit") + .and_then(|v| v.as_i64()) + .unwrap_or(50) + .clamp(1, 1_000) as u32; + let cursor = arguments + .remove("cursor") + .and_then(|v| v.as_str().map(str::to_owned)); + let sort = arguments + .remove("sort") + .and_then(|v| v.as_str().map(str::to_owned)) + .map(|raw| match raw.split_once(":desc") { + Some((column, _)) => (column.to_owned(), SortDirection::Desc), + None => (raw, SortDirection::Asc), + }); + (limit, cursor, sort) +} + pub(crate) async fn seeded_context( state: &AppState, headers: &HeaderMap, diff --git a/crates/copal-server/tests/mcp.rs b/crates/copal-server/tests/mcp.rs index ec327df..625e608 100644 --- a/crates/copal-server/tests/mcp.rs +++ b/crates/copal-server/tests/mcp.rs @@ -248,6 +248,23 @@ async fn an_agent_ingests_end_to_end() { serde_json::from_str(body["result"]["content"][0]["text"].as_str().unwrap()).unwrap(); assert_eq!(fetched["state"], "ready", "{fetched:#?}"); assert_eq!(fetched["path"], "agent-authored.txt"); + + // The upload left a version, and the sub-collection tool the + // manifest declares for it lists that version under its file. + let body = rpc( + &router, + &token, + json!({ + "jsonrpc": "2.0", "id": 13, "method": "tools/call", + "params": { "name": "file_versions_list", "arguments": { "id": id, "limit": 5 } }, + }), + ) + .await; + assert_eq!(body["result"]["isError"], false, "{body:#?}"); + let page: Value = + serde_json::from_str(body["result"]["content"][0]["text"].as_str().unwrap()).unwrap(); + let versions = page["items"].as_array().expect("a page of versions"); + assert_eq!(versions.len(), 1, "{page:#?}"); } /// A get for a row that does not exist fails the call, as REST diff --git a/crates/copal-store/Cargo.toml b/crates/copal-store/Cargo.toml index 813f018..d695d63 100644 --- a/crates/copal-store/Cargo.toml +++ b/crates/copal-store/Cargo.toml @@ -22,7 +22,7 @@ ulid = { workspace = true } # The embedded tier: an optional direct dependency on surrealdb whose # only job is wiring the on-disk engine into surql-rs via Cargo # feature unification. No code here touches it. -surrealdb = { version = "3", default-features = false, features = [ +surrealdb = { version = "3.3", default-features = false, features = [ "kv-surrealkv", "kv-mem", ], optional = true } @@ -37,7 +37,7 @@ tokio = { workspace = true } # Embedded engines are feature-gated on the surrealdb crate itself and # surql-rs deliberately does not pull them. Declaring kv-mem here wires # the mem:// engine into test builds only, via Cargo feature unification. -surrealdb = { version = "3", default-features = false, features = ["kv-mem"] } +surrealdb = { version = "3.3", default-features = false, features = ["kv-mem"] } hmac = "0.13" tempfile = "3" base64 = "0.23" diff --git a/crates/copal-store/src/store.rs b/crates/copal-store/src/store.rs index fde810b..580ad94 100644 --- a/crates/copal-store/src/store.rs +++ b/crates/copal-store/src/store.rs @@ -143,7 +143,9 @@ impl Store { /// [`schema::reference_backfill_script`]. /// /// Concurrent boots race benignly: identical `OVERWRITE` - /// statements are idempotent, and a DDL conflict retries once. + /// statements are idempotent, and a DDL conflict retries once. An + /// index the engine refuses while it reclaims the table's document + /// ids retries on a backoff; see [`Store::run_ddl`]. pub async fn apply_schema( &self, engine_access_key: Option<&str>, @@ -152,45 +154,7 @@ impl Store { let db = self.introspect().await?; let code = schema::code_snapshot(embedding_dimension, &self.engine_policy); let diffs = surql::migration::diff::diff_schemas(&code, &db); - - // Analyzers first: a full-text index names one, so index - // creation cannot precede it, and the script is not a - // transaction. - let mut analyzer_ops: Vec = Vec::new(); - let mut apply: Vec = Vec::new(); - let mut reverse_fields: Vec = Vec::new(); - for diff in &diffs { - use surql::migration::models::DiffOperation as Op; - match diff.operation { - Op::DropTable - | Op::DropField - | Op::DropIndex - | Op::DropEvent - | Op::DropAnalyzer - | Op::DropBucket - | Op::DropSequence - | Op::DropFunction - | Op::DropParam => { - tracing::warn!( - change = %diff.description, - "the database defines this and the code no longer does; remove it \ - manually if it is truly retired", - ); - } - Op::AddAnalyzer | Op::ModifyAnalyzer => { - analyzer_ops.push(diff.forward_sql.clone()); - } - Op::AddIndex => apply.push(index_add_statement(&code, diff)), - Op::AddField if adds_reverse_reference(&code, diff) => { - reverse_fields.push(diff.forward_sql.clone()); - } - _ => apply.push(diff.forward_sql.clone()), - } - } - let mut apply = { - analyzer_ops.extend(apply); - analyzer_ops - }; + let (mut apply, reverse_fields) = plan_schema(&code, &diffs); if let Some(key) = engine_access_key { // Applied whenever configured rather than diffed: the // engine redacts keys in its echo, so access definitions @@ -205,8 +169,13 @@ impl Store { statements = applied, "bringing the database up to the code's schema", ); - if !apply.is_empty() { - self.run_ddl(&apply.join("\n"), "apply_schema").await?; + // One statement at a time, so a retry repeats only the statement + // that was refused. Re-running the whole script would overwrite + // every index ahead of the refused one again, and on SurrealDB + // 3.3 an overwritten index is what starts the document-id + // reclaim that refused it. + for statement in &apply { + self.run_ddl(statement, "apply_schema").await?; } if !reverse_fields.is_empty() { // Backfill first, computed fields after: once the fields @@ -224,22 +193,50 @@ impl Store { Ok(applied) } - /// Run one DDL script, retrying once on an engine-level conflict - /// (two replicas booting at the same moment race the same - /// idempotent statements). + /// Run one DDL script, retrying what a later attempt can fix. + /// + /// An engine-level conflict retries once: two replicas booting at + /// the same moment race the same idempotent statements. A + /// `DEFINE INDEX` that SurrealDB 3.3 refuses because the table's + /// document ids are "still being reclaimed" (the background cleanup + /// a removed or overwritten index starts) retries on the backoff in + /// [`RECLAIM_WAITS`], about half a minute in all, because the + /// refusal ends when the cleanup does. async fn run_ddl(&self, script: &str, what: &str) -> copal_core::Result<()> { - if let Err(first) = self.client.query(script).await { - if first.to_string().contains("conflict") { - tokio::time::sleep(std::time::Duration::from_millis(250)).await; - self.client - .query(script) - .await - .map_err(|e| CopalError::Store(format!("{what} retry: {e}")))?; + let mut reclaim_waits = RECLAIM_WAITS.iter(); + let mut conflict_retried = false; + let mut retried = false; + loop { + let error = match self.client.query(script).await { + Ok(_) => return Ok(()), + Err(error) => error.to_string(), + }; + let wait = if is_reclaim_refusal(&error) { + reclaim_waits.next().copied() + } else if error.contains("conflict") && !conflict_retried { + conflict_retried = true; + Some(std::time::Duration::from_millis(250)) } else { - return Err(CopalError::Store(format!("{what}: {first}"))); + None + }; + let Some(wait) = wait else { + let what = if retried { + format!("{what} retry") + } else { + what.to_owned() + }; + return Err(CopalError::Store(format!("{what}: {error}"))); + }; + if is_reclaim_refusal(&error) { + tracing::info!( + step = what, + wait_ms = wait.as_millis() as u64, + "the engine is still reclaiming a table's document ids; retrying the index", + ); } + retried = true; + tokio::time::sleep(wait).await; } - Ok(()) } /// The database's schema as it actually stands, from both INFO @@ -410,7 +407,78 @@ impl Store { } } -/// The statement for an index the database lacks. +/// How long [`Store::run_ddl`] waits between attempts at an index the +/// engine refused while reclaiming its table's document ids. The +/// cleanup's length grows with the table, and boot is the only thing +/// waiting, so the waits double up to about half a minute in all +/// before the refusal is reported. +const RECLAIM_WAITS: [std::time::Duration; 6] = [ + std::time::Duration::from_millis(500), + std::time::Duration::from_secs(1), + std::time::Duration::from_secs(2), + std::time::Duration::from_secs(4), + std::time::Duration::from_secs(8), + std::time::Duration::from_secs(15), +]; + +/// Whether an engine error is SurrealDB 3.3's refusal of a +/// `DEFINE INDEX` while the table's shared document-id space is being +/// reclaimed: "The shared document-ID space for table `t` is still +/// being reclaimed; retry DEFINE INDEX after cleanup completes". +fn is_reclaim_refusal(error: &str) -> bool { + error.contains("still being reclaimed") +} + +/// The statements that bring the database to the code's schema, in +/// order, and apart from them the computed reverse-reference fields +/// that must wait for the reference backfill. +/// +/// Analyzers come first: a full-text index names one, so index +/// creation cannot precede it, and the script is not a transaction. +/// Definitions only the database holds are logged and skipped. +fn plan_schema( + code: &surql::migration::diff::SchemaSnapshot, + diffs: &[surql::migration::models::SchemaDiff], +) -> (Vec, Vec) { + let mut analyzer_ops: Vec = Vec::new(); + let mut apply: Vec = Vec::new(); + let mut reverse_fields: Vec = Vec::new(); + for diff in diffs { + use surql::migration::models::DiffOperation as Op; + match diff.operation { + Op::DropTable + | Op::DropField + | Op::DropIndex + | Op::DropEvent + | Op::DropAnalyzer + | Op::DropBucket + | Op::DropSequence + | Op::DropFunction + | Op::DropParam => { + tracing::warn!( + change = %diff.description, + "the database defines this and the code no longer does; remove it \ + manually if it is truly retired", + ); + } + Op::AddAnalyzer | Op::ModifyAnalyzer => { + analyzer_ops.push(diff.forward_sql.clone()); + } + // A changed index arrives as ModifyIndex (surql 0.34) and + // rebuilds like a new one, so both take the backgrounded path. + Op::AddIndex | Op::ModifyIndex => apply.push(index_add_statement(code, diff)), + Op::AddField if adds_reverse_reference(code, diff) => { + reverse_fields.push(diff.forward_sql.clone()); + } + _ => apply.push(diff.forward_sql.clone()), + } + } + analyzer_ops.extend(apply); + (analyzer_ops, reverse_fields) +} + +/// The statement for an index the database lacks or defines +/// differently. /// /// Non-unique indexes build `CONCURRENTLY`: the `DEFINE` returns at /// once and the engine populates the index behind it, so a new or @@ -505,6 +573,49 @@ mod tests { assert!(!sql.contains("CONCURRENTLY"), "{sql}"); } + /// A new embedding width rebuilds the vector index, and the rebuild + /// must stay behind boot the way a first build does. surql 0.34 + /// reports the change as ModifyIndex where it used to be an add, so + /// routing only adds sent the rebuild down the synchronous path. + #[test] + fn a_changed_index_is_backgrounded_like_a_new_one() { + let policy = crate::schema::EnginePolicy::default(); + let code = crate::schema::code_snapshot(Some(768), &policy); + let db = crate::schema::code_snapshot(Some(384), &policy); + let diffs = surql::migration::diff::diff_schemas(&code, &db); + let changed = diffs + .iter() + .find(|d| d.index.as_deref() == Some("idx_chunk_embedding")) + .expect("the width change reaches the vector index"); + assert_eq!( + changed.operation, + surql::migration::models::DiffOperation::ModifyIndex, + ); + + let (apply, _) = plan_schema(&code, &diffs); + let rebuilt: Vec<&String> = apply + .iter() + .filter(|sql| sql.contains("idx_chunk_embedding")) + .collect(); + assert_eq!(rebuilt.len(), 1, "{apply:#?}"); + assert!(rebuilt[0].contains("DIMENSION 768"), "{}", rebuilt[0]); + assert!(rebuilt[0].ends_with("CONCURRENTLY;"), "{}", rebuilt[0]); + } + + #[test] + fn the_reclaim_refusal_is_told_apart_from_other_failures() { + assert!(is_reclaim_refusal( + "The shared document-ID space for table `text_chunk` is still being \ + reclaimed; retry DEFINE INDEX after cleanup completes", + )); + assert!(!is_reclaim_refusal( + "Transaction conflict: Resource busy. This transaction can be retried", + )); + assert!(!is_reclaim_refusal( + "The index 'idx_chunk_embedding' already exists" + )); + } + #[test] fn only_the_computed_reverse_fields_are_deferred() { let (code, diffs) = fresh_diffs(); diff --git a/crates/copal-store/tests/engine_assumptions.rs b/crates/copal-store/tests/engine_assumptions.rs index ae91ddd..ad64473 100644 --- a/crates/copal-store/tests/engine_assumptions.rs +++ b/crates/copal-store/tests/engine_assumptions.rs @@ -190,14 +190,19 @@ async fn distinct_files_per_group_need_array_group() { } /// Why `file_version.markers` and `file_text.withheld` are `TYPE any` -/// rather than `array`: a schemafull `array` field refuses object -/// items outright ("no such field exists" for the item's keys), the -/// `FLEXIBLE` escape attaches only to object-bearing types the schema -/// builder cannot spell, and `any` carries the array of objects -/// verbatim, absence included. If this pins differently after an -/// engine upgrade, those columns can graduate to a real array type. +/// rather than `array`: through SurrealDB 3.2 a schemafull `array` +/// field refused object items outright ("no such field exists" for +/// the item's keys), the `FLEXIBLE` escape attaches only to +/// object-bearing types the schema builder cannot spell, and `any` +/// carries the array of objects verbatim, absence included. +/// +/// SurrealDB 3.3 changed the first half: a schemafull `option` +/// now takes object items and keeps their keys, which this pins. The +/// columns stay `any` for now because moving them to an array type is +/// a schema change with its own migration, and `any` still carries +/// everything they hold. #[tokio::test] -async fn any_typed_fields_carry_object_arrays_and_plain_arrays_refuse_them() { +async fn any_typed_fields_carry_object_arrays_and_so_do_plain_arrays_since_3_3() { let client = seeded_client().await; for statement in [ "DEFINE TABLE spans_probe SCHEMAFULL;", @@ -207,16 +212,15 @@ async fn any_typed_fields_carry_object_arrays_and_plain_arrays_refuse_them() { client.inner().query(statement).await.expect(statement); } - // The strict column refuses the very shape markers need. - let mut response = client - .inner() - .query("CREATE spans_probe:strict CONTENT { strict: [{ start: 1, end: 5 }] };") - .await - .expect("statement runs"); - assert!( - !response.take_errors().is_empty(), - "a schemafull array field accepted object items; `any` is no longer required", - ); + // The strict column takes the very shape markers need, keys and all. + let rows: Vec = query_records_raw( + &client, + "CREATE spans_probe:strict CONTENT \ + { strict: [{ start: 1, end: 5, access: 'grant' }] } RETURN AFTER;", + ) + .await; + assert_eq!(rows[0]["strict"][0]["start"], 1, "{rows:?}"); + assert_eq!(rows[0]["strict"][0]["access"], "grant", "{rows:?}"); // The any column carries it whole, and admits absence. let rows: Vec = query_records_raw( diff --git a/docker-compose.yml b/docker-compose.yml index d560f81..525e1c4 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,6 +1,6 @@ services: surrealdb: - image: surrealdb/surrealdb:v3.2.4 + image: surrealdb/surrealdb:v3.3.0 command: start --user root --pass root rocksdb:/data/copal.db environment: # Enables SurrealDB's experimental file buckets. Copal does not use diff --git a/docs/mcp-tools.json b/docs/mcp-tools.json index caee187..a6e5d20 100644 --- a/docs/mcp-tools.json +++ b/docs/mcp-tools.json @@ -16,7 +16,15 @@ }, "state": { "type": "string", - "description": "Filter by state." + "description": "Filter by state.", + "enum": [ + "draft", + "uploading", + "scanning", + "ready", + "failed", + "quarantined" + ] }, "sort": { "type": "string", @@ -54,6 +62,37 @@ "rateClass": "reads" } }, + { + "name": "file_versions_list", + "description": "Every stored version of this file, newest first.", + "inputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "The file whose versions to list." + }, + "limit": { + "type": "integer", + "description": "Rows per page, at most 100." + }, + "cursor": { + "type": "string", + "description": "Resume from a previous page." + } + }, + "required": [ + "id" + ], + "additionalProperties": false + }, + "annotations": { + "requiredScopes": [ + "read" + ], + "rateClass": "reads" + } + }, { "name": "file_create", "description": "Create the file record; bytes follow through the content upload or an upload grant.", @@ -380,6 +419,41 @@ "rateClass": "reads" } }, + { + "name": "webhook_deliveries_list", + "description": "Delivery attempts to this endpoint, newest first.", + "inputSchema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "The webhook whose deliveries to list." + }, + "limit": { + "type": "integer", + "description": "Rows per page, at most 100." + }, + "cursor": { + "type": "string", + "description": "Resume from a previous page." + }, + "state": { + "type": "string", + "description": "Filter by state." + } + }, + "required": [ + "id" + ], + "additionalProperties": false + }, + "annotations": { + "requiredScopes": [ + "read" + ], + "rateClass": "reads" + } + }, { "name": "webhook_register", "description": "Register an endpoint. The signing secret appears once, here.", diff --git a/docs/openapi.json b/docs/openapi.json index 7ff1092..ab076d5 100644 --- a/docs/openapi.json +++ b/docs/openapi.json @@ -497,6 +497,14 @@ "in": "query", "name": "state", "schema": { + "enum": [ + "draft", + "uploading", + "scanning", + "ready", + "failed", + "quarantined" + ], "type": "string" } },