Skip to content

Commit

Permalink
refactor(bindings): Deprecate JsValue::*_serde (#6436)
Browse files Browse the repository at this point in the history
  • Loading branch information
kwonoj committed Nov 14, 2022
1 parent cdc1b4c commit 1dd8b3d
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 41 deletions.
26 changes: 14 additions & 12 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions bindings/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion bindings/binding_core_wasm/Cargo.toml
Expand Up @@ -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
48 changes: 36 additions & 12 deletions 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::{
Expand All @@ -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)]
Expand Down Expand Up @@ -81,12 +89,16 @@ pub fn minify_sync(s: JsString, opts: JsValue) -> Result<JsValue, JsValue> {
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")

program
.serialize(&COMPAT_SERIALIZER)
.map_err(|e| anyhow::anyhow!("failed to serialize program: {}", e))
})
})
.map_err(|e| convert_err(e, None))
Expand All @@ -106,7 +118,8 @@ pub fn parse_sync(s: JsString, opts: JsValue) -> Result<JsValue, JsValue> {
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();
Expand All @@ -133,7 +146,9 @@ pub fn parse_sync(s: JsString, opts: JsValue) -> Result<JsValue, JsValue> {
opts.syntax.typescript(),
));

anyhow::Context::context(JsValue::from_serde(&program), "failed to serialize json")
program
.serialize(&COMPAT_SERIALIZER)
.map_err(|e| anyhow::anyhow!("failed to serialize program: {}", e))
})
})
})
Expand All @@ -160,9 +175,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(|| {
Expand Down Expand Up @@ -193,9 +208,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("Should able to deserialize into program"), &opts)?
}
};
anyhow::Context::context(JsValue::from_serde(&out), "failed to serialize json")

out.serialize(&COMPAT_SERIALIZER)
.map_err(|e| anyhow::anyhow!("failed to serialize transform result: {}", e))
})
})
.map_err(|e| convert_err(e, Some(error_format)))
Expand All @@ -218,10 +237,13 @@ pub fn print_sync(s: JsValue, opts: JsValue) -> Result<JsValue, JsValue> {
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,
Expand All @@ -241,7 +263,9 @@ pub fn print_sync(s: JsValue, opts: JsValue) -> Result<JsValue, JsValue> {
),
"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))
Expand Down
3 changes: 2 additions & 1 deletion crates/binding_macros/Cargo.toml
Expand Up @@ -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" }
46 changes: 31 additions & 15 deletions crates/binding_macros/src/wasm.rs
Expand Up @@ -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::{
Expand All @@ -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<Compiler> {
console_error_panic_hook::set_once();
Expand Down Expand Up @@ -66,13 +74,16 @@ 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")
program
.serialize(&COMPAT_SERIALIZER)
.map_err(|e| $crate::wasm::anyhow::anyhow!("failed to serialize program: {}", e))
})
},
)
Expand Down Expand Up @@ -115,7 +126,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());
Expand All @@ -140,7 +152,9 @@ macro_rules! build_parse_sync {
"failed to parse code"
)?;

$crate::wasm::anyhow::Context::context($crate::wasm::JsValue::from_serde(&program), "failed to serialize json")
program
.serialize(&COMPAT_SERIALIZER)
.map_err(|e| $crate::wasm::anyhow::anyhow!("failed to serialize program: {}", e))
})
},
)
Expand Down Expand Up @@ -183,10 +197,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,
Expand All @@ -205,7 +221,9 @@ macro_rules! build_print_sync {
false,
),"failed to print code")?;

$crate::wasm::anyhow::Context::context(JsValue::from_serde(&s), "failed to serialize json")
program
.serialize(&COMPAT_SERIALIZER)
.map_err(|e| $crate::wasm::anyhow::anyhow!("failed to serialize program: {}", e))
})
},
)
Expand Down Expand Up @@ -281,9 +299,7 @@ macro_rules! build_transform_sync {
buffer
};

let bytes: Vec<u8> = data
.into_serde()
.expect("Could not read byte from plugin resolver");
let bytes: Vec<u8> = $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
Expand All @@ -296,8 +312,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();
Expand Down Expand Up @@ -333,11 +348,12 @@ 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")
out
.serialize(&COMPAT_SERIALIZER)
.map_err(|e| $crate::wasm::anyhow::anyhow!("failed to serialize transform result: {}", e))
})
},
)
Expand Down

