webtorrent_rs_wrapper/
lib.rs

1use js_sys::{Object, Promise};
2use wasm_bindgen::prelude::*;
3use wasm_bindgen::JsValue;
4use wasm_bindgen_futures::JsFuture;
5
6// JS interop for the WebTorrent client
7#[wasm_bindgen(module = "/js/shim.js")]
8extern "C" {
9    #[wasm_bindgen(js_name = WebTorrentClient)]
10    pub type JsWebTorrentClient;
11
12    #[wasm_bindgen(js_name = createClient)]
13    pub fn create_client() -> JsWebTorrentClient;
14
15    #[wasm_bindgen(method, js_name = seed)]
16    pub fn seed(this: &JsWebTorrentClient, input: &JsValue, opts: &JsValue, onseed: &JsValue) -> JsValue;
17
18    #[wasm_bindgen(method, js_name = add)]
19    pub fn add(
20        this: &JsWebTorrentClient,
21        torrent_id: &JsValue,
22        opts: &JsValue,
23        ontorrent: &JsValue,
24    ) -> JsValue;
25
26    #[wasm_bindgen(method, js_name = createServer)]
27    pub fn create_server(this: &JsWebTorrentClient, options: &JsValue, force: bool) -> JsValue;
28
29    #[wasm_bindgen(method, js_name = getTorrent)]
30    pub fn get_torrent(this: &JsWebTorrentClient, torrent_id: &JsValue) -> Promise;
31
32    #[wasm_bindgen(method, js_name = remove)]
33    pub fn remove(
34        this: &JsWebTorrentClient,
35        torrent_id: &JsValue,
36        opts: &JsValue,
37        cb: &JsValue,
38    );
39
40    #[wasm_bindgen(method, js_name = throttleDownload)]
41    pub fn throttle_download(this: &JsWebTorrentClient, rate: f64);
42
43    #[wasm_bindgen(method, js_name = throttleUpload)]
44    pub fn throttle_upload(this: &JsWebTorrentClient, rate: f64);
45
46    #[wasm_bindgen(method, js_name = destroy)]
47    pub fn destroy(this: &JsWebTorrentClient, cb: &JsValue);
48
49    #[wasm_bindgen(method, js_name = isReadable)]
50    pub fn is_readable(this: &JsWebTorrentClient, obj: &JsValue) -> bool;
51
52    #[wasm_bindgen(method, js_name = isFileList)]
53    pub fn is_file_list(this: &JsWebTorrentClient, obj: &JsValue) -> bool;
54}
55
56// Wrapper for the WebTorrent client
57#[wasm_bindgen]
58pub struct WebTorrentClient {
59    inner: JsWebTorrentClient,
60}
61
62#[wasm_bindgen]
63impl WebTorrentClient {
64    // Fix: Use static method pattern instead of constructor
65    #[wasm_bindgen(js_name = new)]
66    pub fn new() -> Self {
67        Self {
68            inner: create_client()
69        }
70    }
71
72    #[wasm_bindgen]
73    pub async fn seed(&self, input: JsValue, opts_str: String) -> Result<JsValue, JsValue> {
74        // Parse JSON options from string
75        let opts = js_sys::JSON::parse(&opts_str).unwrap_or(JsValue::from(Object::new()));
76        let promise = self.inner.seed(&input, &opts, &JsValue::UNDEFINED);
77        JsFuture::from(Promise::from(promise)).await
78    }
79
80    #[wasm_bindgen]
81    pub async fn add(&self, torrent_id: String) -> Result<JsValue, JsValue> {
82        let opts = Object::new();
83        let promise = self.inner.add(&JsValue::from_str(&torrent_id), &JsValue::from(opts), &JsValue::UNDEFINED);
84        JsFuture::from(Promise::from(promise)).await
85    }
86
87    #[wasm_bindgen]
88    pub fn create_server(&self, options: Option<String>, force: bool) -> JsValue {
89        let opts = match options {
90            Some(opts_str) => js_sys::JSON::parse(&opts_str).unwrap_or(JsValue::from(Object::new())),
91            None => JsValue::from(Object::new()),
92        };
93        self.inner.create_server(&opts, force)
94    }
95
96    #[wasm_bindgen]
97    pub async fn get_torrent(&self, torrent_id: String) -> Result<JsValue, JsValue> {
98        let promise = self.inner.get_torrent(&JsValue::from_str(&torrent_id));
99        JsFuture::from(promise).await
100    }
101
102    #[wasm_bindgen]
103    pub fn remove(&self, torrent_id: String) {
104        let opts = Object::new();
105        self.inner.remove(&JsValue::from_str(&torrent_id), &JsValue::from(opts), &JsValue::UNDEFINED);
106    }
107
108    #[wasm_bindgen]
109    pub fn throttle_download(&self, rate: f64) {
110        self.inner.throttle_download(rate);
111    }
112
113    #[wasm_bindgen]
114    pub fn throttle_upload(&self, rate: f64) {
115        self.inner.throttle_upload(rate);
116    }
117
118    #[wasm_bindgen]
119    pub fn destroy(&self) {
120        self.inner.destroy(&JsValue::UNDEFINED);
121    }
122
123    #[wasm_bindgen]
124    pub fn is_readable(&self, obj: JsValue) -> bool {
125        self.inner.is_readable(&obj)
126    }
127
128    #[wasm_bindgen]
129    pub fn is_file_list(&self, obj: JsValue) -> bool {
130        self.inner.is_file_list(&obj)
131    }
132}