Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add some WASM APIs #39

Merged
merged 9 commits into from
Jul 27, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions crates/fs/common/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,17 @@ pub enum UnixFsMode {
/// See <https://docs.ipfs.io/concepts/file-systems/#unix-file-system-unixfs>
#[derive(Debug, Clone, PartialEq, Eq, DagCbor, Serialize, Deserialize)]
pub struct UnixFsMetadata {
pub(crate) created: i64,
pub(crate) modified: i64,
pub(crate) mode: UnixFsMode,
pub(crate) kind: UnixFsNodeKind,
pub created: i64,
pub modified: i64,
pub mode: UnixFsMode,
pub kind: UnixFsNodeKind,
}

/// The metadata of a node on the WNFS file system.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Metadata {
pub(crate) unix_fs: UnixFsMetadata,
pub(crate) version: Version,
pub unix_fs: UnixFsMetadata,
pub version: Version,
}

//--------------------------------------------------------------------------------------------------
Expand Down
44 changes: 44 additions & 0 deletions crates/wasm/fs/metadata.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
use crate::fs::JsResult;
use crate::value;
use js_sys::{Object, Reflect};
use wasm_bindgen::JsValue;
use wnfs::{Metadata, UnixFsMetadata, UnixFsNodeKind};

pub(crate) struct JsMetadata<'a>(pub(crate) &'a Metadata);

impl TryInto<JsValue> for JsMetadata<'_> {
type Error = js_sys::Error;

fn try_into(self) -> JsResult<JsValue> {
let metadata = Object::new();
let unix_meta = unix_fs_to_js_value(&self.0.unix_fs)?;

Reflect::set(&metadata, &value!("unixMeta"), &unix_meta)?;
Reflect::set(&metadata, &value!("version"), &value!("3.0.0"))?;
matheus23 marked this conversation as resolved.
Show resolved Hide resolved

Ok(value!(metadata))
}
}

fn unix_fs_to_js_value(unix_fs: &UnixFsMetadata) -> JsResult<JsValue> {
let obj = Object::new();
let kind = unix_fs_kind_to_js_value(&unix_fs.kind);

Reflect::set(&obj, &value!("created"), &value!(unix_fs.created))?;
Reflect::set(&obj, &value!("modified"), &value!(unix_fs.modified))?;
Reflect::set(&obj, &value!("mode"), &value!(unix_fs.mode.clone() as u32))?;
Reflect::set(&obj, &value!("kind"), &kind)?;
matheus23 marked this conversation as resolved.
Show resolved Hide resolved

Ok(value!(obj))
}

fn unix_fs_kind_to_js_value(kind: &UnixFsNodeKind) -> JsValue {
match kind {
UnixFsNodeKind::Raw => value!("raw"),
UnixFsNodeKind::Dir => value!("dir"),
UnixFsNodeKind::File => value!("file"),
UnixFsNodeKind::Metadata => value!("metadata"),
UnixFsNodeKind::SymLink => value!("symlink"),
UnixFsNodeKind::HAMTShard => value!("hamtShard"),
}
}
matheus23 marked this conversation as resolved.
Show resolved Hide resolved
1 change: 1 addition & 0 deletions crates/wasm/fs/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
mod blockstore;
mod metadata;
mod public;

pub use blockstore::*;
Expand Down
59 changes: 54 additions & 5 deletions crates/wasm/fs/public/directory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use wnfs::{
OpResult as WnfsOpResult, PublicDirectory as WnfsPublicDirectory,
PublicNode as WnfsPublicNode,
},
Id,
BlockStore as WnfsBlockStore, Id,
};

use crate::fs::{BlockStore, ForeignBlockStore, JsResult, PublicNode};
Expand Down Expand Up @@ -86,6 +86,21 @@ impl PublicDirectory {
}))
}

