bitwarden_ipc/wasm/
js_session_repository.rs1use bitwarden_threading::ThreadBoundRunner;
2use serde::{Serialize, de::DeserializeOwned};
3use tsify::serde_wasm_bindgen;
4use wasm_bindgen::prelude::*;
5
6use crate::{endpoint::Endpoint, traits::SessionRepository};
7
8#[wasm_bindgen(typescript_custom_section)]
9const TS_CUSTOM_TYPES: &'static str = r#"
10export interface IpcSessionRepository {
11 get(endpoint: Endpoint): Promise<any | undefined>;
12 save(endpoint: Endpoint, session: any): Promise<void>;
13 remove(endpoint: Endpoint): Promise<void>;
14}
15"#;
16
17#[wasm_bindgen]
18extern "C" {
19 #[wasm_bindgen(js_name = IpcSessionRepository, typescript_type = "IpcSessionRepository")]
21 pub type RawJsSessionRepository;
22
23 #[wasm_bindgen(catch, method, structural)]
25 pub async fn get(this: &RawJsSessionRepository, endpoint: Endpoint)
26 -> Result<JsValue, JsValue>;
27
28 #[wasm_bindgen(catch, method, structural)]
30 pub async fn save(
31 this: &RawJsSessionRepository,
32 endpoint: Endpoint,
33 session: JsValue,
34 ) -> Result<(), JsValue>;
35
36 #[wasm_bindgen(catch, method, structural)]
38 pub async fn remove(this: &RawJsSessionRepository, endpoint: Endpoint) -> Result<(), JsValue>;
39}
40
41pub struct JsSessionRepository(ThreadBoundRunner<RawJsSessionRepository>);
43
44impl JsSessionRepository {
45 pub fn new(repository: RawJsSessionRepository) -> Self {
47 Self(ThreadBoundRunner::new(repository))
48 }
49}
50
51impl Clone for JsSessionRepository {
52 fn clone(&self) -> Self {
53 Self(self.0.clone())
54 }
55}
56
57impl<Session> SessionRepository<Session> for JsSessionRepository
58where
59 Session: Serialize + DeserializeOwned + Send + Sync + 'static,
60{
61 type GetError = String;
62 type SaveError = String;
63 type RemoveError = String;
64
65 async fn get(&self, endpoint: Endpoint) -> Result<Option<Session>, Self::GetError> {
66 self.0
67 .run_in_thread(move |repo| async move {
68 let js_value = repo.get(endpoint).await.map_err(|e| format!("{e:?}"))?;
69 if js_value.is_undefined() || js_value.is_null() {
70 return Ok(None);
71 }
72
73 Ok(Some(
74 serde_wasm_bindgen::from_value(js_value).map_err(|e| e.to_string())?,
75 ))
76 })
77 .await
78 .map_err(|e| e.to_string())?
79 }
80
81 async fn save(&self, endpoint: Endpoint, session: Session) -> Result<(), Self::SaveError> {
82 self.0
83 .run_in_thread(move |repo| async move {
84 let js_value = serde_wasm_bindgen::to_value(&session).map_err(|e| e.to_string())?;
85 repo.save(endpoint, js_value)
86 .await
87 .map_err(|e| format!("{e:?}"))
88 })
89 .await
90 .map_err(|e| e.to_string())?
91 }
92
93 async fn remove(&self, endpoint: Endpoint) -> Result<(), Self::RemoveError> {
94 self.0
95 .run_in_thread(move |repo| async move {
96 repo.remove(endpoint).await.map_err(|e| format!("{e:?}"))
97 })
98 .await
99 .map_err(|e| e.to_string())?
100 }
101}