1 comment on commit 1dd8b3d

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark

Benchmark suite Current: 1dd8b3d Previous: 81a4bb3 Ratio
es/full/bugs-1 359764 ns/iter (± 35638) 347052 ns/iter (± 20512) 1.04
es/full/minify/libraries/antd 1859260645 ns/iter (± 50064656) 1923725849 ns/iter (± 40306160) 0.97
es/full/minify/libraries/d3 407449725 ns/iter (± 22362328) 439671932 ns/iter (± 31729477) 0.93
es/full/minify/libraries/echarts 1612858764 ns/iter (± 52492529) 1643646581 ns/iter (± 58778615) 0.98
es/full/minify/libraries/jquery 100909663 ns/iter (± 11908356) 114105698 ns/iter (± 7923322) 0.88
es/full/minify/libraries/lodash 134324510 ns/iter (± 10291658) 133984446 ns/iter (± 21300946) 1.00
es/full/minify/libraries/moment 67175152 ns/iter (± 8010933) 60560367 ns/iter (± 3894269) 1.11
es/full/minify/libraries/react 21767308 ns/iter (± 633949) 20593417 ns/iter (± 2786835) 1.06
es/full/minify/libraries/terser 318945153 ns/iter (± 12126350) 345732662 ns/iter (± 19628473) 0.92
es/full/minify/libraries/three 575525366 ns/iter (± 33154379) 582607608 ns/iter (± 29822859) 0.99
es/full/minify/libraries/typescript 3525404089 ns/iter (± 93756360) 3587011200 ns/iter (± 259198665) 0.98
es/full/minify/libraries/victory 854009311 ns/iter (± 18508124) 945429374 ns/iter (± 75184631) 0.90
es/full/minify/libraries/vue 186769157 ns/iter (± 10795873) 179476890 ns/iter (± 14293493) 1.04
es/full/codegen/es3 35987 ns/iter (± 2947) 35156 ns/iter (± 3929) 1.02
es/full/codegen/es5 35271 ns/iter (± 2919) 34958 ns/iter (± 2512) 1.01
es/full/codegen/es2015 35398 ns/iter (± 2191) 34488 ns/iter (± 1564) 1.03
es/full/codegen/es2016 35354 ns/iter (± 3173) 34127 ns/iter (± 1825) 1.04
es/full/codegen/es2017 35284 ns/iter (± 2622) 34442 ns/iter (± 3106) 1.02
es/full/codegen/es2018 35578 ns/iter (± 4212) 34504 ns/iter (± 4328) 1.03
es/full/codegen/es2019 35800 ns/iter (± 3202) 34753 ns/iter (± 3736) 1.03
es/full/codegen/es2020 35466 ns/iter (± 3811) 34691 ns/iter (± 5722) 1.02
es/full/all/es3 217580563 ns/iter (± 21596484) 232540296 ns/iter (± 30431077) 0.94
es/full/all/es5 185495295 ns/iter (± 15440090) 216932331 ns/iter (± 44851067) 0.86
es/full/all/es2015 162503849 ns/iter (± 17551828) 168650590 ns/iter (± 28210961) 0.96
es/full/all/es2016 155546701 ns/iter (± 21213081) 184085282 ns/iter (± 33544797) 0.84
es/full/all/es2017 165784208 ns/iter (± 18397331) 176378828 ns/iter (± 32859530) 0.94
es/full/all/es2018 160782944 ns/iter (± 18813240) 170432604 ns/iter (± 15447414) 0.94
es/full/all/es2019 149664700 ns/iter (± 11898224) 173107005 ns/iter (± 26194868) 0.86
es/full/all/es2020 147589823 ns/iter (± 12281102) 176772997 ns/iter (± 24962885) 0.83
es/full/parser 752944 ns/iter (± 74353) 793736 ns/iter (± 112062) 0.95
es/full/base/fixer 27952 ns/iter (± 3623) 30184 ns/iter (± 5813) 0.93
es/full/base/resolver_and_hygiene 95506 ns/iter (± 8627) 95874 ns/iter (± 19630) 1.00
serialization of ast node 215 ns/iter (± 3) 221 ns/iter (± 20) 0.97
serialization of serde 228 ns/iter (± 24) 235 ns/iter (± 28) 0.97

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.