Skip to content

Commit

Permalink
Merge pull request #1 from uditdc/main
Browse files Browse the repository at this point in the history
Init FetchIo api module, based on Blockless host calls
  • Loading branch information
dmikey authored Dec 7, 2023
2 parents 0df708e + b9d059a commit 1574010
Show file tree
Hide file tree
Showing 8 changed files with 492 additions and 34 deletions.
394 changes: 361 additions & 33 deletions Cargo.lock

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions crates/apis/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,17 @@ categories = ["wasm"]

[features]
console = []
fetch_io = ["dep:blockless-sdk", "dep:json"]
random = ["dep:fastrand"]
stream_io = []
text_encoding = []

[dependencies]
anyhow = { workspace = true }
fastrand = { version = "2.0.1", optional = true }
hyper_wasi = { version = "0.15.0", optional = true, features = ["full"] }
tokio_wasi = { version = "1.25", optional = true, features = ["full"] }
reqwest_wasi = { version = "0.11", optional = true, features = ["blocking", "json"] }
javy = { workspace = true }
blockless-sdk = { version = "0.1.3", optional = true }
json = { version = "0.12", optional = true }
2 changes: 2 additions & 0 deletions crates/apis/src/api_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,6 @@
pub struct APIConfig {
#[cfg(feature = "console")]
pub(crate) console: crate::console::ConsoleConfig,
#[cfg(feature = "fetch_io")]
pub(crate) fetch_io: crate::fetch_io::FetchIOConfig,
}
25 changes: 25 additions & 0 deletions crates/apis/src/fetch_io/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use crate::APIConfig;

// Use crate visibility to avoid exposing the property outside the crate
#[derive(Debug)]
pub(crate) struct FetchIOConfig {
pub(super) prefix: String,
}

// Always have a default value for every config.
impl Default for FetchIOConfig {
fn default() -> Self {
Self {
prefix: "Default prefix: ".to_string(),
}
}
}

// Define one or more methods on `APIConfig`, not `FetchIOConfig`, to set properties.
impl APIConfig {
/// Sets the prefix for `Javy.Env.print`.
pub fn prefix(&mut self, prefix: String) -> &mut Self {
self.fetch_io.prefix = prefix;
self
}
}
12 changes: 12 additions & 0 deletions crates/apis/src/fetch_io/fetch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Wrap everything in an anonymous function to avoid leaking local variables into the global scope.
(function () {
// Get a reference to the function before we delete it from `globalThis`.
const __javy_fetchio_get = globalThis.__javy_fetchio_get;
globalThis.Javy.FetchIO = {
get(url) {
__javy_fetchio_get(url);
},
};
// Delete the function from `globalThis` so it doesn't leak.
Reflect.deleteProperty(globalThis, "__javy_fetchio_get");
})();
81 changes: 81 additions & 0 deletions crates/apis/src/fetch_io/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
//use std::collections::HashMap;

use anyhow::{bail, Result};
use javy::{quickjs::JSValue, Runtime};
use blockless_sdk::*;

use crate::{APIConfig, JSApiSet};
pub(super) use config::FetchIOConfig;

mod config;

pub(super) struct FetchIO;

impl JSApiSet for FetchIO {
fn register(&self, runtime: &Runtime, config: &APIConfig) -> Result<()> {
let context = runtime.context();

let global = context.global_object()?;

let mut javy_object = global.get_property("Javy")?;

// If you're defining something on the `Javy` object, ensure it exists.
if javy_object.is_undefined() {
javy_object = context.object_value()?;
global.set_property("Javy", javy_object)?;
}

// `wrap_callback`` has a static lifetime so you can't use references to the config in its body.
global.set_property(
"__javy_fetchio_get",
context.wrap_callback(move |_ctx, _this, args| {
let [url] = args else {
bail!("Incorrect number of arguments");
};
// Convert JSValueRefs to Rust types.
let url: String = url.try_into()?;

let opts = HttpOptions::new("GET", 30, 10);
let http = BlocklessHttp::open(&url, &opts);
let http = http.unwrap();
let body = http.get_all_body().unwrap();
let body = String::from_utf8(body).unwrap();
let data = match json::parse(&body).unwrap() {
json::JsonValue::Object(o) => o,
_ => panic!("must be object"),
};

println!("Http Data: {:?}", data);

Ok(JSValue::Undefined)
})?,
)?;

context.eval_global("fetch.js", include_str!("fetch.js"))?;

Ok(())
}
}

// Automated tests are highly recommended
#[cfg(test)]
mod tests {
use std::env;

use crate::{APIConfig, JSApiSet};
use anyhow::Result;
use javy::Runtime;

use super::FetchIO;

#[test]
fn test_print_env_var() -> Result<()> {
let runtime = Runtime::default();
let context = runtime.context();
FetchIO.register(&runtime, &APIConfig::default())?;
env::set_var("HELLO", "there");
let _ = context.eval_global("main", "Javy.Env.print('HELLO');")?;
env::remove_var("HELLO");
Ok(())
}
}
4 changes: 4 additions & 0 deletions crates/apis/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ mod runtime_ext;
mod stream_io;
#[cfg(feature = "text_encoding")]
mod text_encoding;
#[cfg(feature = "fetch_io")]
mod fetch_io;

pub(crate) trait JSApiSet {
fn register(&self, runtime: &Runtime, config: &APIConfig) -> Result<()>;
Expand All @@ -85,5 +87,7 @@ pub fn add_to_runtime(runtime: &Runtime, config: APIConfig) -> Result<()> {
stream_io::StreamIO.register(runtime, &config)?;
#[cfg(feature = "text_encoding")]
text_encoding::TextEncoding.register(runtime, &config)?;
#[cfg(feature = "fetch_io")]
fetch_io::FetchIO.register(runtime, &config)?;
Ok(())
}
2 changes: 1 addition & 1 deletion crates/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ crate-type = ["cdylib"]
[dependencies]
anyhow = { workspace = true }
javy = { workspace = true, features = ["export_alloc_fns"] }
javy-apis = { path = "../apis", features = ["console", "text_encoding", "random", "stream_io"] }
javy-apis = { path = "../apis", features = ["console", "text_encoding", "random", "stream_io", "fetch_io"] }
once_cell = { workspace = true }

[features]
Expand Down

0 comments on commit 1574010

Please sign in to comment.