From 744e5f150e6662c043a64fe8a250b7cf5fb2903c Mon Sep 17 00:00:00 2001 From: Emmanuel Leblond Date: Tue, 28 May 2024 17:43:13 +0200 Subject: [PATCH] Re-generate electron&web bindings --- bindings/electron/src/index.d.ts | 54 ++++++ bindings/electron/src/meths.rs | 176 ++++++++++++++++++++ bindings/web/src/meths.rs | 163 ++++++++++++++++++ client/src/plugins/libparsec/definitions.ts | 65 ++++++++ 4 files changed, 458 insertions(+) diff --git a/bindings/electron/src/index.d.ts b/bindings/electron/src/index.d.ts index f4d6153573e..ea64b1bc856 100644 --- a/bindings/electron/src/index.d.ts +++ b/bindings/electron/src/index.d.ts @@ -517,6 +517,11 @@ export interface ClientEventTooMuchDriftWithServerClock { export interface ClientEventWorkspaceLocallyCreated { tag: "WorkspaceLocallyCreated" } +export interface ClientEventWorkspaceWatchedEntryChanged { + tag: "WorkspaceWatchedEntryChanged" + realm_id: string + entry_id: string +} export interface ClientEventWorkspacesSelfAccessChanged { tag: "WorkspacesSelfAccessChanged" } @@ -531,6 +536,7 @@ export type ClientEvent = | ClientEventServerConfigChanged | ClientEventTooMuchDriftWithServerClock | ClientEventWorkspaceLocallyCreated + | ClientEventWorkspaceWatchedEntryChanged | ClientEventWorkspacesSelfAccessChanged @@ -1890,6 +1896,50 @@ export type WorkspaceStorageCacheSize = | WorkspaceStorageCacheSizeDefault +// WorkspaceWatchError +export interface WorkspaceWatchErrorEntryNotFound { + tag: "EntryNotFound" + error: string +} +export interface WorkspaceWatchErrorInternal { + tag: "Internal" + error: string +} +export interface WorkspaceWatchErrorInvalidCertificate { + tag: "InvalidCertificate" + error: string +} +export interface WorkspaceWatchErrorInvalidKeysBundle { + tag: "InvalidKeysBundle" + error: string +} +export interface WorkspaceWatchErrorInvalidManifest { + tag: "InvalidManifest" + error: string +} +export interface WorkspaceWatchErrorNoRealmAccess { + tag: "NoRealmAccess" + error: string +} +export interface WorkspaceWatchErrorOffline { + tag: "Offline" + error: string +} +export interface WorkspaceWatchErrorStopped { + tag: "Stopped" + error: string +} +export type WorkspaceWatchError = + | WorkspaceWatchErrorEntryNotFound + | WorkspaceWatchErrorInternal + | WorkspaceWatchErrorInvalidCertificate + | WorkspaceWatchErrorInvalidKeysBundle + | WorkspaceWatchErrorInvalidManifest + | WorkspaceWatchErrorNoRealmAccess + | WorkspaceWatchErrorOffline + | WorkspaceWatchErrorStopped + + export function bootstrapOrganization( config: ClientConfig, on_event_callback: (event: ClientEvent) => void, @@ -2267,3 +2317,7 @@ export function workspaceStatFolderChildrenById( export function workspaceStop( workspace: number ): Promise> +export function workspaceWatchEntryOneshot( + workspace: number, + path: string +): Promise> diff --git a/bindings/electron/src/meths.rs b/bindings/electron/src/meths.rs index b7ffc037ac4..5fc70bfff1c 100644 --- a/bindings/electron/src/meths.rs +++ b/bindings/electron/src/meths.rs @@ -2734,6 +2734,33 @@ fn variant_client_event_js_to_rs<'a>( "ClientEventWorkspaceLocallyCreated" => { Ok(libparsec::ClientEvent::WorkspaceLocallyCreated {}) } + "ClientEventWorkspaceWatchedEntryChanged" => { + let realm_id = { + let js_val: Handle = obj.get(cx, "realmId")?; + { + let custom_from_rs_string = |s: String| -> Result { + libparsec::VlobID::from_hex(s.as_str()).map_err(|e| e.to_string()) + }; + match custom_from_rs_string(js_val.value(cx)) { + Ok(val) => val, + Err(err) => return cx.throw_type_error(err), + } + } + }; + let entry_id = { + let js_val: Handle = obj.get(cx, "entryId")?; + { + let custom_from_rs_string = |s: String| -> Result { + libparsec::VlobID::from_hex(s.as_str()).map_err(|e| e.to_string()) + }; + match custom_from_rs_string(js_val.value(cx)) { + Ok(val) => val, + Err(err) => return cx.throw_type_error(err), + } + } + }; + Ok(libparsec::ClientEvent::WorkspaceWatchedEntryChanged { realm_id, entry_id }) + } "ClientEventWorkspacesSelfAccessChanged" => { Ok(libparsec::ClientEvent::WorkspacesSelfAccessChanged {}) } @@ -2845,6 +2872,33 @@ fn variant_client_event_rs_to_js<'a>( JsString::try_new(cx, "ClientEventWorkspaceLocallyCreated").or_throw(cx)?; js_obj.set(cx, "tag", js_tag)?; } + libparsec::ClientEvent::WorkspaceWatchedEntryChanged { + realm_id, entry_id, .. + } => { + let js_tag = + JsString::try_new(cx, "ClientEventWorkspaceWatchedEntryChanged").or_throw(cx)?; + js_obj.set(cx, "tag", js_tag)?; + let js_realm_id = JsString::try_new(cx, { + let custom_to_rs_string = + |x: libparsec::VlobID| -> Result { Ok(x.hex()) }; + match custom_to_rs_string(realm_id) { + Ok(ok) => ok, + Err(err) => return cx.throw_type_error(err), + } + }) + .or_throw(cx)?; + js_obj.set(cx, "realmId", js_realm_id)?; + let js_entry_id = JsString::try_new(cx, { + let custom_to_rs_string = + |x: libparsec::VlobID| -> Result { Ok(x.hex()) }; + match custom_to_rs_string(entry_id) { + Ok(ok) => ok, + Err(err) => return cx.throw_type_error(err), + } + }) + .or_throw(cx)?; + js_obj.set(cx, "entryId", js_entry_id)?; + } libparsec::ClientEvent::WorkspacesSelfAccessChanged { .. } => { let js_tag = JsString::try_new(cx, "ClientEventWorkspacesSelfAccessChanged").or_throw(cx)?; @@ -6073,6 +6127,56 @@ fn variant_workspace_storage_cache_size_rs_to_js<'a>( Ok(js_obj) } +// WorkspaceWatchError + +#[allow(dead_code)] +fn variant_workspace_watch_error_rs_to_js<'a>( + cx: &mut impl Context<'a>, + rs_obj: libparsec::WorkspaceWatchError, +) -> NeonResult> { + let js_obj = cx.empty_object(); + let js_display = JsString::try_new(cx, &rs_obj.to_string()).or_throw(cx)?; + js_obj.set(cx, "error", js_display)?; + match rs_obj { + libparsec::WorkspaceWatchError::EntryNotFound { .. } => { + let js_tag = JsString::try_new(cx, "WorkspaceWatchErrorEntryNotFound").or_throw(cx)?; + js_obj.set(cx, "tag", js_tag)?; + } + libparsec::WorkspaceWatchError::Internal { .. } => { + let js_tag = JsString::try_new(cx, "WorkspaceWatchErrorInternal").or_throw(cx)?; + js_obj.set(cx, "tag", js_tag)?; + } + libparsec::WorkspaceWatchError::InvalidCertificate { .. } => { + let js_tag = + JsString::try_new(cx, "WorkspaceWatchErrorInvalidCertificate").or_throw(cx)?; + js_obj.set(cx, "tag", js_tag)?; + } + libparsec::WorkspaceWatchError::InvalidKeysBundle { .. } => { + let js_tag = + JsString::try_new(cx, "WorkspaceWatchErrorInvalidKeysBundle").or_throw(cx)?; + js_obj.set(cx, "tag", js_tag)?; + } + libparsec::WorkspaceWatchError::InvalidManifest { .. } => { + let js_tag = + JsString::try_new(cx, "WorkspaceWatchErrorInvalidManifest").or_throw(cx)?; + js_obj.set(cx, "tag", js_tag)?; + } + libparsec::WorkspaceWatchError::NoRealmAccess { .. } => { + let js_tag = JsString::try_new(cx, "WorkspaceWatchErrorNoRealmAccess").or_throw(cx)?; + js_obj.set(cx, "tag", js_tag)?; + } + libparsec::WorkspaceWatchError::Offline { .. } => { + let js_tag = JsString::try_new(cx, "WorkspaceWatchErrorOffline").or_throw(cx)?; + js_obj.set(cx, "tag", js_tag)?; + } + libparsec::WorkspaceWatchError::Stopped { .. } => { + let js_tag = JsString::try_new(cx, "WorkspaceWatchErrorStopped").or_throw(cx)?; + js_obj.set(cx, "tag", js_tag)?; + } + } + Ok(js_obj) +} + // bootstrap_organization fn bootstrap_organization(mut cx: FunctionContext) -> JsResult { let config = { @@ -11524,6 +11628,77 @@ fn workspace_stop(mut cx: FunctionContext) -> JsResult { Ok(promise) } +// workspace_watch_entry_oneshot +fn workspace_watch_entry_oneshot(mut cx: FunctionContext) -> JsResult { + let workspace = { + let js_val = cx.argument::(0)?; + { + let v = js_val.value(&mut cx); + if v < (u32::MIN as f64) || (u32::MAX as f64) < v { + cx.throw_type_error("Not an u32 number")? + } + let v = v as u32; + v + } + }; + let path = { + let js_val = cx.argument::(1)?; + { + let custom_from_rs_string = |s: String| -> Result<_, String> { + s.parse::().map_err(|e| e.to_string()) + }; + match custom_from_rs_string(js_val.value(&mut cx)) { + Ok(val) => val, + Err(err) => return cx.throw_type_error(err), + } + } + }; + let channel = cx.channel(); + let (deferred, promise) = cx.promise(); + + // TODO: Promises are not cancellable in Javascript by default, should we add a custom cancel method ? + let _handle = crate::TOKIO_RUNTIME + .lock() + .expect("Mutex is poisoned") + .spawn(async move { + let ret = libparsec::workspace_watch_entry_oneshot(workspace, path).await; + + deferred.settle_with(&channel, move |mut cx| { + let js_ret = match ret { + Ok(ok) => { + let js_obj = JsObject::new(&mut cx); + let js_tag = JsBoolean::new(&mut cx, true); + js_obj.set(&mut cx, "ok", js_tag)?; + let js_value = JsString::try_new(&mut cx, { + let custom_to_rs_string = + |x: libparsec::VlobID| -> Result { + Ok(x.hex()) + }; + match custom_to_rs_string(ok) { + Ok(ok) => ok, + Err(err) => return cx.throw_type_error(err), + } + }) + .or_throw(&mut cx)?; + js_obj.set(&mut cx, "value", js_value)?; + js_obj + } + Err(err) => { + let js_obj = cx.empty_object(); + let js_tag = JsBoolean::new(&mut cx, false); + js_obj.set(&mut cx, "ok", js_tag)?; + let js_err = variant_workspace_watch_error_rs_to_js(&mut cx, err)?; + js_obj.set(&mut cx, "error", js_err)?; + js_obj + } + }; + Ok(js_ret) + }); + }); + + Ok(promise) +} + pub fn register_meths(cx: &mut ModuleContext) -> NeonResult<()> { cx.export_function("bootstrapOrganization", bootstrap_organization)?; cx.export_function( @@ -11708,5 +11883,6 @@ pub fn register_meths(cx: &mut ModuleContext) -> NeonResult<()> { workspace_stat_folder_children_by_id, )?; cx.export_function("workspaceStop", workspace_stop)?; + cx.export_function("workspaceWatchEntryOneshot", workspace_watch_entry_oneshot)?; Ok(()) } diff --git a/bindings/web/src/meths.rs b/bindings/web/src/meths.rs index 6332e0ab5ad..1489ea248b9 100644 --- a/bindings/web/src/meths.rs +++ b/bindings/web/src/meths.rs @@ -2937,6 +2937,39 @@ fn variant_client_event_js_to_rs(obj: JsValue) -> Result { Ok(libparsec::ClientEvent::WorkspaceLocallyCreated {}) } + "ClientEventWorkspaceWatchedEntryChanged" => { + let realm_id = { + let js_val = Reflect::get(&obj, &"realmId".into())?; + js_val + .dyn_into::() + .ok() + .and_then(|s| s.as_string()) + .ok_or_else(|| TypeError::new("Not a string")) + .and_then(|x| { + let custom_from_rs_string = |s: String| -> Result { + libparsec::VlobID::from_hex(s.as_str()).map_err(|e| e.to_string()) + }; + custom_from_rs_string(x).map_err(|e| TypeError::new(e.as_ref())) + }) + .map_err(|_| TypeError::new("Not a valid VlobID"))? + }; + let entry_id = { + let js_val = Reflect::get(&obj, &"entryId".into())?; + js_val + .dyn_into::() + .ok() + .and_then(|s| s.as_string()) + .ok_or_else(|| TypeError::new("Not a string")) + .and_then(|x| { + let custom_from_rs_string = |s: String| -> Result { + libparsec::VlobID::from_hex(s.as_str()).map_err(|e| e.to_string()) + }; + custom_from_rs_string(x).map_err(|e| TypeError::new(e.as_ref())) + }) + .map_err(|_| TypeError::new("Not a valid VlobID"))? + }; + Ok(libparsec::ClientEvent::WorkspaceWatchedEntryChanged { realm_id, entry_id }) + } "ClientEventWorkspacesSelfAccessChanged" => { Ok(libparsec::ClientEvent::WorkspacesSelfAccessChanged {}) } @@ -3058,6 +3091,35 @@ fn variant_client_event_rs_to_js(rs_obj: libparsec::ClientEvent) -> Result { + Reflect::set( + &js_obj, + &"tag".into(), + &"ClientEventWorkspaceWatchedEntryChanged".into(), + )?; + let js_realm_id = JsValue::from_str({ + let custom_to_rs_string = + |x: libparsec::VlobID| -> Result { Ok(x.hex()) }; + match custom_to_rs_string(realm_id) { + Ok(ok) => ok, + Err(err) => return Err(JsValue::from(TypeError::new(err.as_ref()))), + } + .as_ref() + }); + Reflect::set(&js_obj, &"realmId".into(), &js_realm_id)?; + let js_entry_id = JsValue::from_str({ + let custom_to_rs_string = + |x: libparsec::VlobID| -> Result { Ok(x.hex()) }; + match custom_to_rs_string(entry_id) { + Ok(ok) => ok, + Err(err) => return Err(JsValue::from(TypeError::new(err.as_ref()))), + } + .as_ref() + }); + Reflect::set(&js_obj, &"entryId".into(), &js_entry_id)?; + } libparsec::ClientEvent::WorkspacesSelfAccessChanged { .. } => { Reflect::set( &js_obj, @@ -6894,6 +6956,68 @@ fn variant_workspace_storage_cache_size_rs_to_js( Ok(js_obj) } +// WorkspaceWatchError + +#[allow(dead_code)] +fn variant_workspace_watch_error_rs_to_js( + rs_obj: libparsec::WorkspaceWatchError, +) -> Result { + let js_obj = Object::new().into(); + let js_display = &rs_obj.to_string(); + Reflect::set(&js_obj, &"error".into(), &js_display.into())?; + match rs_obj { + libparsec::WorkspaceWatchError::EntryNotFound { .. } => { + Reflect::set( + &js_obj, + &"tag".into(), + &"WorkspaceWatchErrorEntryNotFound".into(), + )?; + } + libparsec::WorkspaceWatchError::Internal { .. } => { + Reflect::set( + &js_obj, + &"tag".into(), + &"WorkspaceWatchErrorInternal".into(), + )?; + } + libparsec::WorkspaceWatchError::InvalidCertificate { .. } => { + Reflect::set( + &js_obj, + &"tag".into(), + &"WorkspaceWatchErrorInvalidCertificate".into(), + )?; + } + libparsec::WorkspaceWatchError::InvalidKeysBundle { .. } => { + Reflect::set( + &js_obj, + &"tag".into(), + &"WorkspaceWatchErrorInvalidKeysBundle".into(), + )?; + } + libparsec::WorkspaceWatchError::InvalidManifest { .. } => { + Reflect::set( + &js_obj, + &"tag".into(), + &"WorkspaceWatchErrorInvalidManifest".into(), + )?; + } + libparsec::WorkspaceWatchError::NoRealmAccess { .. } => { + Reflect::set( + &js_obj, + &"tag".into(), + &"WorkspaceWatchErrorNoRealmAccess".into(), + )?; + } + libparsec::WorkspaceWatchError::Offline { .. } => { + Reflect::set(&js_obj, &"tag".into(), &"WorkspaceWatchErrorOffline".into())?; + } + libparsec::WorkspaceWatchError::Stopped { .. } => { + Reflect::set(&js_obj, &"tag".into(), &"WorkspaceWatchErrorStopped".into())?; + } + } + Ok(js_obj) +} + // bootstrap_organization #[allow(non_snake_case)] #[wasm_bindgen] @@ -9849,3 +9973,42 @@ pub fn workspaceStop(workspace: u32) -> Promise { }) }) } + +// workspace_watch_entry_oneshot +#[allow(non_snake_case)] +#[wasm_bindgen] +pub fn workspaceWatchEntryOneshot(workspace: u32, path: String) -> Promise { + future_to_promise(async move { + let path = { + let custom_from_rs_string = |s: String| -> Result<_, String> { + s.parse::().map_err(|e| e.to_string()) + }; + custom_from_rs_string(path).map_err(|e| TypeError::new(e.as_ref())) + }?; + let ret = libparsec::workspace_watch_entry_oneshot(workspace, path).await; + Ok(match ret { + Ok(value) => { + let js_obj = Object::new().into(); + Reflect::set(&js_obj, &"ok".into(), &true.into())?; + let js_value = JsValue::from_str({ + let custom_to_rs_string = + |x: libparsec::VlobID| -> Result { Ok(x.hex()) }; + match custom_to_rs_string(value) { + Ok(ok) => ok, + Err(err) => return Err(JsValue::from(TypeError::new(err.as_ref()))), + } + .as_ref() + }); + Reflect::set(&js_obj, &"value".into(), &js_value)?; + js_obj + } + Err(err) => { + let js_obj = Object::new().into(); + Reflect::set(&js_obj, &"ok".into(), &false.into())?; + let js_err = variant_workspace_watch_error_rs_to_js(err)?; + Reflect::set(&js_obj, &"error".into(), &js_err)?; + js_obj + } + }) + }) +} diff --git a/client/src/plugins/libparsec/definitions.ts b/client/src/plugins/libparsec/definitions.ts index 95589d830ef..5f9dcb26e2f 100644 --- a/client/src/plugins/libparsec/definitions.ts +++ b/client/src/plugins/libparsec/definitions.ts @@ -540,6 +540,7 @@ export enum ClientEventTag { ServerConfigChanged = 'ClientEventServerConfigChanged', TooMuchDriftWithServerClock = 'ClientEventTooMuchDriftWithServerClock', WorkspaceLocallyCreated = 'ClientEventWorkspaceLocallyCreated', + WorkspaceWatchedEntryChanged = 'ClientEventWorkspaceWatchedEntryChanged', WorkspacesSelfAccessChanged = 'ClientEventWorkspacesSelfAccessChanged', } @@ -581,6 +582,11 @@ export interface ClientEventTooMuchDriftWithServerClock { export interface ClientEventWorkspaceLocallyCreated { tag: ClientEventTag.WorkspaceLocallyCreated } +export interface ClientEventWorkspaceWatchedEntryChanged { + tag: ClientEventTag.WorkspaceWatchedEntryChanged + realmId: VlobID + entryId: VlobID +} export interface ClientEventWorkspacesSelfAccessChanged { tag: ClientEventTag.WorkspacesSelfAccessChanged } @@ -595,6 +601,7 @@ export type ClientEvent = | ClientEventServerConfigChanged | ClientEventTooMuchDriftWithServerClock | ClientEventWorkspaceLocallyCreated + | ClientEventWorkspaceWatchedEntryChanged | ClientEventWorkspacesSelfAccessChanged // ClientGetUserDeviceError @@ -2269,6 +2276,60 @@ export type WorkspaceStorageCacheSize = | WorkspaceStorageCacheSizeCustom | WorkspaceStorageCacheSizeDefault +// WorkspaceWatchError +export enum WorkspaceWatchErrorTag { + EntryNotFound = 'WorkspaceWatchErrorEntryNotFound', + Internal = 'WorkspaceWatchErrorInternal', + InvalidCertificate = 'WorkspaceWatchErrorInvalidCertificate', + InvalidKeysBundle = 'WorkspaceWatchErrorInvalidKeysBundle', + InvalidManifest = 'WorkspaceWatchErrorInvalidManifest', + NoRealmAccess = 'WorkspaceWatchErrorNoRealmAccess', + Offline = 'WorkspaceWatchErrorOffline', + Stopped = 'WorkspaceWatchErrorStopped', +} + +export interface WorkspaceWatchErrorEntryNotFound { + tag: WorkspaceWatchErrorTag.EntryNotFound + error: string +} +export interface WorkspaceWatchErrorInternal { + tag: WorkspaceWatchErrorTag.Internal + error: string +} +export interface WorkspaceWatchErrorInvalidCertificate { + tag: WorkspaceWatchErrorTag.InvalidCertificate + error: string +} +export interface WorkspaceWatchErrorInvalidKeysBundle { + tag: WorkspaceWatchErrorTag.InvalidKeysBundle + error: string +} +export interface WorkspaceWatchErrorInvalidManifest { + tag: WorkspaceWatchErrorTag.InvalidManifest + error: string +} +export interface WorkspaceWatchErrorNoRealmAccess { + tag: WorkspaceWatchErrorTag.NoRealmAccess + error: string +} +export interface WorkspaceWatchErrorOffline { + tag: WorkspaceWatchErrorTag.Offline + error: string +} +export interface WorkspaceWatchErrorStopped { + tag: WorkspaceWatchErrorTag.Stopped + error: string +} +export type WorkspaceWatchError = + | WorkspaceWatchErrorEntryNotFound + | WorkspaceWatchErrorInternal + | WorkspaceWatchErrorInvalidCertificate + | WorkspaceWatchErrorInvalidKeysBundle + | WorkspaceWatchErrorInvalidManifest + | WorkspaceWatchErrorNoRealmAccess + | WorkspaceWatchErrorOffline + | WorkspaceWatchErrorStopped + export interface LibParsecPlugin { bootstrapOrganization( config: ClientConfig, @@ -2647,4 +2708,8 @@ export interface LibParsecPlugin { workspaceStop( workspace: Handle ): Promise> + workspaceWatchEntryOneshot( + workspace: Handle, + path: FsPath + ): Promise> }