From d52ecc91b3d4f7710bbf5eb68abf45d279365d42 Mon Sep 17 00:00:00 2001 From: OJ Kwon <1210596+kwonoj@users.noreply.github.com> Date: Mon, 14 Nov 2022 10:12:34 -0800 Subject: [PATCH 1/3] refactor(bindings/wasm): deprecate jsvalue::*_serde --- bindings/binding_core_wasm/src/lib.rs | 38 ++++++++++++++++++--------- crates/binding_macros/src/wasm.rs | 34 +++++++++++++----------- 2 files changed, 45 insertions(+), 27 deletions(-) diff --git a/bindings/binding_core_wasm/src/lib.rs b/bindings/binding_core_wasm/src/lib.rs index 9df28d760676..0ec735ff5a95 100644 --- a/bindings/binding_core_wasm/src/lib.rs +++ b/bindings/binding_core_wasm/src/lib.rs @@ -81,12 +81,15 @@ pub fn minify_sync(s: JsString, opts: JsValue) -> Result { let opts = if opts.is_null() || opts.is_undefined() { Default::default() } else { - anyhow::Context::context(opts.into_serde(), "failed to parse options")? + serde_wasm_bindgen::from_value(opts) + .map_err(|e| anyhow::anyhow!("failed to parse options: {}", e))? }; let fm = c.cm.new_source_file(FileName::Anon, s.into()); let program = anyhow::Context::context(c.minify(fm, handler, &opts), "failed to minify file")?; - anyhow::Context::context(JsValue::from_serde(&program), "failed to serialize json") + + serde_wasm_bindgen::to_value(&program) + .map_err(|e| anyhow::anyhow!("failed to deserialize program: {}", e)) }) }) .map_err(|e| convert_err(e, None)) @@ -106,7 +109,8 @@ pub fn parse_sync(s: JsString, opts: JsValue) -> Result { let opts: ParseOptions = if opts.is_null() || opts.is_undefined() { Default::default() } else { - anyhow::Context::context(opts.into_serde(), "failed to parse options")? + serde_wasm_bindgen::from_value(opts) + .map_err(|e| anyhow::anyhow!("failed to parse options: {}", e))? }; let fm = c.cm.new_source_file(FileName::Anon, s.into()); let cmts = c.comments().clone(); @@ -133,7 +137,8 @@ pub fn parse_sync(s: JsString, opts: JsValue) -> Result { opts.syntax.typescript(), )); - anyhow::Context::context(JsValue::from_serde(&program), "failed to serialize json") + serde_wasm_bindgen::to_value(&program) + .map_err(|e| anyhow::anyhow!("failed to serialize json: {}", e)) }) }) }) @@ -160,9 +165,9 @@ pub fn transform_sync( let opts: Options = if opts.is_null() || opts.is_undefined() { Default::default() } else { - anyhow::Context::context(opts.into_serde(), "failed to parse options") - .map_err(|e| convert_err(e, None))? + serde_wasm_bindgen::from_value(opts)? }; + let error_format = opts.experimental.error_format.unwrap_or_default(); try_with_handler(c.cm.clone(), Default::default(), |handler| { c.run(|| { @@ -193,9 +198,13 @@ pub fn transform_sync( "failed to process js file", )? } - Err(v) => unsafe { c.process_js(handler, v.into_serde().expect(""), &opts)? }, + Err(v) => { + c.process_js(handler, serde_wasm_bindgen::from_value(v).expect(""), &opts)? + }, }; - anyhow::Context::context(JsValue::from_serde(&out), "failed to serialize json") + + serde_wasm_bindgen::to_value(&out) + .map_err(|e| anyhow::anyhow!("failed to serialize json: {}", e)) }) }) .map_err(|e| convert_err(e, Some(error_format))) @@ -218,10 +227,13 @@ pub fn print_sync(s: JsValue, opts: JsValue) -> Result { let opts: Options = if opts.is_null() || opts.is_undefined() { Default::default() } else { - anyhow::Context::context(opts.into_serde(), "failed to parse options")? + serde_wasm_bindgen::from_value(opts) + .map_err(|e| anyhow::anyhow!("failed to parse options: {}", e))? }; - let program: Program = - anyhow::Context::context(s.into_serde(), "failed to deserialize program")?; + + let program: Program = serde_wasm_bindgen::from_value(s) + .map_err(|e| anyhow::anyhow!("failed to deserialize program: {}", e))?; + let s = anyhow::Context::context( c.print( &program, @@ -241,7 +253,9 @@ pub fn print_sync(s: JsValue, opts: JsValue) -> Result { ), "failed to print code", )?; - anyhow::Context::context(JsValue::from_serde(&s), "failed to serialize json") + + serde_wasm_bindgen::to_value(&s) + .map_err(|e| anyhow::anyhow!("failed to serialize json: {}", e)) }) }) .map_err(|e| convert_err(e, None)) diff --git a/crates/binding_macros/src/wasm.rs b/crates/binding_macros/src/wasm.rs index a5e2aff01d3d..e68fd608850e 100644 --- a/crates/binding_macros/src/wasm.rs +++ b/crates/binding_macros/src/wasm.rs @@ -66,13 +66,15 @@ macro_rules! build_minify_sync { let opts = if opts.is_null() || opts.is_undefined() { Default::default() } else { - $crate::wasm::anyhow::Context::context(opts.into_serde(), "failed to parse options")? + $crate::wasm::serde_wasm_bindgen::from_value(opts) + .map_err(|e| $crate::wasm::anyhow::anyhow!("failed to parse options: {}", e))? }; let fm = c.cm.new_source_file($crate::wasm::FileName::Anon, s.into()); let program = $crate::wasm::anyhow::Context::context(c.minify(fm, handler, &opts), "failed to minify file")?; - $crate::wasm::anyhow::Context::context($crate::wasm::JsValue::from_serde(&program), "failed to serialize json") + $crate::wasm::serde_wasm_bindgen::to_value(&program) + .map_err(|e| $crate::wasm::anyhow::anyhow!("failed to deserialize program: {}", e)) }) }, ) @@ -115,7 +117,8 @@ macro_rules! build_parse_sync { let opts: $crate::wasm::ParseOptions = if opts.is_null() || opts.is_undefined() { Default::default() } else { - $crate::wasm::anyhow::Context::context(opts.into_serde(), "failed to parse options")? + $crate::wasm::serde_wasm_bindgen::from_value(opts) + .map_err(|e| $crate::wasm::anyhow::anyhow!("failed to parse options: {}", e))? }; let fm = c.cm.new_source_file($crate::wasm::FileName::Anon, s.into()); @@ -140,7 +143,8 @@ macro_rules! build_parse_sync { "failed to parse code" )?; - $crate::wasm::anyhow::Context::context($crate::wasm::JsValue::from_serde(&program), "failed to serialize json") + $crate::wasm::serde_wasm_bindgen::to_value(&program) + .map_err(|e| $crate::wasm::anyhow::anyhow!("failed to deserialize program: {}", e)) }) }, ) @@ -183,10 +187,12 @@ macro_rules! build_print_sync { let opts: $crate::wasm::Options = if opts.is_null() || opts.is_undefined() { Default::default() } else { - $crate::wasm::anyhow::Context::context(opts.into_serde(), "failed to parse options")? + $crate::wasm::serde_wasm_bindgen::from_value(opts) + .map_err(|e| $crate::wasm::anyhow::anyhow!("failed to parse options: {}", e))? }; - let program: $crate::wasm::Program = $crate::wasm::anyhow::Context::context(s.into_serde(), "failed to deserialize program")?; + let program: $crate::wasm::Program = $crate::wasm::serde_wasm_bindgen::from_value(s) + .map_err(|e| $crate::wasm::anyhow::anyhow!("failed to deserialize program: {}", e))?; let s = $crate::wasm::anyhow::Context::context(c .print( &program, @@ -205,7 +211,8 @@ macro_rules! build_print_sync { false, ),"failed to print code")?; - $crate::wasm::anyhow::Context::context(JsValue::from_serde(&s), "failed to serialize json") + $crate::wasm::serde_wasm_bindgen::to_value(&s) + .map_err(|e| $crate::wasm::anyhow::anyhow!("failed to serialize json: {}", e)) }) }, ) @@ -281,9 +288,7 @@ macro_rules! build_transform_sync { buffer }; - let bytes: Vec = data - .into_serde() - .expect("Could not read byte from plugin resolver"); + let bytes: Vec = $crate::wasm::serde_wasm_bindgen::from_value(data).expect("Could not read byte from plugin resolver"); // In here we 'inject' externally loaded bytes into the cache, so // remaining plugin_runner execution path works as much as @@ -296,8 +301,7 @@ macro_rules! build_transform_sync { let opts: $crate::wasm::Options = if opts.is_null() || opts.is_undefined() { Default::default() } else { - $crate::wasm::anyhow::Context::context(opts.into_serde(), "failed to parse options") - .map_err(|e| $crate::wasm::convert_err(e, None))? + $crate::wasm::serde_wasm_bindgen::from_value(opts)? }; let error_format = opts.experimental.error_format.unwrap_or_default(); @@ -333,11 +337,11 @@ macro_rules! build_transform_sync { ), "failed to process js file" )? } - Err(v) => unsafe { c.process_js(handler, v.into_serde().expect(""), &opts)? }, + Err(v) => unsafe { c.process_js(handler, $crate::wasm::serde_wasm_bindgen::from_value(v).expect(""), &opts)? }, }; - $crate::wasm::anyhow::Context::context($crate::wasm::JsValue::from_serde(&out), - "failed to serialize json") + $crate::wasm::serde_wasm_bindgen::to_value(&out) + .map_err(|e| $crate::wasm::anyhow::anyhow!("failed to serialize json: {}", e)) }) }, ) From c6423bf86dc2bb280369e5d2017ca8fa7777afb7 Mon Sep 17 00:00:00 2001 From: OJ Kwon <1210596+kwonoj@users.noreply.github.com> Date: Mon, 14 Nov 2022 10:13:06 -0800 Subject: [PATCH 2/3] build(cargo): update lockfile, dependencies --- Cargo.lock | 26 ++++++++++++++------------ bindings/Cargo.lock | 2 ++ bindings/binding_core_wasm/Cargo.toml | 3 ++- crates/binding_macros/Cargo.toml | 3 ++- 4 files changed, 20 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c5378f291e5d..42393bdc3697 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -174,6 +174,8 @@ dependencies = [ "console_error_panic_hook", "js-sys", "once_cell", + "serde", + "serde-wasm-bindgen", "swc", "swc_common", "swc_ecma_ast", @@ -2655,9 +2657,9 @@ dependencies = [ [[package]] name = "serde-wasm-bindgen" -version = "0.4.3" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cfc62771e7b829b517cb213419236475f434fb480eddd76112ae182d274434a" +checksum = "e3b4c031cd0d9014307d82b8abf653c0290fbdaeb4c02d00c63cf52f728628bf" dependencies = [ "js-sys", "serde", @@ -4915,9 +4917,9 @@ checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[package]] name = "wasm-bindgen" -version = "0.2.82" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7652e3f6c4706c8d9cd54832c4a4ccb9b5336e2c3bd154d5cccfbf1c1f5f7d" +checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" dependencies = [ "cfg-if 1.0.0", "serde", @@ -4927,9 +4929,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.82" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "662cd44805586bd52971b9586b1df85cdbbd9112e4ef4d8f41559c334dc6ac3f" +checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" dependencies = [ "bumpalo", "log", @@ -4954,9 +4956,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.82" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b260f13d3012071dfb1512849c033b1925038373aea48ced3012c09df952c602" +checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4964,9 +4966,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.82" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be8e654bdd9b79216c2929ab90721aa82faf65c48cdf08bdc4e7f51357b80da" +checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" dependencies = [ "proc-macro2", "quote", @@ -4977,9 +4979,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.82" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6598dd0bd3c7d51095ff6531a5b23e02acdc81804e30d8f07afb77b7215a140a" +checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" [[package]] name = "wasmer" diff --git a/bindings/Cargo.lock b/bindings/Cargo.lock index 3bdc1d03d448..3c322822dd4d 100644 --- a/bindings/Cargo.lock +++ b/bindings/Cargo.lock @@ -179,6 +179,8 @@ name = "binding_core_wasm" version = "1.3.16" dependencies = [ "anyhow", + "serde", + "serde-wasm-bindgen", "swc_core", "tracing", "wasm-bindgen", diff --git a/bindings/binding_core_wasm/Cargo.toml b/bindings/binding_core_wasm/Cargo.toml index 0ed3ca6f6130..f4d56033c910 100644 --- a/bindings/binding_core_wasm/Cargo.toml +++ b/bindings/binding_core_wasm/Cargo.toml @@ -29,9 +29,10 @@ swc_core = { version = "0.43.3", features = [ ] } tracing = { version = "0.1.37", features = ["max_level_off"] } wasm-bindgen = { version = "0.2.82", features = [ - "serde-serialize", "enable-interning", ] } +serde = { version = "1", features = ["derive"] } +serde-wasm-bindgen = "0.4.5" [package.metadata.wasm-pack.profile.release] wasm-opt = false diff --git a/crates/binding_macros/Cargo.toml b/crates/binding_macros/Cargo.toml index 13d3ee7fb5d0..aee83f3563a6 100644 --- a/crates/binding_macros/Cargo.toml +++ b/crates/binding_macros/Cargo.toml @@ -40,8 +40,9 @@ anyhow = { optional = true, version = "1.0.58" } console_error_panic_hook = { optional = true, version = "0.1.7" } js-sys = { optional = true, version = "0.3.59" } once_cell = { optional = true, version = "1.13.0" } +serde = { optional = true, version = "1", features = ["derive"] } wasm-bindgen = { optional = true, version = "0.2.82", features = [ - "serde-serialize", "enable-interning", ] } wasm-bindgen-futures = { optional = true, version = "0.4.32" } +serde-wasm-bindgen = { optional = true, version = "0.4.5" } From e301cf588e752ff0f9a31d3e8fcd06cddc36e1df Mon Sep 17 00:00:00 2001 From: OJ Kwon <1210596+kwonoj@users.noreply.github.com> Date: Mon, 14 Nov 2022 11:34:54 -0800 Subject: [PATCH 3/3] fix(binding/wasm): provides backward compat output --- bindings/binding_core_wasm/src/lib.rs | 26 +++++++++++++++++-------- crates/binding_macros/src/wasm.rs | 28 +++++++++++++++++++-------- 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/bindings/binding_core_wasm/src/lib.rs b/bindings/binding_core_wasm/src/lib.rs index 0ec735ff5a95..0ecf9f981e46 100644 --- a/bindings/binding_core_wasm/src/lib.rs +++ b/bindings/binding_core_wasm/src/lib.rs @@ -1,4 +1,6 @@ use anyhow::Error; +use serde::Serialize; +use serde_wasm_bindgen::Serializer; use swc_core::{ base::HandlerOpts, binding_macros::wasm::{ @@ -21,6 +23,12 @@ use swc_core::{ use wasm_bindgen::{prelude::*, JsCast}; mod types; +// A serializer with options to provide backward compat for the input / output +// from the bindgen generated swc interfaces. +const COMPAT_SERIALIZER: Serializer = Serializer::new() + .serialize_maps_as_objects(true) + .serialize_missing_as_null(true); + /// Custom interface definitions for the @swc/wasm's public interface instead of /// auto generated one, which is not reflecting most of types in detail. #[wasm_bindgen(typescript_custom_section)] @@ -88,8 +96,9 @@ pub fn minify_sync(s: JsString, opts: JsValue) -> Result { let program = anyhow::Context::context(c.minify(fm, handler, &opts), "failed to minify file")?; - serde_wasm_bindgen::to_value(&program) - .map_err(|e| anyhow::anyhow!("failed to deserialize program: {}", e)) + program + .serialize(&COMPAT_SERIALIZER) + .map_err(|e| anyhow::anyhow!("failed to serialize program: {}", e)) }) }) .map_err(|e| convert_err(e, None)) @@ -137,8 +146,9 @@ pub fn parse_sync(s: JsString, opts: JsValue) -> Result { opts.syntax.typescript(), )); - serde_wasm_bindgen::to_value(&program) - .map_err(|e| anyhow::anyhow!("failed to serialize json: {}", e)) + program + .serialize(&COMPAT_SERIALIZER) + .map_err(|e| anyhow::anyhow!("failed to serialize program: {}", e)) }) }) }) @@ -199,12 +209,12 @@ pub fn transform_sync( )? } Err(v) => { - c.process_js(handler, serde_wasm_bindgen::from_value(v).expect(""), &opts)? - }, + c.process_js(handler, serde_wasm_bindgen::from_value(v).expect("Should able to deserialize into program"), &opts)? + } }; - serde_wasm_bindgen::to_value(&out) - .map_err(|e| anyhow::anyhow!("failed to serialize json: {}", e)) + out.serialize(&COMPAT_SERIALIZER) + .map_err(|e| anyhow::anyhow!("failed to serialize transform result: {}", e)) }) }) .map_err(|e| convert_err(e, Some(error_format))) diff --git a/crates/binding_macros/src/wasm.rs b/crates/binding_macros/src/wasm.rs index e68fd608850e..f857b01655a7 100644 --- a/crates/binding_macros/src/wasm.rs +++ b/crates/binding_macros/src/wasm.rs @@ -6,6 +6,8 @@ use anyhow::Error; #[doc(hidden)] pub use js_sys; use once_cell::sync::Lazy; +use serde::Serialize; +use serde_wasm_bindgen::Serializer; use swc::{config::ErrorFormat, Compiler}; #[doc(hidden)] pub use swc::{ @@ -24,6 +26,12 @@ pub use wasm_bindgen::{JsCast, JsValue}; #[doc(hidden)] pub use wasm_bindgen_futures::future_to_promise; +// A serializer with options to provide backward compat for the input / output +// from the bindgen generated swc interfaces. +const COMPAT_SERIALIZER: Serializer = Serializer::new() + .serialize_maps_as_objects(true) + .serialize_missing_as_null(true); + /// Get global sourcemap pub fn compiler() -> Arc { console_error_panic_hook::set_once(); @@ -73,8 +81,9 @@ macro_rules! build_minify_sync { let fm = c.cm.new_source_file($crate::wasm::FileName::Anon, s.into()); let program = $crate::wasm::anyhow::Context::context(c.minify(fm, handler, &opts), "failed to minify file")?; - $crate::wasm::serde_wasm_bindgen::to_value(&program) - .map_err(|e| $crate::wasm::anyhow::anyhow!("failed to deserialize program: {}", e)) + program + .serialize(&COMPAT_SERIALIZER) + .map_err(|e| $crate::wasm::anyhow::anyhow!("failed to serialize program: {}", e)) }) }, ) @@ -143,8 +152,9 @@ macro_rules! build_parse_sync { "failed to parse code" )?; - $crate::wasm::serde_wasm_bindgen::to_value(&program) - .map_err(|e| $crate::wasm::anyhow::anyhow!("failed to deserialize program: {}", e)) + program + .serialize(&COMPAT_SERIALIZER) + .map_err(|e| $crate::wasm::anyhow::anyhow!("failed to serialize program: {}", e)) }) }, ) @@ -211,8 +221,9 @@ macro_rules! build_print_sync { false, ),"failed to print code")?; - $crate::wasm::serde_wasm_bindgen::to_value(&s) - .map_err(|e| $crate::wasm::anyhow::anyhow!("failed to serialize json: {}", e)) + program + .serialize(&COMPAT_SERIALIZER) + .map_err(|e| $crate::wasm::anyhow::anyhow!("failed to serialize program: {}", e)) }) }, ) @@ -340,8 +351,9 @@ macro_rules! build_transform_sync { Err(v) => unsafe { c.process_js(handler, $crate::wasm::serde_wasm_bindgen::from_value(v).expect(""), &opts)? }, }; - $crate::wasm::serde_wasm_bindgen::to_value(&out) - .map_err(|e| $crate::wasm::anyhow::anyhow!("failed to serialize json: {}", e)) + out + .serialize(&COMPAT_SERIALIZER) + .map_err(|e| $crate::wasm::anyhow::anyhow!("failed to serialize transform result: {}", e)) }) }, )