Skip to content

Commit 2518c94

Browse files
matheus23appcypher
andauthored
Add more JS APIs (#44)
* Add more JS APIs - `previousCid` - `contentCid` for Public Files - `store` and `load` for Public Files - `metadata` - `isFile` and `asFile` for Public Node * Use `Vec<u8>` instead of Uint8Array Co-authored-by: appcypher <[email protected]> * Use `Vec<u8>` instead of Uint8Array Co-authored-by: appcypher <[email protected]> * More usage of `Vec<u8>` instead of `Uint8Array` * Expose setting the panic hook Co-authored-by: appcypher <[email protected]>
1 parent 345d758 commit 2518c94

File tree

7 files changed

+124
-15
lines changed

7 files changed

+124
-15
lines changed

crates/fs/public/directory.rs

+5
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,11 @@ impl PublicDirectory {
241241
self.previous
242242
}
243243

244+
/// Gets the metadata of the directory
245+
pub fn get_metadata<'a>(self: &'a Rc<Self>) -> &'a Metadata {
246+
&self.metadata
247+
}
248+
244249
/// Gets the directory nodes along specified path.
245250
///
246251
/// Supports cases where the entire path does not exist.

crates/fs/public/file.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,21 @@ impl PublicFile {
5656
}
5757
}
5858

59-
// Gets the previous value of the file.
59+
/// Gets the previous value of the file.
6060
pub fn get_previous(self: &Rc<Self>) -> Option<Cid> {
6161
self.previous
6262
}
6363

64+
/// Gets the metadata of the file
65+
pub fn get_metadata<'a>(self: &'a Rc<Self>) -> &'a Metadata {
66+
&self.metadata
67+
}
68+
69+
/// Gets the content cid of a file
70+
pub fn get_content_cid(self: &Rc<Self>) -> Cid {
71+
self.userland
72+
}
73+
6474
/// Stores file in provided block store.
6575
///
6676
/// # Examples

crates/fs/public/node.rs

+5
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,11 @@ impl PublicNode {
107107
matches!(self, Self::Dir(_))
108108
}
109109

