329 lines
9.7 KiB
Rust
329 lines
9.7 KiB
Rust
use crate::id::MizeId;
|
|
use crate::item::{Item, ItemData};
|
|
use crate::platform::js::js_sys::Function;
|
|
use core::convert::From;
|
|
use core::option::Option;
|
|
use std::panic;
|
|
use std::ptr::NonNull;
|
|
use web_sys::js_sys::{self, eval, Promise};
|
|
use web_sys::Worker;
|
|
use web_sys::{WorkerOptions, WorkerType};
|
|
|
|
use crate::core::item::IntoItemData;
|
|
use crate::error::MizeResult;
|
|
use crate::Mize;
|
|
use crate::MizeError;
|
|
use crate::mize_err;
|
|
|
|
// console_log macro
|
|
// that can be copied into other files for debugging purposes
|
|
#[cfg(feature = "target-js")]
|
|
use wasm_bindgen::prelude::*;
|
|
|
|
#[cfg(feature = "target-js")]
|
|
#[wasm_bindgen]
|
|
extern "C" {
|
|
#[wasm_bindgen(js_namespace = console)]
|
|
fn log(s: &str);
|
|
}
|
|
|
|
#[cfg(feature = "target-js")]
|
|
macro_rules! console_log {
|
|
// Note that this is using the `log` function imported above during
|
|
// `bare_bones`
|
|
($($t:tt)*) => (unsafe { log(&format_args!($($t)*).to_string())})
|
|
}
|
|
|
|
#[cfg(not(feature = "target-js"))]
|
|
macro_rules! console_log {
|
|
// Note that this is using the `log` function imported above during
|
|
// `bare_bones`
|
|
($($t:tt)*) => {};
|
|
}
|
|
//end of console_log macro
|
|
|
|
#[global_allocator]
|
|
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
|
|
|
|
pub fn wasm_instance_init(mize: &mut Mize) -> MizeResult<()> {
|
|
console_log!("Hello world from wasm_instance_init!!!!!!!!!!");
|
|
|
|
#[cfg(feature = "target-obsidian")] {
|
|
////// populate values from $MIZE_CONFIG_FILES
|
|
if let Ok(config_file_paths) = obsidian_get_env_var("MIZE_CONFIG_FILES") {
|
|
for config_file_path in config_file_paths.split(":") {
|
|
println!("reading config file: {config_file_path}");
|
|
let content = std::fs::read_to_string(config_file_path)?;
|
|
let mut data = ItemData::from_toml(content.as_str())?;
|
|
crate::core::item::set_config_from_data(mize, data)?;
|
|
}
|
|
}
|
|
|
|
////// load config from MIZE_CONFIG env var
|
|
match std::env::var("MIZE_CONFIG") {
|
|
Ok(config_string) => {
|
|
let data = data_from_string(config_string)?;
|
|
crate::core::item::set_config_from_data(mize, data)?;
|
|
}
|
|
Err(var_err) => match var_err {
|
|
VarError::NotPresent => {
|
|
debug!("env var MIZE_CONFIG NOT present")
|
|
}
|
|
VarError::NotUnicode(_) => {
|
|
warn!("env var MIZE_CONFIG is not Unicode, so not reading it")
|
|
}
|
|
},
|
|
};
|
|
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[cfg(feature = "target-obsidian")]
|
|
pub fn obsidian_get_env_var(name: &str) -> Option<String> {
|
|
use js_sys::{Reflect, Object};
|
|
// 1. Get the global `process` object
|
|
let global = js_sys::global();
|
|
let process = Reflect::get(&global, &JsValue::from_str("process")).ok()?;
|
|
|
|
if process.is_undefined() {
|
|
return None;
|
|
}
|
|
|
|
// 2. Get the `env` object from `process`
|
|
let env = Reflect::get(&process, &JsValue::from_str("env")).ok()?;
|
|
if env.is_undefined() {
|
|
return None;
|
|
}
|
|
|
|
// 3. Get the `MIZE_STORE` value from `env`
|
|
let mize_store = Reflect::get(&env, &JsValue::from_str("MIZE_STORE")).ok()?;
|
|
|
|
// 4. Convert the JsValue to a Rust String if it exists
|
|
mize_store.as_string()
|
|
}
|
|
|
|
|
|
pub fn load_module(mize: &mut Mize, name: &str, path: Option<String>) -> MizeResult<()> {
|
|
console_log!("loading module NOT IMPLEMENTED: {}", name);
|
|
|
|
//wasm_bindgen_futures::spawn_local(load_module_async(mize.clone(), name.to_owned(), path));
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/*
|
|
async fn load_module_async(mut mize: Mize, name: String, path: Option<String>) -> () {
|
|
let name = name.as_str();
|
|
let module_url = fetch_module(&mut mize, name).unwrap();
|
|
let memory = wasm_bindgen::memory();
|
|
|
|
let mut empty_module: Box<dyn Module + Send + Sync> = Box::new(EmptyModule {});
|
|
let mut mize = mize.clone();
|
|
|
|
let empty_module_ptr = Box::into_raw(Box::new(empty_module));
|
|
let empty_module_usize = empty_module_ptr as usize;
|
|
let mize_usize = Box::into_raw(Box::new(mize)) as usize;
|
|
|
|
console_log!("testttttttttttttt in load_module_async...");
|
|
|
|
let function_str = format!(
|
|
r#"
|
|
const promise = new Promise((resolve, reject) => {{
|
|
import("{module_url}/mize_module_{name}.js").then( module => {{
|
|
const wasm_bindgen = module.get_wasm_bindgen();
|
|
|
|
const {{ wasm_get_mize_module_mme }} = wasm_bindgen;
|
|
|
|
wasm_bindgen("{module_url}/mize_module_{name}_bg.wasm", memory).then( () => {{
|
|
console.log("empty_module_usize:", empty_module_usize)
|
|
console.log("mize_usize:", mize_usize)
|
|
//resolve()
|
|
resolve(wasm_get_mize_module_mme(empty_module_usize, mize_usize))
|
|
}})
|
|
}})
|
|
}})
|
|
return promise;
|
|
"#
|
|
);
|
|
|
|
let function = Function::new_with_args("memory, empty_module_usize, mize_usize", &function_str);
|
|
|
|
let ret_value: JsValue = match function.call3(
|
|
&JsValue::null(),
|
|
&memory,
|
|
&empty_module_usize.into(),
|
|
&mize_usize.into(),
|
|
) {
|
|
Ok(val) => val,
|
|
Err(err) => {
|
|
console_log!("failed to load the wasm mize module....");
|
|
console_log!("{:?}", err);
|
|
return;
|
|
}
|
|
};
|
|
|
|
console_log!("got ret_value: {:?}", ret_value);
|
|
let ret_promise = Promise::from(ret_value);
|
|
let ret_result = match wasm_bindgen_futures::JsFuture::from(ret_promise).await {
|
|
Ok(val) => val,
|
|
Err(err) => {
|
|
console_log!("err awaiting ret_promise");
|
|
console_log!("{:?}", err);
|
|
return;
|
|
}
|
|
};
|
|
|
|
let mut filled_module = unsafe { Box::from_raw(empty_module_ptr) };
|
|
|
|
console_log!("before....");
|
|
//let a = mize.get("0/config");
|
|
console_log!("after....");
|
|
|
|
//filled_module.init(&instance);
|
|
|
|
/*
|
|
console_log!("got ret_result: {:?}", ret_result);
|
|
let ret_f64 = ret_result.as_f64().unwrap();
|
|
console_log!("got ret_f64: {:?}", ret_f64);
|
|
|
|
let ret_usize = ret_f64.floor() as usize;
|
|
|
|
let mut module: Box<dyn Module + Send + Sync> = Box::new(EmptyModule {});
|
|
|
|
unsafe {
|
|
let get_mize_module_fn_ptr = ret_usize as *const fn(&mut Box<dyn Module + Send + Sync>, Instance) -> ();
|
|
let get_mize_module_fn: fn(&mut Box<dyn Module + Send + Sync>, Instance) -> () = unsafe { std::mem::transmute(get_mize_module_fn_ptr) };
|
|
get_mize_module_fn(&mut module, instance.clone());
|
|
}
|
|
*/
|
|
}
|
|
*/
|
|
|
|
pub fn fetch_module(mize: &mut Mize, name: &str) -> MizeResult<String> {
|
|
let module_name_with_slashes = name.replace(".", "/");
|
|
if let Ok(module_path) = mize
|
|
.get(format!(
|
|
"self/config/module_dir/{}",
|
|
module_name_with_slashes
|
|
))?
|
|
.value_string()
|
|
{
|
|
return Ok(module_path);
|
|
} else {
|
|
let module_url = mize.get("self/config/module_url")?.value_string()?;
|
|
return Ok(format!("{}/{}", module_url, module_name_with_slashes));
|
|
}
|
|
}
|
|
|
|
async fn download_module(mize: &mut Mize, name: &str) -> MizeResult<js_sys::ArrayBuffer> {
|
|
use wasm_bindgen_futures::JsFuture;
|
|
use web_sys::{Request, RequestInit, RequestMode, Response};
|
|
|
|
let opts = RequestInit::new();
|
|
opts.set_method("GET");
|
|
opts.set_mode(RequestMode::Cors);
|
|
|
|
let url = format!("{}/mize_module_{}_bg.wasm", fetch_module(mize, name)?, name);
|
|
|
|
let request = Request::new_with_str_and_init(&url, &opts).unwrap();
|
|
|
|
let window = web_sys::window().unwrap();
|
|
let resp_value = JsFuture::from(window.fetch_with_request(&request))
|
|
.await
|
|
.unwrap();
|
|
|
|
let resp: Response = resp_value.dyn_into().unwrap();
|
|
|
|
let wasm_bytes: js_sys::ArrayBuffer = JsFuture::from(resp.array_buffer().unwrap())
|
|
.await
|
|
.unwrap()
|
|
.dyn_into()
|
|
.unwrap();
|
|
|
|
Ok(wasm_bytes)
|
|
}
|
|
|
|
#[wasm_bindgen]
|
|
#[derive(Clone)]
|
|
pub struct JsMize {
|
|
inner: NonNull<Mize>,
|
|
}
|
|
|
|
#[wasm_bindgen]
|
|
pub struct JsItem {
|
|
mize: NonNull<Mize>,
|
|
id: MizeId,
|
|
}
|
|
|
|
#[wasm_bindgen]
|
|
pub async fn new_js_instance(config_json_str: String) -> JsMize {
|
|
panic::set_hook(Box::new(console_error_panic_hook::hook));
|
|
|
|
let config = ItemData::from_json(config_json_str).expect("parsing of json config failed");
|
|
|
|
let mut mize = Mize::with_config(config).expect("Mize::new() failed");
|
|
|
|
let mut js_instance = JsMize {
|
|
inner: NonNull::from(Box::leak(Box::new(mize))),
|
|
};
|
|
|
|
return js_instance;
|
|
}
|
|
|
|
#[wasm_bindgen]
|
|
impl JsMize {
|
|
#[wasm_bindgen]
|
|
pub unsafe fn init(&mut self) -> MizeResult<()> {
|
|
self.inner.as_mut().init()
|
|
}
|
|
|
|
#[wasm_bindgen]
|
|
pub unsafe fn set(&mut self, id: String, value: String) -> () {
|
|
let data = value.into_item_data();
|
|
console_log!("data in set: {}", data);
|
|
self.inner.as_mut().set(id, data);
|
|
}
|
|
|
|
#[wasm_bindgen]
|
|
pub unsafe fn get_handle(&mut self, id: String) -> MizeResult<JsItem> {
|
|
let item = self.inner.as_mut().get(id)?;
|
|
Ok(JsItem {
|
|
mize: self.inner,
|
|
id: item.id(),
|
|
})
|
|
}
|
|
}
|
|
|
|
impl JsMize {
|
|
pub fn inner(&mut self) -> &mut Mize {
|
|
unsafe { self.inner.as_mut() }
|
|
}
|
|
}
|
|
|
|
#[wasm_bindgen]
|
|
impl JsItem {
|
|
#[wasm_bindgen]
|
|
pub unsafe fn value_string(&mut self) -> MizeResult<String> {
|
|
let item = self.mize.as_mut().get(self.id.clone())?;
|
|
let string = item.value_string()?;
|
|
Ok(string)
|
|
}
|
|
|
|
#[wasm_bindgen]
|
|
pub unsafe fn as_data_full(&mut self) -> MizeResult<JsValue> {
|
|
let item = self.mize.as_mut().get(self.id.clone())?;
|
|
let data_raw = item.as_data_full()?;
|
|
let jsvalue = serde_wasm_bindgen::to_value(data_raw.cbor())?;
|
|
Ok(jsvalue)
|
|
}
|
|
}
|
|
|
|
impl From<MizeError> for JsValue {
|
|
fn from(value: MizeError) -> Self {
|
|
let string = format!("{:?}", value);
|
|
string.into()
|
|
}
|
|
}
|