diff --git a/crates/ide-host/src/plugins/api.rs b/crates/ide-host/src/plugins/api.rs index 5c379f866..0fa9fea54 100644 --- a/crates/ide-host/src/plugins/api.rs +++ b/crates/ide-host/src/plugins/api.rs @@ -18,7 +18,7 @@ use std::sync::atomic::{AtomicU64, Ordering}; use std::time::{Duration, Instant}; /// Largest storage of one plugin (keys + values). -const MAX_STORAGE: usize = 1 << 20; +const MAX_STORAGE: usize = 64 << 20; const MAX_KEY: usize = 256; /// Most status bar items per plugin. const MAX_STATUS_ITEMS: usize = 8; @@ -856,7 +856,10 @@ impl HostApi for PluginApi { } let size: usize = map.iter().map(|(k, v)| k.len() + v.len()).sum(); if size > MAX_STORAGE { - return Err(HostError::Invalid(format!("storage is limited to {} KiB", MAX_STORAGE >> 10))); + return Err(HostError::Invalid(format!( + "storage is limited to {} MiB (UTF-8 keys and values)", + MAX_STORAGE >> 20 + ))); } self.save_storage(&map) } @@ -1292,6 +1295,40 @@ mod tests { PluginApi { pkg: Package::new(manifest, dir.to_path_buf()), shared } } + #[test] + fn storage_keeps_multimegabyte_indexes_after_host_recreation() { + let tmp = tempfile::tempdir().unwrap(); + let value = "é".repeat(2 << 20); + { + let api = api(tmp.path(), Arc::default()); + api.storage_set("index", Some(value.clone())).unwrap(); + } + let api = api(tmp.path(), Arc::default()); + assert_eq!(api.storage_get("index").unwrap().as_deref(), Some(value.as_str())); + api.storage_set("index", None).unwrap(); + assert_eq!(api.storage_get("index").unwrap(), None); + } + + #[test] + fn storage_quota_counts_utf8_keys_and_values_and_preserves_data_on_failure() { + let tmp = tempfile::tempdir().unwrap(); + let api = api(tmp.path(), Arc::default()); + let key = "index"; + let mut value = "é".repeat(((64 << 20) - key.len()) / 2); + value.push('x'); + api.storage_set(key, Some(value.clone())).unwrap(); + + for (key, value) in [("x", String::new()), (key, format!("{value}x"))] { + let err = api.storage_set(key, Some(value)).unwrap_err(); + assert!(matches!(err, HostError::Invalid(ref message) if message.contains("64 MiB")), "{err}"); + } + assert_eq!(api.storage_keys("").unwrap(), [key]); + assert_eq!(api.storage_get(key).unwrap().as_deref(), Some(value.as_str())); + api.storage_set(key, Some("small".into())).unwrap(); + api.storage_set("other", Some("value".into())).unwrap(); + assert_eq!(api.storage_get("other").unwrap().as_deref(), Some("value")); + } + #[test] fn repository_and_search_paths_match_ipc_events() { let tmp = tempfile::tempdir().unwrap(); diff --git a/crates/ide-host/tests/plugins.rs b/crates/ide-host/tests/plugins.rs index a1e7fa865..e31c52845 100644 --- a/crates/ide-host/tests/plugins.rs +++ b/crates/ide-host/tests/plugins.rs @@ -1540,6 +1540,27 @@ fn official_key_promoter() { assert!(f.host.event_kinds().is_empty()); } +#[test] +fn storage_keeps_multimegabyte_indexes_after_idle_reclaim_and_removes_them_on_uninstall() { + let f = fixture(Limits { idle_timeout: Some(Duration::from_millis(100)), ..Limits::default() }); + let pkg = Path::new(env!("CARGO_MANIFEST_DIR")).join("../ide-plugin/tests/fixtures/storage"); + f.install(&pkg); + f.run("test.storage", "save", None).unwrap(); + assert_eq!(f.host.instances(), 1); + std::thread::sleep(Duration::from_millis(150)); + f.host.tick(); + assert_eq!(f.host.instances(), 0); + assert_eq!(f.host.info_of("test.storage").unwrap().stats.reclaims, 1); + assert_eq!(f.run("test.storage", "load", None).unwrap().as_deref(), Some("4194304")); + assert_eq!(f.host.info_of("test.storage").unwrap().stats.activations, 2); + let storage_dir = f.plugins_dir.join(".data/test.storage"); + assert!(storage_dir.join("storage.json").is_file()); + f.host.uninstall("test.storage").unwrap(); + assert!(!storage_dir.exists()); + f.install(&pkg); + assert!(f.run("test.storage", "load", None).unwrap_err().contains("missing index")); +} + fn git(dir: &Path, args: &[&str]) { let out = std::process::Command::new("git") .args(["-c", "user.name=t", "-c", "user.email=t@t", "-c", "init.defaultBranch=main"]) diff --git a/crates/ide-plugin/tests/fixtures/commit/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/commit/dist/plugin.wasm index 512310a56..c4c54cc72 100644 Binary files a/crates/ide-plugin/tests/fixtures/commit/dist/plugin.wasm and b/crates/ide-plugin/tests/fixtures/commit/dist/plugin.wasm differ diff --git a/crates/ide-plugin/tests/fixtures/commit/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/commit/dist/plugin.wasm.sources index e4e7a0746..ea8dfb8e4 100644 --- a/crates/ide-plugin/tests/fixtures/commit/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/commit/dist/plugin.wasm.sources @@ -1 +1 @@ -e9f2e3818dab64aa24e3f1852eff301c2ba971e90157067b11b832cdcc361fd6 +83a1e3f362740752ed69c53da29ff950cf9c9de18125af6c98995ea490b31690 diff --git a/crates/ide-plugin/tests/fixtures/hello/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/hello/dist/plugin.wasm index 29fd2096a..b615eac69 100644 Binary files a/crates/ide-plugin/tests/fixtures/hello/dist/plugin.wasm and b/crates/ide-plugin/tests/fixtures/hello/dist/plugin.wasm differ diff --git a/crates/ide-plugin/tests/fixtures/hello/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/hello/dist/plugin.wasm.sources index 91bac91d4..66a53d3e5 100644 --- a/crates/ide-plugin/tests/fixtures/hello/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/hello/dist/plugin.wasm.sources @@ -1 +1 @@ -ad6f103e549a51cc64aa9ce03e0759c7e247b98fa4d7d84f2d5cbbd32a56e47a +a9f1e2ec87de32ef241fcb559d157cd05800dcf106ab27e906ba36468c0b39e5 diff --git a/crates/ide-plugin/tests/fixtures/hover/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/hover/dist/plugin.wasm index 0150f1231..4997739af 100644 Binary files a/crates/ide-plugin/tests/fixtures/hover/dist/plugin.wasm and b/crates/ide-plugin/tests/fixtures/hover/dist/plugin.wasm differ diff --git a/crates/ide-plugin/tests/fixtures/hover/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/hover/dist/plugin.wasm.sources index 51895a5d7..aad78a925 100644 --- a/crates/ide-plugin/tests/fixtures/hover/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/hover/dist/plugin.wasm.sources @@ -1 +1 @@ -bb5747f6e319f1852dbfd92c6a65e6e54a41a6d508fe96dc570a5c0684f7d322 +d065af9f54b5bd1ec2fbc31250c87153a55501a4e8bf4002fcc04c67c2d1e03e diff --git a/crates/ide-plugin/tests/fixtures/indexer/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/indexer/dist/plugin.wasm index 8fed17f4b..7c1ec874c 100644 Binary files a/crates/ide-plugin/tests/fixtures/indexer/dist/plugin.wasm and b/crates/ide-plugin/tests/fixtures/indexer/dist/plugin.wasm differ diff --git a/crates/ide-plugin/tests/fixtures/indexer/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/indexer/dist/plugin.wasm.sources index 6495924ea..0dbbaeed3 100644 --- a/crates/ide-plugin/tests/fixtures/indexer/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/indexer/dist/plugin.wasm.sources @@ -1 +1 @@ -f651ab979bc6b52c5bdde0417667393ffd442726b406b9064a431e0fad39b8be +dd57b09293deb0fdc3201978e350c118f428429df4beccc4f23665be0335a795 diff --git a/crates/ide-plugin/tests/fixtures/jobs/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/jobs/dist/plugin.wasm index 410c59c70..1508c592c 100644 Binary files a/crates/ide-plugin/tests/fixtures/jobs/dist/plugin.wasm and b/crates/ide-plugin/tests/fixtures/jobs/dist/plugin.wasm differ diff --git a/crates/ide-plugin/tests/fixtures/jobs/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/jobs/dist/plugin.wasm.sources index ee95222e0..0c7559d57 100644 --- a/crates/ide-plugin/tests/fixtures/jobs/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/jobs/dist/plugin.wasm.sources @@ -1 +1 @@ -7fd84d18cbcf8673c988e7d3d9a143883635f967ba2b3f679fb1f3aafaa9169c +436516e5f17a11f5a1225b854ab9fef703172a47d33bf3d840c721ad6d373e62 diff --git a/crates/ide-plugin/tests/fixtures/misbehave/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/misbehave/dist/plugin.wasm index 1da6e94d3..45912d407 100644 Binary files a/crates/ide-plugin/tests/fixtures/misbehave/dist/plugin.wasm and b/crates/ide-plugin/tests/fixtures/misbehave/dist/plugin.wasm differ diff --git a/crates/ide-plugin/tests/fixtures/misbehave/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/misbehave/dist/plugin.wasm.sources index 628e1120d..a30308d3a 100644 --- a/crates/ide-plugin/tests/fixtures/misbehave/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/misbehave/dist/plugin.wasm.sources @@ -1 +1 @@ -a2762b47de8abd3d1c4fff0130001c6a9347292f94bfffd3933db1a270c95076 +4e8118c9f4974385421d1e2ca0106fd658ad85124e1453c4114f60a164f72f68 diff --git a/crates/ide-plugin/tests/fixtures/semantic-tokens/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/semantic-tokens/dist/plugin.wasm index e00246b33..39656c746 100644 Binary files a/crates/ide-plugin/tests/fixtures/semantic-tokens/dist/plugin.wasm and b/crates/ide-plugin/tests/fixtures/semantic-tokens/dist/plugin.wasm differ diff --git a/crates/ide-plugin/tests/fixtures/semantic-tokens/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/semantic-tokens/dist/plugin.wasm.sources index 0ffbe7fb7..f360dc576 100644 --- a/crates/ide-plugin/tests/fixtures/semantic-tokens/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/semantic-tokens/dist/plugin.wasm.sources @@ -1 +1 @@ -a38d39b7d43d4f2fbcb31064a9037f3a6d58fb16b3e7bfeb0f85f5f13459dbff +b77e7e3d163995f0a9a3f3cb49dc6c4ea04b2eaa0a8b74b46c64e83908bae504 diff --git a/crates/ide-plugin/tests/fixtures/storage/Cargo.lock b/crates/ide-plugin/tests/fixtures/storage/Cargo.lock new file mode 100644 index 000000000..2906de079 --- /dev/null +++ b/crates/ide-plugin/tests/fixtures/storage/Cargo.lock @@ -0,0 +1,333 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "anyhow" +version = "1.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" + +[[package]] +name = "bitflags" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ded4057c258ba199e2d26386d3af3780957ecaee6c4ef4041c6b4b8b97c0b06" + +[[package]] +name = "equivalent" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00d174d5400e5e8fd687ad1049e2f578285fa914201b1af7e8b112a4546bd826" + +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" +dependencies = [ + "foldhash", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "id-arena" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" + +[[package]] +name = "indexmap" +version = "2.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855" +dependencies = [ + "equivalent", + "hashbrown", + "serde", + "serde_core", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "leb128fmt" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" + +[[package]] +name = "log" +version = "0.4.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d15f86d12da44cd8d4ec3c73984537eb7f4cadcb9776a575a0a8a05ca11005c" + +[[package]] +name = "macro-string" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e7b3a5bbb2f63aaa223a671ea1bd0e7bc16bd30ce387324cf63995deaddbbd2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[package]] +name = "openidea-plugin" +version = "0.1.0" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "openidea-test-storage" +version = "0.1.0" +dependencies = [ + "openidea-plugin", +] + +[[package]] +name = "prettyplease" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bfe0f4c752e450fc2faf62654f1c134747922825d5b04ca717b8874f41a40c0" +dependencies = [ + "proc-macro2", + "syn", +] + +[[package]] +name = "proc-macro2" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" + +[[package]] +name = "serde" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" +dependencies = [ + "serde_core", +] + +[[package]] +name = "serde_core" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.154" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7e9cc8b1b85264074fbcc02a88680c4096b1e47df8f739dceb03bf482f04bd6" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "syn" +version = "3.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d78c8dee4c7bf0e14673097256fed6142ce9d3b85a408189d07482442145823b" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2c754d6c33795a1c324727428e5a7dedb5b06195f9890bdbcba760d3e246563" + +[[package]] +name = "wasm-encoder" +version = "0.262.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4495a6f85dd94c411c749303efcbc5defade0b0cbdbc0541495241ab917a9b5a" +dependencies = [ + "leb128fmt", + "wasmparser", +] + +[[package]] +name = "wasm-metadata" +version = "0.262.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c86ff6668190d9fb70372b306b4f9fe8930f0e2f57ce72e4922bf2f117900949" +dependencies = [ + "anyhow", + "indexmap", + "wasm-encoder", + "wasmparser", +] + +[[package]] +name = "wasmparser" +version = "0.262.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "974d643b125b272607e2fff8012ea14a8328acd7621e4bafa7afb32500052b1b" +dependencies = [ + "bitflags", + "hashbrown", + "indexmap", + "semver", +] + +[[package]] +name = "wit-bindgen" +version = "0.63.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b85a987ab61d365382d25c7d47e26edd48941b3bf6e3fbf76eff918bc71dab06" +dependencies = [ + "bitflags", + "wit-bindgen-rust-macro", +] + +[[package]] +name = "wit-bindgen-core" +version = "0.63.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "775e122e390603abfacd548027016cd0113a6e2bf2f8ce6bdd3658b013456ea8" +dependencies = [ + "anyhow", + "heck", + "wit-parser", +] + +[[package]] +name = "wit-bindgen-rust" +version = "0.63.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84e26e13b9d972026778d2ffb7985736de116026fdc8d9464f966e12df2eb240" +dependencies = [ + "anyhow", + "heck", + "indexmap", + "prettyplease", + "syn", + "wasm-metadata", + "wit-bindgen-core", + "wit-component", +] + +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.63.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16a008a0d6b4840677326beb4edbeb210a2f1b7d0183fb7cc33f466b90fd7fb6" +dependencies = [ + "anyhow", + "macro-string", + "prettyplease", + "proc-macro2", + "quote", + "syn", + "wit-bindgen-core", + "wit-bindgen-rust", +] + +[[package]] +name = "wit-component" +version = "0.262.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "078def49fdb49cab405c3006e05793b3fdaf7069126ba6b9c97d01ec8c98fe4c" +dependencies = [ + "anyhow", + "bitflags", + "indexmap", + "log", + "serde", + "serde_derive", + "serde_json", + "wasm-encoder", + "wasm-metadata", + "wasmparser", + "wit-parser", +] + +[[package]] +name = "wit-parser" +version = "0.262.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00f0dc051466ffe46787721fca3d088536f158ae400be044f1b1c386ba9397ad" +dependencies = [ + "anyhow", + "hashbrown", + "id-arena", + "indexmap", + "log", + "semver", + "serde", + "serde_derive", + "serde_json", + "unicode-ident", + "wasmparser", +] + +[[package]] +name = "zmij" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" diff --git a/crates/ide-plugin/tests/fixtures/storage/Cargo.toml b/crates/ide-plugin/tests/fixtures/storage/Cargo.toml new file mode 100644 index 000000000..f525c8b38 --- /dev/null +++ b/crates/ide-plugin/tests/fixtures/storage/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "openidea-test-storage" +version = "0.1.0" +edition = "2024" +publish = false + +[workspace] + +[lib] +crate-type = ["cdylib", "rlib"] + +[dependencies] +openidea-plugin = { path = "../../../../../sdk/rust/openidea-plugin" } + +[profile.release] +opt-level = "s" +lto = true +strip = true +codegen-units = 1 +panic = "abort" diff --git a/crates/ide-plugin/tests/fixtures/storage/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/storage/dist/plugin.wasm new file mode 100644 index 000000000..55ade2325 Binary files /dev/null and b/crates/ide-plugin/tests/fixtures/storage/dist/plugin.wasm differ diff --git a/crates/ide-plugin/tests/fixtures/storage/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/storage/dist/plugin.wasm.sources new file mode 100644 index 000000000..fe1ac7aa9 --- /dev/null +++ b/crates/ide-plugin/tests/fixtures/storage/dist/plugin.wasm.sources @@ -0,0 +1 @@ +9f2195fb83f16221e98313c095d57c293e79041ed8ae439fe2fb4f008a3a0921 diff --git a/crates/ide-plugin/tests/fixtures/storage/plugin.toml b/crates/ide-plugin/tests/fixtures/storage/plugin.toml new file mode 100644 index 000000000..77acd2c58 --- /dev/null +++ b/crates/ide-plugin/tests/fixtures/storage/plugin.toml @@ -0,0 +1,16 @@ +id = "test.storage" +name = "Storage fixture" +version = "0.1.0" +engines.openidea = "^1.3" +wasm = "dist/plugin.wasm" + +[capabilities] +required = ["storage"] + +[[contributes.commands]] +id = "save" +title = "Save index" + +[[contributes.commands]] +id = "load" +title = "Load index" diff --git a/crates/ide-plugin/tests/fixtures/storage/src/lib.rs b/crates/ide-plugin/tests/fixtures/storage/src/lib.rs new file mode 100644 index 000000000..c5a493cb5 --- /dev/null +++ b/crates/ide-plugin/tests/fixtures/storage/src/lib.rs @@ -0,0 +1,25 @@ +use openidea_plugin::{Error, Invocation, Plugin, host, register_plugin}; + +#[derive(Default)] +struct Storage; + +impl Plugin for Storage { + fn run_command(&mut self, id: &str, _: &Invocation, _: Option<&str>) -> Result, Error> { + match id { + "save" => { + host::storage::set("index", &"é".repeat(2 << 20))?; + Ok(None) + } + "load" => { + let value = host::storage::get("index")?.ok_or("missing index")?; + if value != "é".repeat(2 << 20) { + return Err("index changed".into()); + } + Ok(Some(value.len().to_string())) + } + _ => Err(Error::NotFound(id.into())), + } + } +} + +register_plugin!(Storage); diff --git a/plugins/README.md b/plugins/README.md index da543d8af..4d976c25e 100644 --- a/plugins/README.md +++ b/plugins/README.md @@ -239,7 +239,7 @@ machine. Users can revoke optional capabilities in Settings › Plugins. | `editor.write` | medium | `TextEditor::apply_edits` | | `vcs.read` | low | `Project::vcs_status` (branch, upstream, ahead/behind, changes), `vcs_remotes`, `host::pending_commit`, before-commit checks | | `vcs.write` | medium | `Project::vcs_fetch` (trusted projects only), `host::set_commit_message` | -| `storage` | low | `host::storage` (1 MiB per plugin) | +| `storage` | low | `host::storage` (64 MiB per plugin, counting UTF-8 bytes of keys and values) | | `events` | low | file opened/saved, editor focused, repository changed events | | `events.input` | medium | `action-performed` events (which actions you run, and how) | | `process:` | high | `Project::run_process`, language servers, debug adapters, runs | diff --git a/plugins/official/ai-completion/dist/plugin.wasm b/plugins/official/ai-completion/dist/plugin.wasm index fb381145c..4090bc909 100644 Binary files a/plugins/official/ai-completion/dist/plugin.wasm and b/plugins/official/ai-completion/dist/plugin.wasm differ diff --git a/plugins/official/ai-completion/dist/plugin.wasm.sources b/plugins/official/ai-completion/dist/plugin.wasm.sources index 715a8a3cb..97bb305b2 100644 --- a/plugins/official/ai-completion/dist/plugin.wasm.sources +++ b/plugins/official/ai-completion/dist/plugin.wasm.sources @@ -1 +1 @@ -c9cbe5d5a6d2d5bf3bda9308b6e07c374a60b3f95714425e9f0d855bcaa38666 +a5cba00850ccde12896ed7a69ae336a1968e024e8f5fefb6a49f2adea10569e4 diff --git a/plugins/official/checkstyle/dist/plugin.wasm b/plugins/official/checkstyle/dist/plugin.wasm index d28bdc426..8d0d091fe 100644 Binary files a/plugins/official/checkstyle/dist/plugin.wasm and b/plugins/official/checkstyle/dist/plugin.wasm differ diff --git a/plugins/official/checkstyle/dist/plugin.wasm.sources b/plugins/official/checkstyle/dist/plugin.wasm.sources index 29814a869..fbede8a3c 100644 --- a/plugins/official/checkstyle/dist/plugin.wasm.sources +++ b/plugins/official/checkstyle/dist/plugin.wasm.sources @@ -1 +1 @@ -dada583da1a117277325077bf700a2b485433768836335683ff3f4d370e43334 +27d61fcc109561aeea56f3a37da0aba7b6c56fdf01ff918f2e62d5732832ba3d diff --git a/plugins/official/csv-editor/dist/plugin.wasm b/plugins/official/csv-editor/dist/plugin.wasm index 3fc0f3f05..bbaa24452 100644 Binary files a/plugins/official/csv-editor/dist/plugin.wasm and b/plugins/official/csv-editor/dist/plugin.wasm differ diff --git a/plugins/official/csv-editor/dist/plugin.wasm.sources b/plugins/official/csv-editor/dist/plugin.wasm.sources index 5574d116d..309f7acad 100644 --- a/plugins/official/csv-editor/dist/plugin.wasm.sources +++ b/plugins/official/csv-editor/dist/plugin.wasm.sources @@ -1 +1 @@ -720fc0e60bb11cabbf9658bbada16eb889e509ab436d62b17b2a64ef9651a559 +c86fae61f88b6903354b1fb706b0718f9036f82085653481d77ddc3f622b3a73 diff --git a/plugins/official/git-toolbox/dist/plugin.wasm b/plugins/official/git-toolbox/dist/plugin.wasm index 6ce3baa4b..7823ce2da 100644 Binary files a/plugins/official/git-toolbox/dist/plugin.wasm and b/plugins/official/git-toolbox/dist/plugin.wasm differ diff --git a/plugins/official/git-toolbox/dist/plugin.wasm.sources b/plugins/official/git-toolbox/dist/plugin.wasm.sources index 965e14771..5027ca6fe 100644 --- a/plugins/official/git-toolbox/dist/plugin.wasm.sources +++ b/plugins/official/git-toolbox/dist/plugin.wasm.sources @@ -1 +1 @@ -4ced6756e3f94c0989a7c00948c3456954eaa0b08cb072a3b1790872eabc6a45 +b4d059850083339f826223700eda7df0c8b655a40e4832d3acda36dc0f76db9a diff --git a/plugins/official/graphviz/dist/plugin.wasm b/plugins/official/graphviz/dist/plugin.wasm index 2299fe45e..a20fdb830 100644 Binary files a/plugins/official/graphviz/dist/plugin.wasm and b/plugins/official/graphviz/dist/plugin.wasm differ diff --git a/plugins/official/graphviz/dist/plugin.wasm.sources b/plugins/official/graphviz/dist/plugin.wasm.sources index 85650c065..f9b5d4c5f 100644 --- a/plugins/official/graphviz/dist/plugin.wasm.sources +++ b/plugins/official/graphviz/dist/plugin.wasm.sources @@ -1 +1 @@ -ae7c04be3b7811e560c711077391bec14705a1acb769ba8a7e0212dc8e8ec5ff +b2977b3b82ad26126125c614281cbbf888bb8151ece9a43fbaa5459c7a8b97cc diff --git a/plugins/official/key-promoter/dist/plugin.wasm b/plugins/official/key-promoter/dist/plugin.wasm index b96fa15a7..7a8d47790 100644 Binary files a/plugins/official/key-promoter/dist/plugin.wasm and b/plugins/official/key-promoter/dist/plugin.wasm differ diff --git a/plugins/official/key-promoter/dist/plugin.wasm.sources b/plugins/official/key-promoter/dist/plugin.wasm.sources index 5c7365be8..93cb8b224 100644 --- a/plugins/official/key-promoter/dist/plugin.wasm.sources +++ b/plugins/official/key-promoter/dist/plugin.wasm.sources @@ -1 +1 @@ -df4f523b86e29e7f5f992eeb9b8fd9ab61b58ac8b9e05d20f1db457e9328f187 +9f59f59b999475a8c4c626f1cfc3c77ef1b3c0684f0cbf9af148556c8f9d30c0 diff --git a/plugins/official/license-header/dist/plugin.wasm b/plugins/official/license-header/dist/plugin.wasm index b6f0ef5cb..1bac6624b 100644 Binary files a/plugins/official/license-header/dist/plugin.wasm and b/plugins/official/license-header/dist/plugin.wasm differ diff --git a/plugins/official/license-header/dist/plugin.wasm.sources b/plugins/official/license-header/dist/plugin.wasm.sources index e1f166679..6fc1569b2 100644 --- a/plugins/official/license-header/dist/plugin.wasm.sources +++ b/plugins/official/license-header/dist/plugin.wasm.sources @@ -1 +1 @@ -0a4d7548b157513276176e4e02ec5d8a5a71f55f4098afd9963ec0f47312d6de +0f175352e4fcfe3b07359afb7f4a20348a488a21012e89775c628d19277d8c8c diff --git a/plugins/official/mybatis/dist/plugin.wasm b/plugins/official/mybatis/dist/plugin.wasm index 5b05e7474..9f7a275be 100644 Binary files a/plugins/official/mybatis/dist/plugin.wasm and b/plugins/official/mybatis/dist/plugin.wasm differ diff --git a/plugins/official/mybatis/dist/plugin.wasm.sources b/plugins/official/mybatis/dist/plugin.wasm.sources index b291da9ec..0373f3a3f 100644 --- a/plugins/official/mybatis/dist/plugin.wasm.sources +++ b/plugins/official/mybatis/dist/plugin.wasm.sources @@ -1 +1 @@ -451c7bf3dcbdd6e57dc657cb7d1f4ddee8d262a859863ac71287b85eb474793c +d7e9b2801ca70df9a84ec458f0fc5c6b01b7d03c056807c53268e40ecbbb9d1a diff --git a/plugins/official/regex-tester/dist/plugin.wasm b/plugins/official/regex-tester/dist/plugin.wasm index fa02945af..bfa4fe0e8 100644 Binary files a/plugins/official/regex-tester/dist/plugin.wasm and b/plugins/official/regex-tester/dist/plugin.wasm differ diff --git a/plugins/official/regex-tester/dist/plugin.wasm.sources b/plugins/official/regex-tester/dist/plugin.wasm.sources index 94fe42e82..280635cb3 100644 --- a/plugins/official/regex-tester/dist/plugin.wasm.sources +++ b/plugins/official/regex-tester/dist/plugin.wasm.sources @@ -1 +1 @@ -daf6fb2a5cff9210cc380f19dca42480d380166e028239d985abf37ebddd7a6c +50524b5be85f6bc040521f97adba6030263045dcacfeae8dbcf73ce7234e2616 diff --git a/plugins/official/solidity/dist/plugin.wasm b/plugins/official/solidity/dist/plugin.wasm index b5b4c7104..55aa66561 100644 Binary files a/plugins/official/solidity/dist/plugin.wasm and b/plugins/official/solidity/dist/plugin.wasm differ diff --git a/plugins/official/solidity/dist/plugin.wasm.sources b/plugins/official/solidity/dist/plugin.wasm.sources index 81268eb86..4ef5e13e3 100644 --- a/plugins/official/solidity/dist/plugin.wasm.sources +++ b/plugins/official/solidity/dist/plugin.wasm.sources @@ -1 +1 @@ -1364aed3a99e0769d53b444c51b873083aeb7088afa7dc6c8821cd312d0319ad +0c44311a5f9ddb1893be7c82d818297a05b15576d996a33ddc2389f9432c416c diff --git a/plugins/official/string-tools/dist/plugin.wasm b/plugins/official/string-tools/dist/plugin.wasm index edb2b3fdc..c2702a54f 100644 Binary files a/plugins/official/string-tools/dist/plugin.wasm and b/plugins/official/string-tools/dist/plugin.wasm differ diff --git a/plugins/official/string-tools/dist/plugin.wasm.sources b/plugins/official/string-tools/dist/plugin.wasm.sources index 23d8f1f07..ecce56321 100644 --- a/plugins/official/string-tools/dist/plugin.wasm.sources +++ b/plugins/official/string-tools/dist/plugin.wasm.sources @@ -1 +1 @@ -d6d1a81f02c7346b365689bc3893745aa9d867e56c187cdd28efde758bfb0fe8 +3e4e23976ce0ddb1e83813269eefc24008521cdf22757e6b5249f6f219f344d2 diff --git a/sdk/rust/openidea-plugin/src/host.rs b/sdk/rust/openidea-plugin/src/host.rs index 55a0b0e31..7ce3f9828 100644 --- a/sdk/rust/openidea-plugin/src/host.rs +++ b/sdk/rust/openidea-plugin/src/host.rs @@ -749,7 +749,8 @@ pub fn unsubscribe(kind: EventKind) { imp::unsubscribe(kind) } -/// The plugin's persistent key-value store (≤ 1 MiB). Needs `storage`. +/// The plugin's persistent key-value store (≤ 64 MiB of UTF-8 keys and values). +/// Needs `storage`; rejected writes preserve the stored data. pub mod storage { use super::imp; use crate::types::Error; diff --git a/sdk/rust/openidea-plugin/wit/host.wit b/sdk/rust/openidea-plugin/wit/host.wit index cda36d5d1..5e7f7cf38 100644 --- a/sdk/rust/openidea-plugin/wit/host.wit +++ b/sdk/rust/openidea-plugin/wit/host.wit @@ -68,7 +68,8 @@ interface ui { } /// Persistent key-value storage of the plugin (survives restarts and idle -/// reclaim; instance memory does not). Requires `storage`. At most 1 MiB. +/// reclaim; instance memory does not). Requires `storage`. At most 64 MiB, +/// counting UTF-8 bytes of keys and values; rejected writes preserve the data. interface storage { use types.{error}; diff --git a/wit/host.wit b/wit/host.wit index cda36d5d1..5e7f7cf38 100644 --- a/wit/host.wit +++ b/wit/host.wit @@ -68,7 +68,8 @@ interface ui { } /// Persistent key-value storage of the plugin (survives restarts and idle -/// reclaim; instance memory does not). Requires `storage`. At most 1 MiB. +/// reclaim; instance memory does not). Requires `storage`. At most 64 MiB, +/// counting UTF-8 bytes of keys and values; rejected writes preserve the data. interface storage { use types.{error};