/// Loads a directory given its CID from the block store.
pub fn load(cid: Uint8Array, store: BlockStore) -> JsResult<Promise> {
let store = ForeignBlockStore(store);
let cid = Cid::read_bytes(cid.to_vec().as_slice())
.map_err(|e| Error::new(&format!("Cannot parse cid: {e}")))?;
Ok(future_to_promise(async move {
let directory: WnfsPublicDirectory = store
.get_deserializable(&cid)
.await
.map_err(|e| Error::new(&format!("Couldn't deserialize directory: {e}")))?;

Ok(value!(PublicDirectory(Rc::new(directory))))
}))
}

/// Reads specified file content from the directory.
pub fn read(&self, path_segments: &Array, store: BlockStore) -> JsResult<Promise> {
let directory = Rc::clone(&self.0);
Expand All @@ -98,7 +113,9 @@ impl PublicDirectory {
.await
.map_err(|e| Error::new(&format!("Cannot read from directory: {e}")))?;

Ok(utils::create_op_result(root_dir, result.to_string())?)
let cid_u8array = Uint8Array::from(&result.to_bytes()[..]);

Ok(utils::create_op_result(root_dir, cid_u8array)?)
}))
}

Expand All @@ -116,7 +133,7 @@ impl PublicDirectory {

let result = result
.iter()
.map(|(name, _)| value!(name))
.flat_map(|(name, metadata)| utils::create_ls_entry(name, metadata))
.collect::<Array>();

Ok(utils::create_op_result(root_dir, result)?)
Expand Down Expand Up @@ -169,6 +186,7 @@ impl PublicDirectory {
}

/// Moves a specified path to a new location.
#[wasm_bindgen(js_name = "basicMv")]
pub fn basic_mv(
&self,
path_segments_from: &Array,
Expand Down Expand Up @@ -216,6 +234,24 @@ impl PublicDirectory {
}))
}

#[wasm_bindgen(js_name = "baseHistoryOn")]
pub fn base_history_on(&self, base: &PublicDirectory, store: BlockStore) -> JsResult<Promise> {
let directory = self.0.clone();
let base = base.0.clone();
let mut store = ForeignBlockStore(store);

Ok(future_to_promise(async move {
let WnfsOpResult { root_dir, .. } = directory
.base_history_on(base, &mut store)
.await
.map_err(|e| {
Error::new(&format!("Cannot do history rebase (base_history_on): {e}"))
})?;

Ok(utils::create_op_result(root_dir, JsValue::NULL)?)
}))
}

/// Converts directory to a node.
#[wasm_bindgen(js_name = "asNode")]
pub fn as_node(&self) -> PublicNode {
Expand All @@ -236,10 +272,10 @@ impl PublicDirectory {
mod utils {
use std::rc::Rc;

use crate::{fs::JsResult, value};
use crate::{fs::metadata::JsMetadata, fs::JsResult, value};
use js_sys::{Array, Error, Object, Reflect};
use wasm_bindgen::JsValue;
use wnfs::public::PublicDirectory as WnfsPublicDirectory;
use wnfs::{public::PublicDirectory as WnfsPublicDirectory, Metadata};

use super::PublicDirectory;

Expand Down Expand Up @@ -273,4 +309,17 @@ mod utils {

Ok(value!(op_result))
}

pub(crate) fn create_ls_entry(name: &String, metadata: &Metadata) -> JsResult<JsValue> {
let entry = Object::new();

Reflect::set(&entry, &value!("name"), &value!(name))?;
Reflect::set(
&entry,
&value!("metadata"),
&JsMetadata(metadata).try_into()?,
)?;

Ok(value!(entry))
}
}
7 changes: 4 additions & 3 deletions crates/wasm/tests/fs.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@ test.describe("PublicDirectory", () => {
});

expect(result.length).toBe(2);
expect(result.includes("dogs")).toBe(true);
expect(result.includes("cats")).toBe(true);
expect(result[0].name).toBe("cats");
expect(result[1].name).toBe("dogs");
});

test("rm can remove children from directory", async ({ page }) => {
Expand Down Expand Up @@ -137,6 +137,7 @@ test.describe("PublicDirectory", () => {
return result;
});

expect(result).toEqual(["dogs"]);
expect(result.length).toEqual(1)
expect(result[0].name).toEqual("dogs");
});
});