From 620c4be86c754a1fdb428d9e0e487a96b8773b2f Mon Sep 17 00:00:00 2001 From: Jeff Charles Date: Wed, 30 Oct 2024 16:24:35 -0400 Subject: [PATCH 1/3] Create plugin-api crate and move most of core's logic into it --- Cargo.lock | 11 +- Cargo.toml | 3 +- Makefile | 11 +- crates/core/Cargo.toml | 5 +- crates/core/src/execution.rs | 82 ------- crates/core/src/lib.rs | 105 +-------- crates/plugin-api/CHANGELOG.md | 11 + crates/plugin-api/Cargo.toml | 18 ++ crates/plugin-api/README.md | 37 ++++ crates/plugin-api/publish.sh | 5 + crates/plugin-api/src/lib.rs | 220 +++++++++++++++++++ crates/{core => plugin-api}/src/namespace.rs | 7 +- 12 files changed, 322 insertions(+), 193 deletions(-) delete mode 100644 crates/core/src/execution.rs create mode 100644 crates/plugin-api/CHANGELOG.md create mode 100644 crates/plugin-api/Cargo.toml create mode 100644 crates/plugin-api/README.md create mode 100755 crates/plugin-api/publish.sh create mode 100644 crates/plugin-api/src/lib.rs rename crates/{core => plugin-api}/src/namespace.rs (79%) diff --git a/Cargo.lock b/Cargo.lock index 355e1178..aaeacb8e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1562,8 +1562,7 @@ name = "javy-core" version = "0.2.0" dependencies = [ "anyhow", - "javy", - "once_cell", + "javy-plugin-api", "serde", "serde_json", ] @@ -1579,6 +1578,14 @@ dependencies = [ "serde_json", ] +[[package]] +name = "javy-plugin-api" +version = "1.0.0-alpha.1" +dependencies = [ + "anyhow", + "javy", +] + [[package]] name = "javy-runner" version = "3.1.2" diff --git a/Cargo.toml b/Cargo.toml index ffa8ac64..c271f595 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,6 +3,7 @@ members = [ "crates/javy", "crates/core", "crates/cli", + "crates/plugin-api", "crates/test-macros", "crates/runner", "fuzz", @@ -21,8 +22,8 @@ wasmtime = "19" wasmtime-wasi = "19" wasi-common = "19" anyhow = "1.0" -once_cell = "1.20" javy = { path = "crates/javy", version = "3.0.2-alpha.1" } +javy-plugin-api = { path = "crates/plugin-api", version = "1.0.0-alpha.1" } tempfile = "3.13.0" uuid = { version = "1.10", features = ["v4"] } serde = { version = "1.0", default-features = false } diff --git a/Makefile b/Makefile index 228ef128..7b0e82e9 100644 --- a/Makefile +++ b/Makefile @@ -24,6 +24,9 @@ docs: test-javy: CARGO_TARGET_WASM32_WASIP1_RUNNER="wasmtime --dir=." cargo hack test --package=javy --target=wasm32-wasip1 --each-feature -- --nocapture +test-plugin-api: + CARGO_TARGET_WASM32_WASIP1_RUNNER="wasmtime --dir=." cargo hack test --package=javy-plugin-api --target=wasm32-wasip1 --each-feature -- --nocapture + test-core: CARGO_TARGET_WASM32_WASIP1_RUNNER="wasmtime" cargo test --package=javy-core --target=wasm32-wasip1 -- --nocapture @@ -44,14 +47,18 @@ test-wpt: npm install --prefix wpt npm test --prefix wpt -tests: test-javy test-core test-runner test-cli test-wpt +tests: test-javy test-plugin-api test-core test-runner test-cli test-wpt -fmt: fmt-javy fmt-core fmt-cli +fmt: fmt-javy fmt-plugin-api fmt-core fmt-cli fmt-javy: cargo fmt --package=javy -- --check cargo clippy --package=javy --target=wasm32-wasip1 --all-targets -- -D warnings +fmt-plugin-api: + cargo fmt --package=javy-plugin-api -- --check + cargo clippy --package=javy-plugin-api --target=wasm32-wasip1 --all-targets -- -D warnings + fmt-core: cargo fmt --package=javy-core -- --check cargo clippy --package=javy-core --target=wasm32-wasip1 --all-targets -- -D warnings diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index 628a5fc7..5a72553a 100644 --- a/crates/core/Cargo.toml +++ b/crates/core/Cargo.toml @@ -11,10 +11,9 @@ crate-type = ["cdylib"] [dependencies] anyhow = { workspace = true } -javy = { workspace = true, features = ["export_alloc_fns", "json"] } -once_cell = { workspace = true } +javy-plugin-api = { workspace = true, features = ["json"] } serde = { workspace = true } serde_json = { workspace = true } [features] -experimental_event_loop = [] +experimental_event_loop = ["javy-plugin-api/experimental_event_loop"] diff --git a/crates/core/src/execution.rs b/crates/core/src/execution.rs deleted file mode 100644 index 960ce4ea..00000000 --- a/crates/core/src/execution.rs +++ /dev/null @@ -1,82 +0,0 @@ -use std::process; - -use anyhow::{anyhow, bail, Error, Result}; -use javy::{ - from_js_error, - quickjs::{Ctx, Error as JSError, Function, Module, Value}, - to_js_error, Runtime, -}; - -static EVENT_LOOP_ERR: &str = r#" - Pending jobs in the event queue. - Scheduling events is not supported when the - experimental_event_loop cargo feature is disabled. - "#; - -/// Evaluate the given bytecode. -/// -/// Evaluating also prepares (or "instantiates") the state of the JavaScript -/// engine given all the information encoded in the bytecode. -pub fn run_bytecode(runtime: &Runtime, bytecode: &[u8], fn_name: Option<&str>) { - runtime - .context() - .with(|this| { - let module = unsafe { Module::load(this.clone(), bytecode)? }; - let (module, promise) = module.eval()?; - - handle_maybe_promise(this.clone(), promise.into())?; - - if let Some(fn_name) = fn_name { - let fun: Function = module.get(fn_name)?; - // Exported functions are guaranteed not to have arguments so - // we can safely pass an empty tuple for arguments. - let value = fun.call(())?; - handle_maybe_promise(this.clone(), value)? - } - Ok(()) - }) - .map_err(|e| runtime.context().with(|cx| from_js_error(cx.clone(), e))) - .and_then(|_: ()| ensure_pending_jobs(runtime)) - .unwrap_or_else(handle_error) -} - -/// Handles the promise returned by evaluating the JS bytecode. -fn handle_maybe_promise(this: Ctx, value: Value) -> javy::quickjs::Result<()> { - match value.as_promise() { - Some(promise) => { - if cfg!(feature = "experimental_event_loop") { - // If the experimental event loop is enabled, trigger it. - let resolved = promise.finish::(); - // `Promise::finish` returns Err(Wouldblock) when the all - // pending jobs have been handled. - if let Err(JSError::WouldBlock) = resolved { - Ok(()) - } else { - resolved.map(|_| ()) - } - } else { - // Else we simply expect the promise to resolve immediately. - match promise.result() { - None => Err(to_js_error(this, anyhow!(EVENT_LOOP_ERR))), - Some(r) => r, - } - } - } - None => Ok(()), - } -} - -fn ensure_pending_jobs(rt: &Runtime) -> Result<()> { - if cfg!(feature = "experimental_event_loop") { - rt.resolve_pending_jobs() - } else if rt.has_pending_jobs() { - bail!(EVENT_LOOP_ERR); - } else { - Ok(()) - } -} - -fn handle_error(e: Error) { - eprintln!("{e}"); - process::abort(); -} diff --git a/crates/core/src/lib.rs b/crates/core/src/lib.rs index 238c0cf1..d0ed0083 100644 --- a/crates/core/src/lib.rs +++ b/crates/core/src/lib.rs @@ -1,24 +1,12 @@ -use anyhow::anyhow; -use javy::Config; -use javy::Runtime; -use namespace::import_namespace; -use once_cell::sync::OnceCell; +use javy_plugin_api::import_namespace; +use javy_plugin_api::javy::Config; use shared_config::SharedConfig; use std::io; use std::io::Read; use std::slice; -use std::str; -mod execution; -mod namespace; mod shared_config; -const FUNCTION_MODULE_NAME: &str = "function.mjs"; - -static mut COMPILE_SRC_RET_AREA: [u32; 2] = [0; 2]; - -static mut RUNTIME: OnceCell = OnceCell::new(); - import_namespace!("javy_quickjs_provider_v3"); /// Used by Wizer to preinitialize the module. @@ -48,60 +36,7 @@ pub extern "C" fn initialize_runtime() { shared_config.apply_to_config(&mut config); } - let runtime = Runtime::new(config).unwrap(); - unsafe { - RUNTIME.take(); // Allow re-initializing. - RUNTIME - .set(runtime) - // `unwrap` requires error `T` to implement `Debug` but `set` - // returns the `javy::Runtime` on error and `javy::Runtime` does not - // implement `Debug`. - .map_err(|_| anyhow!("Could not pre-initialize javy::Runtime")) - .unwrap(); - }; -} - -/// Compiles JS source code to QuickJS bytecode. -/// -/// Returns a pointer to a buffer containing a 32-bit pointer to the bytecode byte array and the -/// u32 length of the bytecode byte array. -/// -/// # Arguments -/// -/// * `js_src_ptr` - A pointer to the start of a byte array containing UTF-8 JS source code -/// * `js_src_len` - The length of the byte array containing JS source code -/// -/// # Safety -/// -/// * `js_src_ptr` must reference a valid array of unsigned bytes of `js_src_len` length -#[export_name = "compile_src"] -pub unsafe extern "C" fn compile_src(js_src_ptr: *const u8, js_src_len: usize) -> *const u32 { - // Use initialized runtime when compiling because certain runtime - // configurations can cause different bytecode to be emitted. - // - // For example, given the following JS: - // ``` - // function foo() { - // "use math" - // 1234 % 32 - // } - // ``` - // - // Setting `config.bignum_extension` to `true` will produce different - // bytecode than if it were set to `false`. - let runtime = unsafe { RUNTIME.get().unwrap() }; - let js_src = str::from_utf8(slice::from_raw_parts(js_src_ptr, js_src_len)).unwrap(); - - let bytecode = runtime - .compile_to_bytecode(FUNCTION_MODULE_NAME, js_src) - .unwrap(); - - // We need the bytecode buffer to live longer than this function so it can be read from memory - let len = bytecode.len(); - let bytecode_ptr = Box::leak(bytecode.into_boxed_slice()).as_ptr(); - COMPILE_SRC_RET_AREA[0] = bytecode_ptr as u32; - COMPILE_SRC_RET_AREA[1] = len.try_into().unwrap(); - COMPILE_SRC_RET_AREA.as_ptr() + javy_plugin_api::initialize_runtime(config, |runtime| runtime).unwrap(); } /// Evaluates QuickJS bytecode @@ -109,38 +44,10 @@ pub unsafe extern "C" fn compile_src(js_src_ptr: *const u8, js_src_len: usize) - /// # Safety /// /// * `bytecode_ptr` must reference a valid array of unsigned bytes of `bytecode_len` length +// This will be removed as soon as we stop emitting calls to it in dynamically +// linked modules. #[export_name = "eval_bytecode"] pub unsafe extern "C" fn eval_bytecode(bytecode_ptr: *const u8, bytecode_len: usize) { - let runtime = RUNTIME.get().unwrap(); - let bytecode = slice::from_raw_parts(bytecode_ptr, bytecode_len); - execution::run_bytecode(runtime, bytecode, None); -} - -/// Evaluates QuickJS bytecode and optionally invokes exported JS function with -/// name. -/// -/// # Safety -/// -/// * `bytecode_ptr` must reference a valid array of bytes of `bytecode_len` -/// length. -/// * If `fn_name_ptr` is not 0, it must reference a UTF-8 string with -/// `fn_name_len` byte length. -#[export_name = "invoke"] -pub unsafe extern "C" fn invoke( - bytecode_ptr: *const u8, - bytecode_len: usize, - fn_name_ptr: *const u8, - fn_name_len: usize, -) { - let runtime = RUNTIME.get().unwrap(); let bytecode = slice::from_raw_parts(bytecode_ptr, bytecode_len); - let fn_name = if !fn_name_ptr.is_null() && fn_name_len != 0 { - Some(str::from_utf8_unchecked(slice::from_raw_parts( - fn_name_ptr, - fn_name_len, - ))) - } else { - None - }; - execution::run_bytecode(runtime, bytecode, fn_name); + javy_plugin_api::run_bytecode(bytecode, None); } diff --git a/crates/plugin-api/CHANGELOG.md b/crates/plugin-api/CHANGELOG.md new file mode 100644 index 00000000..dd963f2f --- /dev/null +++ b/crates/plugin-api/CHANGELOG.md @@ -0,0 +1,11 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic +Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +Initial release diff --git a/crates/plugin-api/Cargo.toml b/crates/plugin-api/Cargo.toml new file mode 100644 index 00000000..f82df1b4 --- /dev/null +++ b/crates/plugin-api/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "javy-plugin-api" +version = "1.0.0-alpha.1" +authors.workspace = true +edition.workspace = true +license.workspace = true +description = "APIs for Javy plugins" +homepage = "https://github.com/bytecodealliance/javy/tree/main/crates/javy-plugin-api" +repository = "https://github.com/bytecodealliance/javy/tree/main/crates/javy-plugin-api" +categories = ["wasm"] + +[dependencies] +anyhow = { workspace = true } +javy = { workspace = true, features = ["export_alloc_fns"] } + +[features] +experimental_event_loop = [] +json = ["javy/json"] diff --git a/crates/plugin-api/README.md b/crates/plugin-api/README.md new file mode 100644 index 00000000..c57bba49 --- /dev/null +++ b/crates/plugin-api/README.md @@ -0,0 +1,37 @@ +
+

