From a104c89bf4a220b729ff33854f12c8136f757ed5 Mon Sep 17 00:00:00 2001 From: Nasr Date: Tue, 26 Aug 2025 13:47:40 +0100 Subject: [PATCH 1/5] fix --- src/wasm/utils.rs | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/src/wasm/utils.rs b/src/wasm/utils.rs index 8ed213b..10d5a8d 100644 --- a/src/wasm/utils.rs +++ b/src/wasm/utils.rs @@ -2,17 +2,56 @@ use std::collections::HashMap; use num_bigint::BigUint; use num_traits::Num; +use serde_json::Value as JsonValue; use wasm_bindgen::JsValue; use super::types::{EnumValue, Ty}; use crate::wasm::types::FixedSizeArray; +fn json_value_to_js_value(json_value: &JsonValue) -> JsValue { + match json_value { + JsonValue::Null => JsValue::NULL, + JsonValue::Bool(b) => JsValue::from(*b), + JsonValue::Number(n) => { + if let Some(i) = n.as_i64() { + JsValue::from(i) + } else if let Some(u) = n.as_u64() { + JsValue::from(u) + } else if let Some(f) = n.as_f64() { + JsValue::from(f) + } else { + JsValue::from(n.to_string()) + } + } + JsonValue::String(s) => JsValue::from(s.as_str()), + JsonValue::Array(arr) => { + let js_array = js_sys::Array::new(); + for item in arr { + js_array.push(&json_value_to_js_value(item)); + } + js_array.into() + } + JsonValue::Object(obj) => { + let js_obj = js_sys::Object::new(); + for (key, value) in obj { + js_sys::Reflect::set( + &js_obj, + &JsValue::from(key.as_str()), + &json_value_to_js_value(value), + ) + .unwrap(); + } + js_obj.into() + } + } +} + pub fn parse_ty_as_json_str(ty: &dojo_types::schema::Ty, key: bool) -> Ty { match ty { dojo_types::schema::Ty::Primitive(primitive) => Ty { r#type: "primitive".to_string(), type_name: ty.name(), - value: serde_wasm_bindgen::to_value(&primitive.to_json_value().unwrap()).unwrap(), + value: json_value_to_js_value(&primitive.to_json_value().unwrap()), key, }, dojo_types::schema::Ty::Struct(struct_ty) => Ty { From 4ec09d8ca4858d56e587a7f0a2969aa584065d55 Mon Sep 17 00:00:00 2001 From: Nasr Date: Tue, 26 Aug 2025 13:53:36 +0100 Subject: [PATCH 2/5] use gloo utils --- Cargo.lock | 2 + Cargo.toml | 4 ++ src/wasm/utils.rs | 157 +++++++++++++++++++++++++++++++++++----------- 3 files changed, 128 insertions(+), 35 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d3669c1..5125ace 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1376,6 +1376,7 @@ dependencies = [ "futures", "futures-channel", "gloo-timers", + "gloo-utils", "instant", "js-sys", "keyring", @@ -1402,6 +1403,7 @@ dependencies = [ "urlencoding", "wasm-bindgen", "wasm-bindgen-futures", + "wasm-bindgen-test", "web-sys", ] diff --git a/Cargo.toml b/Cargo.toml index 61fd05a..3d2d526 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,6 +46,7 @@ crypto-bigint = "0.5.5" tsify-next = { version = "0.5.4", features = ["js"] } instant = { version = "0.1.13", features = ["wasm-bindgen"] } gloo-timers = { version = "0.3.0", features = ["futures"] } +gloo-utils = { version = "0.2.0", features = ["serde"] } num-bigint = "0.4.6" num-traits = "0.2.19" chrono = "0.4.41" @@ -69,5 +70,8 @@ base64 = "0.22.1" # see. https://github.com/mozilla/cbindgen/issues/43 cbindgen = { git = "https://github.com/masnagam/cbindgen", branch = "fix-issue-43" } +[dev-dependencies] +wasm-bindgen-test = "0.3.33" + [patch.crates-io] crunchy = { git = "https://github.com/nmathewson/crunchy", branch = "cross-compilation-fix" } \ No newline at end of file diff --git a/src/wasm/utils.rs b/src/wasm/utils.rs index 10d5a8d..ed16cc5 100644 --- a/src/wasm/utils.rs +++ b/src/wasm/utils.rs @@ -2,6 +2,7 @@ use std::collections::HashMap; use num_bigint::BigUint; use num_traits::Num; +use gloo_utils::format::JsValueSerdeExt; use serde_json::Value as JsonValue; use wasm_bindgen::JsValue; @@ -9,41 +10,7 @@ use super::types::{EnumValue, Ty}; use crate::wasm::types::FixedSizeArray; fn json_value_to_js_value(json_value: &JsonValue) -> JsValue { - match json_value { - JsonValue::Null => JsValue::NULL, - JsonValue::Bool(b) => JsValue::from(*b), - JsonValue::Number(n) => { - if let Some(i) = n.as_i64() { - JsValue::from(i) - } else if let Some(u) = n.as_u64() { - JsValue::from(u) - } else if let Some(f) = n.as_f64() { - JsValue::from(f) - } else { - JsValue::from(n.to_string()) - } - } - JsonValue::String(s) => JsValue::from(s.as_str()), - JsonValue::Array(arr) => { - let js_array = js_sys::Array::new(); - for item in arr { - js_array.push(&json_value_to_js_value(item)); - } - js_array.into() - } - JsonValue::Object(obj) => { - let js_obj = js_sys::Object::new(); - for (key, value) in obj { - js_sys::Reflect::set( - &js_obj, - &JsValue::from(key.as_str()), - &json_value_to_js_value(value), - ) - .unwrap(); - } - js_obj.into() - } - } + JsValue::from_serde(json_value).unwrap() } pub fn parse_ty_as_json_str(ty: &dojo_types::schema::Ty, key: bool) -> Ty { @@ -170,3 +137,123 @@ pub fn pad_to_hex(input: &str) -> Result { Ok(padded_hex) } + +#[cfg(test)] +mod tests { + use super::*; + use dojo_types::primitive::Primitive; + use serde_json::json; + use wasm_bindgen_test::*; + + wasm_bindgen_test_configure!(run_in_browser); + + #[wasm_bindgen_test] + fn test_json_value_to_js_value_primitives() { + // Test null + let json_val = json!(null); + let js_val = json_value_to_js_value(&json_val); + assert!(js_val.is_null()); + + // Test boolean + let json_val = json!(true); + let js_val = json_value_to_js_value(&json_val); + assert!(js_val.is_truthy()); + + let json_val = json!(false); + let js_val = json_value_to_js_value(&json_val); + assert!(!js_val.is_truthy()); + + // Test number + let json_val = json!(42); + let js_val = json_value_to_js_value(&json_val); + assert!(js_val.is_f64()); + assert_eq!(js_val.as_f64().unwrap() as i32, 42); + + // Test string + let json_val = json!("hello world"); + let js_val = json_value_to_js_value(&json_val); + assert!(js_val.is_string()); + assert_eq!(js_val.as_string().unwrap(), "hello world"); + + // Test hex string (like what primitives produce) + let json_val = json!("0x000000000000000000000000000000000000000000000000000000000000002a"); + let js_val = json_value_to_js_value(&json_val); + assert!(js_val.is_string()); + assert_eq!(js_val.as_string().unwrap(), "0x000000000000000000000000000000000000000000000000000000000000002a"); + } + + #[wasm_bindgen_test] + fn test_primitive_to_js_value_conversions() { + // Test small integers + let primitive = Primitive::I8(Some(42)); + let json_val = primitive.to_json_value().unwrap(); + let js_val = json_value_to_js_value(&json_val); + assert!(js_val.is_f64()); + assert_eq!(js_val.as_f64().unwrap() as i8, 42); + + let primitive = Primitive::U32(Some(1234567)); + let json_val = primitive.to_json_value().unwrap(); + let js_val = json_value_to_js_value(&json_val); + assert!(js_val.is_f64()); + assert_eq!(js_val.as_f64().unwrap() as u32, 1234567); + + // Test boolean + let primitive = Primitive::Bool(Some(true)); + let json_val = primitive.to_json_value().unwrap(); + let js_val = json_value_to_js_value(&json_val); + assert!(js_val.is_truthy()); + + // Test large integers (should be strings) + let primitive = Primitive::U64(Some(18446744073709551615u64)); + let json_val = primitive.to_json_value().unwrap(); + let js_val = json_value_to_js_value(&json_val); + assert!(js_val.is_string()); + assert_eq!(js_val.as_string().unwrap(), "18446744073709551615"); + + // Test U256 (should be hex string) + let primitive = Primitive::U256(Some(starknet_types_core::felt::Felt::from(42u32))); + let json_val = primitive.to_json_value().unwrap(); + let js_val = json_value_to_js_value(&json_val); + assert!(js_val.is_string()); + assert!(js_val.as_string().unwrap().starts_with("0x")); + + // Test ContractAddress (should be hex string) + let primitive = Primitive::ContractAddress(Some(starknet_types_core::felt::Felt::from(42u32))); + let json_val = primitive.to_json_value().unwrap(); + let js_val = json_value_to_js_value(&json_val); + assert!(js_val.is_string()); + assert!(js_val.as_string().unwrap().starts_with("0x")); + } + + #[wasm_bindgen_test] + fn test_json_array_conversion() { + let json_val = json!([1, 2, 3, "test", true]); + let js_val = json_value_to_js_value(&json_val); + + // Check if it's an array + assert!(js_val.is_object()); + + // Convert to js_sys::Array to test further + let js_array = js_sys::Array::from(&js_val); + assert_eq!(js_array.length(), 5); + } + + #[wasm_bindgen_test] + fn test_json_object_conversion() { + let json_val = json!({ + "name": "test", + "value": 42, + "active": true + }); + let js_val = json_value_to_js_value(&json_val); + + // Check if it's an object + assert!(js_val.is_object()); + + // Test that we can access properties + let js_obj = js_sys::Object::from(js_val); + let name_val = js_sys::Reflect::get(&js_obj, &JsValue::from("name")).unwrap(); + assert!(name_val.is_string()); + assert_eq!(name_val.as_string().unwrap(), "test"); + } +} From 7f679bb91e9fe2e84a2d7e48b9332b3d621adde0 Mon Sep 17 00:00:00 2001 From: Nasr Date: Tue, 26 Aug 2025 13:53:54 +0100 Subject: [PATCH 3/5] fmt --- src/wasm/utils.rs | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/wasm/utils.rs b/src/wasm/utils.rs index ed16cc5..357d8b7 100644 --- a/src/wasm/utils.rs +++ b/src/wasm/utils.rs @@ -1,8 +1,8 @@ use std::collections::HashMap; +use gloo_utils::format::JsValueSerdeExt; use num_bigint::BigUint; use num_traits::Num; -use gloo_utils::format::JsValueSerdeExt; use serde_json::Value as JsonValue; use wasm_bindgen::JsValue; @@ -140,11 +140,12 @@ pub fn pad_to_hex(input: &str) -> Result { #[cfg(test)] mod tests { - use super::*; use dojo_types::primitive::Primitive; use serde_json::json; use wasm_bindgen_test::*; + use super::*; + wasm_bindgen_test_configure!(run_in_browser); #[wasm_bindgen_test] @@ -179,7 +180,10 @@ mod tests { let json_val = json!("0x000000000000000000000000000000000000000000000000000000000000002a"); let js_val = json_value_to_js_value(&json_val); assert!(js_val.is_string()); - assert_eq!(js_val.as_string().unwrap(), "0x000000000000000000000000000000000000000000000000000000000000002a"); + assert_eq!( + js_val.as_string().unwrap(), + "0x000000000000000000000000000000000000000000000000000000000000002a" + ); } #[wasm_bindgen_test] @@ -218,7 +222,8 @@ mod tests { assert!(js_val.as_string().unwrap().starts_with("0x")); // Test ContractAddress (should be hex string) - let primitive = Primitive::ContractAddress(Some(starknet_types_core::felt::Felt::from(42u32))); + let primitive = + Primitive::ContractAddress(Some(starknet_types_core::felt::Felt::from(42u32))); let json_val = primitive.to_json_value().unwrap(); let js_val = json_value_to_js_value(&json_val); assert!(js_val.is_string()); @@ -229,10 +234,10 @@ mod tests { fn test_json_array_conversion() { let json_val = json!([1, 2, 3, "test", true]); let js_val = json_value_to_js_value(&json_val); - + // Check if it's an array assert!(js_val.is_object()); - + // Convert to js_sys::Array to test further let js_array = js_sys::Array::from(&js_val); assert_eq!(js_array.length(), 5); @@ -246,10 +251,10 @@ mod tests { "active": true }); let js_val = json_value_to_js_value(&json_val); - + // Check if it's an object assert!(js_val.is_object()); - + // Test that we can access properties let js_obj = js_sys::Object::from(js_val); let name_val = js_sys::Reflect::get(&js_obj, &JsValue::from("name")).unwrap(); From ea685b2e91a124f82f19ecff902fa3f4501ad788 Mon Sep 17 00:00:00 2001 From: Nasr Date: Tue, 26 Aug 2025 14:06:17 +0100 Subject: [PATCH 4/5] f --- src/wasm/utils.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/wasm/utils.rs b/src/wasm/utils.rs index 357d8b7..beb18ac 100644 --- a/src/wasm/utils.rs +++ b/src/wasm/utils.rs @@ -167,7 +167,7 @@ mod tests { // Test number let json_val = json!(42); let js_val = json_value_to_js_value(&json_val); - assert!(js_val.is_f64()); + assert!(js_val.as_f64().is_some()); assert_eq!(js_val.as_f64().unwrap() as i32, 42); // Test string @@ -192,13 +192,13 @@ mod tests { let primitive = Primitive::I8(Some(42)); let json_val = primitive.to_json_value().unwrap(); let js_val = json_value_to_js_value(&json_val); - assert!(js_val.is_f64()); + assert!(js_val.as_f64().is_some()); assert_eq!(js_val.as_f64().unwrap() as i8, 42); let primitive = Primitive::U32(Some(1234567)); let json_val = primitive.to_json_value().unwrap(); let js_val = json_value_to_js_value(&json_val); - assert!(js_val.is_f64()); + assert!(js_val.as_f64().is_some()); assert_eq!(js_val.as_f64().unwrap() as u32, 1234567); // Test boolean @@ -215,7 +215,8 @@ mod tests { assert_eq!(js_val.as_string().unwrap(), "18446744073709551615"); // Test U256 (should be hex string) - let primitive = Primitive::U256(Some(starknet_types_core::felt::Felt::from(42u32))); + use crypto_bigint::U256; + let primitive = Primitive::U256(Some(U256::from(42u32))); let json_val = primitive.to_json_value().unwrap(); let js_val = json_value_to_js_value(&json_val); assert!(js_val.is_string()); From 50f3db2addd194e509a7642f72af0be89f941f03 Mon Sep 17 00:00:00 2001 From: Nasr Date: Tue, 26 Aug 2025 14:11:53 +0100 Subject: [PATCH 5/5] fix test --- src/wasm/utils.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/wasm/utils.rs b/src/wasm/utils.rs index beb18ac..0c752a6 100644 --- a/src/wasm/utils.rs +++ b/src/wasm/utils.rs @@ -146,8 +146,6 @@ mod tests { use super::*; - wasm_bindgen_test_configure!(run_in_browser); - #[wasm_bindgen_test] fn test_json_value_to_js_value_primitives() { // Test null