Skip to content

Commit

Permalink
fix: Support webkit that doesn't have BYOBReader support
Browse files Browse the repository at this point in the history
  • Loading branch information
matheus23 committed Mar 1, 2024
1 parent f87bad2 commit 9a1d5b7
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 17 deletions.
2 changes: 1 addition & 1 deletion car-mirror-wasm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ js-sys = { version = "0.3" }
libipld = { workspace = true }
serde-wasm-bindgen = "0.6.5"
serde_json = { workspace = true }
tokio-util = { workspace = true, features = ["compat"] }
tokio-util = { workspace = true, features = ["compat", "io"] }
tracing = "0.1"
wasm-bindgen = { workspace = true }
wasm-bindgen-futures = { workspace = true }
Expand Down
16 changes: 14 additions & 2 deletions car-mirror-wasm/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"scripts": {
"build": "wireit",
"test": "wireit",
"http-server": "wireit",
"release": "export PROFILE=release && export TARGET_DIR=release && npm run build"
},
"wireit": {
Expand All @@ -48,7 +49,13 @@
}
},
"opt": {
"command": "wasm-opt -O1 ../target/wasm32-unknown-unknown/$TARGET_DIR/car_mirror_wasm.wasm -o ../target/wasm32-unknown-unknown/$TARGET_DIR/car_mirror_wasm.wasm",
"command": "wasm-opt -O1 ../target/wasm32-unknown-unknown/$TARGET_DIR/car_mirror_wasm.wasm -o ../target/wasm32-unknown-unknown/$TARGET_DIR/car_mirror_wasm-opt.wasm",
"files": [
"../target/wasm32-unknown-unknown/$TARGET_DIR/car_mirror_wasm.wasm"
],
"output": [
"../target/wasm32-unknown-unknown/$TARGET_DIR/car_mirror_wasm-opt.wasm"
],
"env": {
"TARGET_DIR": {
"external": true,
Expand All @@ -61,6 +68,9 @@
},
"bindgen:bundler": {
"command": "wasm-bindgen --weak-refs --target bundler --out-dir dist/bundler ../target/wasm32-unknown-unknown/$TARGET_DIR/car_mirror_wasm.wasm",
"files": [
"../target/wasm32-unknown-unknown/$TARGET_DIR/car_mirror_wasm-opt.wasm"
],
"env": {
"TARGET_DIR": {
"external": true,
Expand Down Expand Up @@ -133,7 +143,9 @@
"lineMatches": "Available on:.*"
}
},
"dependencies": []
"dependencies": [
"bindgen:web"
]
},
"car-mirror-server": {
"command": "cargo run -p car-mirror-axum --example serve_test_data",
Expand Down
55 changes: 44 additions & 11 deletions car-mirror-wasm/src/exports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ use crate::{
messages::{PullRequest, PushResponse},
utils::{handle_jserr, parse_cid},
};
use bytes::BytesMut;
use car_mirror::{cache::NoCache, common::Config};
use futures::StreamExt;
use futures::TryStreamExt;
use js_sys::{Error, Promise, Uint8Array};
use std::rc::Rc;
Expand Down Expand Up @@ -117,24 +119,55 @@ pub fn pull_request(root_cid: Vec<u8>, store: BlockStore) -> Result<Promise, Err
#[wasm_bindgen]
pub fn pull_handle_response_streaming(
root_cid: Vec<u8>,
stream: web_sys::ReadableStream,
readable_stream: web_sys::ReadableStream,
store: BlockStore,
) -> Result<Promise, Error> {
let store = ForeignBlockStore(store);
let root = parse_cid(root_cid)?;
let stream = ReadableStream::from_raw(stream);
let readable_stream = ReadableStream::from_raw(readable_stream);

Ok(future_to_promise(async move {
let pull_request = car_mirror::pull::handle_response_streaming(
root,
stream.into_async_read().compat(),
&Config::default(),
store,
NoCache,
)
.await
.map_err(handle_jserr)?;
let pull_request = match readable_stream.try_into_async_read() {
Ok(async_read) => car_mirror::pull::handle_response_streaming(
root,
async_read.compat(),
&Config::default(),
store,
NoCache,
)
.await
.map_err(handle_jserr)?,

// If BYOB readers are unsupported:
Err((_, readable_stream)) => {
let stream = readable_stream
.into_stream()
.map(|result| result.and_then(convert_jsvalue_to_bytes))
.map_err(|_| std::io::Error::new(std::io::ErrorKind::Other, "Error while trying to read item from stream or trying to convert the item into bytes on the rust side."));

let async_read = tokio_util::io::StreamReader::new(stream);

car_mirror::pull::handle_response_streaming(
root,
async_read,
&Config::default(),
store,
NoCache,
)
.await
.map_err(handle_jserr)?
}
};
Ok(PullRequest(Rc::new(pull_request)).into())
}))
}

fn convert_jsvalue_to_bytes(js_value: JsValue) -> Result<BytesMut, JsValue> {
let uint8array = Uint8Array::new(&js_value);

let mut result = BytesMut::with_capacity(uint8array.length() as usize);
result.resize(uint8array.length() as usize, 0);
uint8array.copy_to(&mut result);

Ok(result)
}
2 changes: 1 addition & 1 deletion car-mirror-wasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//! This crate exposes wasm bindings to car-mirror *client* functions.
#![cfg_attr(docsrs, feature(doc_cfg))]
#![warn(missing_debug_implementations, missing_docs, rust_2018_idioms)]
#![warn(missing_docs, rust_2018_idioms)]
#![deny(unreachable_pub)]
#![cfg(target_arch = "wasm32")]

Expand Down
3 changes: 1 addition & 2 deletions car-mirror-wasm/test/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,8 @@ export async function runCarMirrorPull(serverUrl, cidString, store) {
method: "POST",
body: request.encode()
});
console.debug("Got response status", response.status, response.body.locked);
console.debug("Got response status", response.status);
if (200 <= response.status && response.status < 300) {
response.body.getReader().releaseLock();
request = await pull_handle_response_streaming(cid.bytes, response.body, store);
} else {
throw new Error(`Unexpected status code in car-mirror pull response: ${response.status}, body: ${await response.text()}`);
Expand Down

0 comments on commit 9a1d5b7

Please sign in to comment.