javy-plugin-api

+

+ A crate for creating Javy plugins +

+

+ Documentation Status + crates.io status +

+
+ +Refer to the [crate level documentation](https://docs.rs/javy-plugin-api) to learn more. + +Example usage: + +```rust +use javy_plugin_api::import_namespace; +use javy_plugin_api::javy::Config; + +// Dynamically linked modules will use `my_javy_plugin_v1` as the import +// namespace. +import_namespace!("my_javy_plugin_v1"); + +#[export_name = "initialize_runtime"] +pub extern "C" fn initialize_runtime() { + let mut config = Config::default(); + config + .text_encoding(true) + .javy_stream_io(true); + + javy_plugin_api::initialize_runtime(config, |runtime| runtime).unwrap(); +} +``` + +## Publishing to crates.io + +To publish this crate to crates.io, run `./publish.sh`. diff --git a/crates/plugin-api/publish.sh b/crates/plugin-api/publish.sh new file mode 100755 index 00000000..ecb5ce17 --- /dev/null +++ b/crates/plugin-api/publish.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +set -e + +cargo publish --target=wasm32-wasip1 diff --git a/crates/plugin-api/src/lib.rs b/crates/plugin-api/src/lib.rs new file mode 100644 index 00000000..ddda0f34 --- /dev/null +++ b/crates/plugin-api/src/lib.rs @@ -0,0 +1,220 @@ +//! A crate for creating Javy plugins +//! +//! Example usage: +//! ``` +//! use javy_plugin_api::import_namespace; +//! use javy_plugin_api::javy::Config; +//! +//! // Dynamically linked modules will use `my_javy_plugin_v1` as the import +//! // namespace. +//! import_namespace!("my_javy_plugin_v1"); +//! +//! #[export_name = "initialize_runtime"] +//! pub extern "C" fn initialize_runtime() { +//! let mut config = Config::default(); +//! config +//! .text_encoding(true) +//! .javy_stream_io(true); +//! +//! javy_plugin_api::initialize_runtime(config, |runtime| runtime).unwrap(); +//! } +//! ``` +//! +//! The crate will automatically add exports for a number of Wasm functions in +//! your crate that Javy needs to work. +//! +//! # Core concepts +//! * [`javy`] - a re-export of the [`javy`] crate. +//! * [`import_namespace`] - required to provide an import namespace when the +//! plugin is used to generate dynamically linked modules. +//! * [`initialize_runtime`] - used to configure the QuickJS runtime with a +//! [`javy::Config`] and to add behavior to the created [`javy::Runtime`]. +//! +//! # Features +//! * `experimental_event_loop` - enables the JS event loop. A number of +//! important things are not yet supported so be careful when enabling. +//! * `json` - enables the `json` feature in the `javy` crate. + +use anyhow::{anyhow, bail, Error, Result}; +use javy::quickjs::{self, Ctx, Error as JSError, Function, Module, Value}; +use javy::{from_js_error, Config, Runtime}; +use std::cell::OnceCell; +use std::{process, slice, str}; + +pub use javy; + +mod namespace; + +const FUNCTION_MODULE_NAME: &str = "function.mjs"; + +static mut COMPILE_SRC_RET_AREA: [u32; 2] = [0; 2]; + +static mut RUNTIME: OnceCell = OnceCell::new(); + +static EVENT_LOOP_ERR: &str = r#" + Pending jobs in the event queue. + Scheduling events is not supported when the + experimental_event_loop cargo feature is disabled. + "#; + +/// Initializes the Javy runtime. +pub fn initialize_runtime(config: Config, modify_runtime: F) -> Result<()> +where + F: FnOnce(Runtime) -> Runtime, +{ + let runtime = Runtime::new(config).unwrap(); + let runtime = modify_runtime(runtime); + unsafe { + RUNTIME.take(); // Allow re-initializing. + RUNTIME + .set(runtime) + // `unwrap` requires error `T` to implement `Debug` but `set` + // returns the `javy::Runtime` on error and `javy::Runtime` does not + // implement `Debug`. + .map_err(|_| anyhow!("Could not pre-initialize javy::Runtime")) + .unwrap(); + }; + Ok(()) +} + +/// Compiles JS source code to QuickJS bytecode. +/// +/// Returns a pointer to a buffer containing a 32-bit pointer to the bytecode byte array and the +/// u32 length of the bytecode byte array. +/// +/// # Arguments +/// +/// * `js_src_ptr` - A pointer to the start of a byte array containing UTF-8 JS source code +/// * `js_src_len` - The length of the byte array containing JS source code +/// +/// # Safety +/// +/// * `js_src_ptr` must reference a valid array of unsigned bytes of `js_src_len` length +#[export_name = "compile_src"] +pub unsafe extern "C" fn compile_src(js_src_ptr: *const u8, js_src_len: usize) -> *const u32 { + // Use initialized runtime when compiling because certain runtime + // configurations can cause different bytecode to be emitted. + // + // For example, given the following JS: + // ``` + // function foo() { + // "use math" + // 1234 % 32 + // } + // ``` + // + // Setting `config.bignum_extension` to `true` will produce different + // bytecode than if it were set to `false`. + let runtime = unsafe { RUNTIME.get().unwrap() }; + let js_src = str::from_utf8(slice::from_raw_parts(js_src_ptr, js_src_len)).unwrap(); + + let bytecode = runtime + .compile_to_bytecode(FUNCTION_MODULE_NAME, js_src) + .unwrap(); + + // We need the bytecode buffer to live longer than this function so it can be read from memory + let len = bytecode.len(); + let bytecode_ptr = Box::leak(bytecode.into_boxed_slice()).as_ptr(); + COMPILE_SRC_RET_AREA[0] = bytecode_ptr as u32; + COMPILE_SRC_RET_AREA[1] = len.try_into().unwrap(); + COMPILE_SRC_RET_AREA.as_ptr() +} + +/// Evaluates QuickJS bytecode and optionally invokes exported JS function with +/// name. +/// +/// # Safety +/// +/// * `bytecode_ptr` must reference a valid array of bytes of `bytecode_len` +/// length. +/// * If `fn_name_ptr` is not 0, it must reference a UTF-8 string with +/// `fn_name_len` byte length. +#[export_name = "invoke"] +pub unsafe extern "C" fn invoke( + bytecode_ptr: *const u8, + bytecode_len: usize, + fn_name_ptr: *const u8, + fn_name_len: usize, +) { + let bytecode = slice::from_raw_parts(bytecode_ptr, bytecode_len); + let fn_name = if !fn_name_ptr.is_null() && fn_name_len != 0 { + Some(str::from_utf8_unchecked(slice::from_raw_parts( + fn_name_ptr, + fn_name_len, + ))) + } else { + None + }; + run_bytecode(bytecode, fn_name); +} + +/// Evaluate the given bytecode. +/// +/// Deprecated for use outside of this crate. +/// +/// Evaluating also prepares (or "instantiates") the state of the JavaScript +/// engine given all the information encoded in the bytecode. +pub fn run_bytecode(bytecode: &[u8], fn_name: Option<&str>) { + let runtime = unsafe { RUNTIME.get() }.unwrap(); + runtime + .context() + .with(|this| { + let module = unsafe { Module::load(this.clone(), bytecode)? }; + let (module, promise) = module.eval()?; + + handle_maybe_promise(this.clone(), promise.into())?; + + if let Some(fn_name) = fn_name { + let fun: Function = module.get(fn_name)?; + // Exported functions are guaranteed not to have arguments so + // we can safely pass an empty tuple for arguments. + let value = fun.call(())?; + handle_maybe_promise(this.clone(), value)? + } + Ok(()) + }) + .map_err(|e| runtime.context().with(|cx| from_js_error(cx.clone(), e))) + .and_then(|_: ()| ensure_pending_jobs(runtime)) + .unwrap_or_else(handle_error) +} + +/// Handles the promise returned by evaluating the JS bytecode. +fn handle_maybe_promise(this: Ctx, value: Value) -> quickjs::Result<()> { + match value.as_promise() { + Some(promise) => { + if cfg!(feature = "experimental_event_loop") { + // If the experimental event loop is enabled, trigger it. + let resolved = promise.finish::(); + // `Promise::finish` returns Err(Wouldblock) when the all + // pending jobs have been handled. + if let Err(JSError::WouldBlock) = resolved { + Ok(()) + } else { + resolved.map(|_| ()) + } + } else { + // Else we simply expect the promise to resolve immediately. + match promise.result() { + None => Err(javy::to_js_error(this, anyhow!(EVENT_LOOP_ERR))), + Some(r) => r, + } + } + } + None => Ok(()), + } +} + +fn ensure_pending_jobs(rt: &Runtime) -> Result<()> { + if cfg!(feature = "experimental_event_loop") { + rt.resolve_pending_jobs() + } else if rt.has_pending_jobs() { + bail!(EVENT_LOOP_ERR); + } else { + Ok(()) + } +} + +fn handle_error(e: Error) { + eprintln!("{e}"); + process::abort(); +} diff --git a/crates/core/src/namespace.rs b/crates/plugin-api/src/namespace.rs similarity index 79% rename from crates/core/src/namespace.rs rename to crates/plugin-api/src/namespace.rs index d882d54a..8005ffb2 100644 --- a/crates/core/src/namespace.rs +++ b/crates/plugin-api/src/namespace.rs @@ -1,5 +1,6 @@ -// Create a custom section named `import_namespace` with the contents of the -// string argument. +/// Create a custom section named `import_namespace` with the contents of the +/// string argument. +#[macro_export] macro_rules! import_namespace { ($str:literal) => { const IMPORT_NAMESPACE_BYTES: &[u8] = $str.as_bytes(); @@ -16,5 +17,3 @@ macro_rules! import_namespace { }; }; } - -pub(crate) use import_namespace; From 896121f843bdd739cb887b0283ed23a1f507ad16 Mon Sep 17 00:00:00 2001 From: Jeffrey Charles Date: Thu, 31 Oct 2024 09:36:55 -0400 Subject: [PATCH 2/3] Add rust to example usage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Saúl Cabrera --- crates/plugin-api/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/plugin-api/src/lib.rs b/crates/plugin-api/src/lib.rs index ddda0f34..a3953df2 100644 --- a/crates/plugin-api/src/lib.rs +++ b/crates/plugin-api/src/lib.rs @@ -1,7 +1,7 @@ //! A crate for creating Javy plugins //! //! Example usage: -//! ``` +//! ```rust //! use javy_plugin_api::import_namespace; //! use javy_plugin_api::javy::Config; //! From 1745c96dc683dd464ee2b4ecdbe0c15b2f0ead64 Mon Sep 17 00:00:00 2001 From: Jeff Charles Date: Thu, 31 Oct 2024 09:45:23 -0400 Subject: [PATCH 3/3] Move dependency out of workspace --- Cargo.toml | 1 - crates/core/Cargo.toml | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c271f595..f9ef39af 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,6 @@ wasmtime-wasi = "19" wasi-common = "19" anyhow = "1.0" javy = { path = "crates/javy", version = "3.0.2-alpha.1" } -javy-plugin-api = { path = "crates/plugin-api", version = "1.0.0-alpha.1" } tempfile = "3.13.0" uuid = { version = "1.10", features = ["v4"] } serde = { version = "1.0", default-features = false } diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index 5a72553a..9c77d69b 100644 --- a/crates/core/Cargo.toml +++ b/crates/core/Cargo.toml @@ -11,7 +11,7 @@ crate-type = ["cdylib"] [dependencies] anyhow = { workspace = true } -javy-plugin-api = { workspace = true, features = ["json"] } +javy-plugin-api = { path = "../plugin-api", features = ["json"] } serde = { workspace = true } serde_json = { workspace = true }