110+
/// Returns true if the underlying node is a file.
111+
pub fn is_file(&self) -> bool {
112+
matches!(self, Self::File(_))
113+
}
114+
110115
/// Gets the node kind.
111116
pub fn kind(&self) -> UnixFsNodeKind {
112117
match self {

crates/wasm/fs/public/directory.rs

+21-4
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use wnfs::{
1515
BlockStore as WnfsBlockStore, Id,
1616
};
1717

18-
use crate::fs::{BlockStore, ForeignBlockStore, JsResult, PublicNode};
18+
use crate::fs::{metadata::JsMetadata, BlockStore, ForeignBlockStore, JsResult, PublicNode};
1919
use crate::value;
2020

2121
/// A directory in a WNFS public file system.
@@ -87,10 +87,10 @@ impl PublicDirectory {
8787
}
8888

8989
/// Loads a directory given its CID from the block store.
90-
pub fn load(cid: Uint8Array, store: BlockStore) -> JsResult<Promise> {
90+
pub fn load(cid: Vec<u8>, store: BlockStore) -> JsResult<Promise> {
9191
let store = ForeignBlockStore(store);
92-
let cid = Cid::read_bytes(cid.to_vec().as_slice())
93-
.map_err(|e| Error::new(&format!("Cannot parse cid: {e}")))?;
92+
let cid =
93+
Cid::read_bytes(&cid[..]).map_err(|e| Error::new(&format!("Cannot parse cid: {e}")))?;
9494
Ok(future_to_promise(async move {
9595
let directory: WnfsPublicDirectory = store
9696
.get_deserializable(&cid)
@@ -252,6 +252,23 @@ impl PublicDirectory {
252252
}))
253253
}
254254

255+
/// Gets the previous cid of the directory or null if it doesn't have a previous cid.
256+
#[wasm_bindgen(js_name = "previousCid")]
257+
pub fn previous_cid(&self) -> JsValue {
258+
match self.0.get_previous() {
259+
Some(cid) => {
260+
let cid_u8array = Uint8Array::from(&cid.to_bytes()[..]);
261+
value!(cid_u8array)
262+
}
263+
None => JsValue::NULL,
264+
}
265+
}
266+
267+
/// Gets the metadata of the directory
268+
pub fn metadata(&self) -> JsResult<JsValue> {
269+
JsMetadata(self.0.get_metadata()).try_into()
270+
}
271+
255272
/// Converts directory to a node.
256273
#[wasm_bindgen(js_name = "asNode")]
257274
pub fn as_node(&self) -> PublicNode {

crates/wasm/fs/public/file.rs

+65-9
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,88 @@
11
//! The bindgen API for PublicFile.
22
3+
use crate::{fs::metadata::JsMetadata, value};
34
use chrono::{DateTime, Utc};
4-
use js_sys::{Error, Uint8Array};
5-
use wasm_bindgen::prelude::wasm_bindgen;
6-
use wnfs::{ipld::Cid, public::PublicFile as WnfsPublicFile, Id};
5+
use js_sys::{Error, Promise, Uint8Array};
6+
use std::rc::Rc;
7+
use wasm_bindgen::{prelude::wasm_bindgen, JsValue};
8+
use wasm_bindgen_futures::future_to_promise;
9+
use wnfs::{ipld::Cid, public::PublicFile as WnfsPublicFile, BlockStore as WnfsBlockStore, Id};
710

8-
use crate::fs::JsResult;
11+
use crate::fs::{BlockStore, ForeignBlockStore, JsResult};
912

1013
/// A file in a WNFS public file system.
1114
#[wasm_bindgen]
12-
pub struct PublicFile(WnfsPublicFile);
15+
pub struct PublicFile(pub(crate) Rc<WnfsPublicFile>);
1316

1417
#[wasm_bindgen]
1518
impl PublicFile {
1619
/// Creates a new file in a WNFS public file system.
1720
#[wasm_bindgen(constructor)]
18-
pub fn new(time: &js_sys::Date, cid: Uint8Array) -> JsResult<PublicFile> {
21+
pub fn new(time: &js_sys::Date, cid: Vec<u8>) -> JsResult<PublicFile> {
1922
let time = DateTime::<Utc>::from(time);
2023

21-
let cid = Cid::try_from(&cid.to_vec()[..])
22-
.map_err(|e| Error::new(&format!("Invalid CID: {e}")))?;
24+
let cid = Cid::try_from(&cid[..]).map_err(|e| Error::new(&format!("Invalid CID: {e}")))?;
2325

24-
Ok(PublicFile(WnfsPublicFile::new(time, cid)))
26+
Ok(PublicFile(Rc::new(WnfsPublicFile::new(time, cid))))
2527
}
2628

2729
/// Gets a unique id for node.
2830
#[wasm_bindgen(js_name = "getId")]
2931
pub fn get_id(&self) -> String {
3032
self.0.get_id()
3133
}
34+
35+
/// Stores a file in provided block store.
36+
pub fn store(&self, store: BlockStore) -> JsResult<Promise> {
37+
let file = Rc::clone(&self.0);
38+
let mut store = ForeignBlockStore(store);
39+
40+
Ok(future_to_promise(async move {
41+
let cid = file
42+
.store(&mut store)
43+
.await
44+
.map_err(|e| Error::new(&format!("Cannot add to store: {e}")))?;
45+
46+
let cid_u8array = Uint8Array::from(&cid.to_bytes()[..]);
47+
48+
Ok(value!(cid_u8array))
49+
}))
50+
}
51+
52+
/// Loads a file given its CID from the block store.
53+
pub fn load(cid: Vec<u8>, store: BlockStore) -> JsResult<Promise> {
54+
let store = ForeignBlockStore(store);
55+
let cid = Cid::try_from(cid).map_err(|e| Error::new(&format!("Cannot parse cid: {e}")))?;
56+
Ok(future_to_promise(async move {
57+
let file: WnfsPublicFile = store
58+
.get_deserializable(&cid)
59+
.await
60+
.map_err(|e| Error::new(&format!("Couldn't deserialize directory: {e}")))?;
61+
62+
Ok(value!(PublicFile(Rc::new(file))))
63+
}))
64+
}
65+
66+
/// Gets the previous cid of the file or null if the file doesn't have a previous cid.
67+
#[wasm_bindgen(js_name = "previousCid")]
68+
pub fn previous_cid(&self) -> JsValue {
69+
match self.0.get_previous() {
70+
Some(cid) => {
71+
let cid_u8array = Uint8Array::from(&cid.to_bytes()[..]);
72+
value!(cid_u8array)
73+
}
74+
None => JsValue::NULL,
75+
}
76+
}
77+
78+
/// Gets the metadata of this file.
79+
pub fn metadata(&self) -> JsResult<JsValue> {
80+
JsMetadata(self.0.get_metadata()).try_into()
81+
}
82+
83+
/// Gets the content cid of the file.
84+
#[wasm_bindgen(js_name = "contentCid")]
85+
pub fn content_cid(&self) -> Vec<u8> {
86+
self.0.get_content_cid().to_bytes()
87+
}
3288
}

crates/wasm/fs/public/node.rs

+16-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use js_sys::Error;
22
use wasm_bindgen::prelude::wasm_bindgen;
33
use wnfs::{public::PublicNode as WnfsPublicNode, Id};
44

5-
use crate::fs::{JsResult, PublicDirectory};
5+
use crate::fs::{JsResult, PublicDirectory, PublicFile};
66

77
/// Wraps a wnfs PublicNode.
88
#[wasm_bindgen]
@@ -20,11 +20,26 @@ impl PublicNode {
2020
Ok(PublicDirectory(dir))
2121
}
2222

23+
#[wasm_bindgen(js_name = "asFile")]
24+
pub fn as_file(&self) -> JsResult<PublicFile> {
25+
let file = self
26+
.0
27+
.as_file()
28+
.map_err(|e| Error::new(&format!("Cannot cast to a file: {e}")))?;
29+
30+
Ok(PublicFile(file))
31+
}
32+
2333
#[wasm_bindgen(js_name = "isDir")]
2434
pub fn is_dir(&self) -> bool {
2535
self.0.is_dir()
2636
}
2737

38+
#[wasm_bindgen(js_name = "isFile")]
39+
pub fn is_file(&self) -> bool {
40+
self.0.is_file()
41+
}
42+
2843
#[wasm_bindgen(js_name = "getId")]
2944
pub fn get_id(&self) -> String {
3045
self.0.get_id()

crates/wasm/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ pub mod fs;
1212
///
1313
/// This function needs to be called at least once during initialisation.
1414
/// https://rustwasm.github.io/docs/wasm-pack/tutorials/npm-browser-packages/template-deep-dive/src-utils-rs.html#2-what-is-console_error_panic_hook
15+
#[wasm_bindgen(js_name = "setPanicHook")]
1516
pub fn set_panic_hook() {
1617
#[cfg(feature = "console_error_panic_hook")]
1718
console_error_panic_hook::set_once();

0 commit comments

Comments
 (0)