Parcourir la source

refactor(runtime): remove clipboard APIs (#6735)

Lucas Fernandes Nogueira il y a 2 ans
Parent
commit
db9c12c1ad

+ 2 - 0
.changes/remove-clipboard.md

@@ -1,5 +1,7 @@
 ---
 "tauri": patch
+"tauri-runtime": patch
+"tauri-runtime-wry": patch
 "api": patch
 ---
 

+ 0 - 1
core/tauri-runtime-wry/Cargo.toml

@@ -49,5 +49,4 @@ macos-private-api = [
 ]
 objc-exception = [ "wry/objc-exception" ]
 global-shortcut = [ "tauri-runtime/global-shortcut" ]
-clipboard = [ "tauri-runtime/clipboard" ]
 linux-headers = [ "wry/linux-headers", "webkit2gtk/v2_36" ]

+ 0 - 62
core/tauri-runtime-wry/src/clipboard.rs

@@ -1,62 +0,0 @@
-// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
-// SPDX-License-Identifier: Apache-2.0
-// SPDX-License-Identifier: MIT
-
-//! Clipboard implementation.
-
-use crate::{getter, Context, Message};
-
-use std::sync::{
-  mpsc::{channel, Sender},
-  Arc, Mutex,
-};
-
-use tauri_runtime::{ClipboardManager, Result, UserEvent};
-pub use wry::application::clipboard::Clipboard;
-
-#[derive(Debug, Clone)]
-pub enum ClipboardMessage {
-  WriteText(String, Sender<()>),
-  ReadText(Sender<Option<String>>),
-}
-
-#[derive(Debug, Clone)]
-pub struct ClipboardManagerWrapper<T: UserEvent> {
-  pub context: Context<T>,
-}
-
-// SAFETY: this is safe since the `Context` usage is guarded on `send_user_message`.
-#[allow(clippy::non_send_fields_in_send_ty)]
-unsafe impl<T: UserEvent> Sync for ClipboardManagerWrapper<T> {}
-
-impl<T: UserEvent> ClipboardManager for ClipboardManagerWrapper<T> {
-  fn read_text(&self) -> Result<Option<String>> {
-    let (tx, rx) = channel();
-    getter!(self, rx, Message::Clipboard(ClipboardMessage::ReadText(tx)))
-  }
-
-  fn write_text<V: Into<String>>(&mut self, text: V) -> Result<()> {
-    let (tx, rx) = channel();
-    getter!(
-      self,
-      rx,
-      Message::Clipboard(ClipboardMessage::WriteText(text.into(), tx))
-    )?;
-    Ok(())
-  }
-}
-
-pub fn handle_clipboard_message(
-  message: ClipboardMessage,
-  clipboard_manager: &Arc<Mutex<Clipboard>>,
-) {
-  match message {
-    ClipboardMessage::WriteText(text, tx) => {
-      clipboard_manager.lock().unwrap().write_text(text);
-      tx.send(()).unwrap();
-    }
-    ClipboardMessage::ReadText(tx) => tx
-      .send(clipboard_manager.lock().unwrap().read_text())
-      .unwrap(),
-  }
-}

+ 0 - 70
core/tauri-runtime-wry/src/lib.rs

@@ -121,11 +121,6 @@ mod global_shortcut;
 #[cfg(all(desktop, feature = "global-shortcut"))]
 use global_shortcut::*;
 
-#[cfg(feature = "clipboard")]
-mod clipboard;
-#[cfg(feature = "clipboard")]
-use clipboard::*;
-
 pub type WebContextStore = Arc<Mutex<HashMap<Option<PathBuf>, WebContext>>>;
 // window
 pub type WindowEventHandler = Box<dyn Fn(&WindowEvent) + Send>;
@@ -176,8 +171,6 @@ pub(crate) fn send_user_message<T: UserEvent>(
         webview_id_map: context.webview_id_map.clone(),
         #[cfg(all(desktop, feature = "global-shortcut"))]
         global_shortcut_manager: context.main_thread.global_shortcut_manager.clone(),
-        #[cfg(feature = "clipboard")]
-        clipboard_manager: context.main_thread.clipboard_manager.clone(),
         windows: context.main_thread.windows.clone(),
         #[cfg(all(desktop, feature = "system-tray"))]
         system_tray_manager: context.main_thread.system_tray_manager.clone(),
@@ -252,8 +245,6 @@ pub struct DispatcherMainThreadContext<T: UserEvent> {
   pub web_context: WebContextStore,
   #[cfg(all(desktop, feature = "global-shortcut"))]
   pub global_shortcut_manager: Arc<Mutex<WryShortcutManager>>,
-  #[cfg(feature = "clipboard")]
-  pub clipboard_manager: Arc<Mutex<Clipboard>>,
   pub windows: Arc<RefCell<HashMap<WebviewId, WindowWrapper>>>,
   #[cfg(all(desktop, feature = "system-tray"))]
   system_tray_manager: SystemTrayManager,
@@ -1177,8 +1168,6 @@ pub enum Message<T: 'static> {
   ),
   #[cfg(all(desktop, feature = "global-shortcut"))]
   GlobalShortcut(GlobalShortcutMessage),
-  #[cfg(feature = "clipboard")]
-  Clipboard(ClipboardMessage),
   UserEvent(T),
 }
 
@@ -1190,8 +1179,6 @@ impl<T: UserEvent> Clone for Message<T> {
       Self::Tray(i, m) => Self::Tray(*i, m.clone()),
       #[cfg(all(desktop, feature = "global-shortcut"))]
       Self::GlobalShortcut(m) => Self::GlobalShortcut(m.clone()),
-      #[cfg(feature = "clipboard")]
-      Self::Clipboard(m) => Self::Clipboard(m.clone()),
       Self::UserEvent(t) => Self::UserEvent(t.clone()),
       _ => unimplemented!(),
     }
@@ -1742,9 +1729,6 @@ pub struct Wry<T: UserEvent> {
   #[cfg(all(desktop, feature = "global-shortcut"))]
   global_shortcut_manager_handle: GlobalShortcutManagerHandle<T>,
 
-  #[cfg(feature = "clipboard")]
-  clipboard_manager_handle: ClipboardManagerWrapper<T>,
-
   event_loop: EventLoop<Message<T>>,
 }
 
@@ -1773,13 +1757,6 @@ impl<T: UserEvent> fmt::Debug for Wry<T> {
       &self.global_shortcut_manager_handle,
     );
 
-    #[cfg(feature = "clipboard")]
-    d.field(
-      "clipboard_manager",
-      &self.context.main_thread.clipboard_manager,
-    )
-    .field("clipboard_manager_handle", &self.clipboard_manager_handle);
-
     d.finish()
   }
 }
@@ -1931,9 +1908,6 @@ impl<T: UserEvent> Wry<T> {
     #[cfg(all(desktop, feature = "global-shortcut"))]
     let global_shortcut_manager = Arc::new(Mutex::new(WryShortcutManager::new(&event_loop)));
 
-    #[cfg(feature = "clipboard")]
-    let clipboard_manager = Arc::new(Mutex::new(Clipboard::new()));
-
     let windows = Arc::new(RefCell::new(HashMap::default()));
     let webview_id_map = WebviewIdStore::default();
 
@@ -1949,8 +1923,6 @@ impl<T: UserEvent> Wry<T> {
         web_context,
         #[cfg(all(desktop, feature = "global-shortcut"))]
         global_shortcut_manager,
-        #[cfg(feature = "clipboard")]
-        clipboard_manager,
         windows,
         #[cfg(all(desktop, feature = "system-tray"))]
         system_tray_manager,
@@ -1965,21 +1937,12 @@ impl<T: UserEvent> Wry<T> {
       listeners: Default::default(),
     };
 
-    #[cfg(feature = "clipboard")]
-    #[allow(clippy::redundant_clone)]
-    let clipboard_manager_handle = ClipboardManagerWrapper {
-      context: context.clone(),
-    };
-
     Ok(Self {
       context,
 
       #[cfg(all(desktop, feature = "global-shortcut"))]
       global_shortcut_manager_handle,
 
-      #[cfg(feature = "clipboard")]
-      clipboard_manager_handle,
-
       event_loop,
     })
   }
@@ -1992,9 +1955,6 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
   #[cfg(all(desktop, feature = "global-shortcut"))]
   type GlobalShortcutManager = GlobalShortcutManagerHandle<T>;
 
-  #[cfg(feature = "clipboard")]
-  type ClipboardManager = ClipboardManagerWrapper<T>;
-
   #[cfg(all(desktop, feature = "system-tray"))]
   type TrayHandler = SystemTrayHandle<T>;
 
@@ -2030,11 +1990,6 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
     self.global_shortcut_manager_handle.clone()
   }
 
-  #[cfg(feature = "clipboard")]
-  fn clipboard_manager(&self) -> Self::ClipboardManager {
-    self.clipboard_manager_handle.clone()
-  }
-
   fn create_window(&self, pending: PendingWindow<T, Self>) -> Result<DetachedWindow<T, Self>> {
     let label = pending.label.clone();
     let menu_ids = pending.menu_ids.clone();
@@ -2155,8 +2110,6 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
     #[cfg(all(desktop, feature = "global-shortcut"))]
     let global_shortcut_manager_handle = self.global_shortcut_manager_handle.clone();
 
-    #[cfg(feature = "clipboard")]
-    let clipboard_manager = self.context.main_thread.clipboard_manager.clone();
     let mut iteration = RunIteration::default();
 
     let proxy = self.event_loop.create_proxy();
@@ -2183,8 +2136,6 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
               global_shortcut_manager: global_shortcut_manager.clone(),
               #[cfg(all(desktop, feature = "global-shortcut"))]
               global_shortcut_manager_handle: &global_shortcut_manager_handle,
-              #[cfg(feature = "clipboard")]
-              clipboard_manager: clipboard_manager.clone(),
               #[cfg(all(desktop, feature = "system-tray"))]
               system_tray_manager: system_tray_manager.clone(),
             },
@@ -2207,8 +2158,6 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
             global_shortcut_manager: global_shortcut_manager.clone(),
             #[cfg(all(desktop, feature = "global-shortcut"))]
             global_shortcut_manager_handle: &global_shortcut_manager_handle,
-            #[cfg(feature = "clipboard")]
-            clipboard_manager: clipboard_manager.clone(),
             #[cfg(all(desktop, feature = "system-tray"))]
             system_tray_manager: system_tray_manager.clone(),
           },
@@ -2233,9 +2182,6 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
     #[cfg(all(desktop, feature = "global-shortcut"))]
     let global_shortcut_manager_handle = self.global_shortcut_manager_handle.clone();
 
-    #[cfg(feature = "clipboard")]
-    let clipboard_manager = self.context.main_thread.clipboard_manager.clone();
-
     let proxy = self.event_loop.create_proxy();
 
     self.event_loop.run(move |event, event_loop, control_flow| {
@@ -2253,8 +2199,6 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
             global_shortcut_manager: global_shortcut_manager.clone(),
             #[cfg(all(desktop, feature = "global-shortcut"))]
             global_shortcut_manager_handle: &global_shortcut_manager_handle,
-            #[cfg(feature = "clipboard")]
-            clipboard_manager: clipboard_manager.clone(),
             #[cfg(all(desktop, feature = "system-tray"))]
             system_tray_manager: system_tray_manager.clone(),
           },
@@ -2276,8 +2220,6 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
           global_shortcut_manager: global_shortcut_manager.clone(),
           #[cfg(all(desktop, feature = "global-shortcut"))]
           global_shortcut_manager_handle: &global_shortcut_manager_handle,
-          #[cfg(feature = "clipboard")]
-          clipboard_manager: clipboard_manager.clone(),
           #[cfg(all(desktop, feature = "system-tray"))]
           system_tray_manager: system_tray_manager.clone(),
         },
@@ -2295,8 +2237,6 @@ pub struct EventLoopIterationContext<'a, T: UserEvent> {
   pub global_shortcut_manager: Arc<Mutex<WryShortcutManager>>,
   #[cfg(all(desktop, feature = "global-shortcut"))]
   pub global_shortcut_manager_handle: &'a GlobalShortcutManagerHandle<T>,
-  #[cfg(feature = "clipboard")]
-  pub clipboard_manager: Arc<Mutex<Clipboard>>,
   #[cfg(all(desktop, feature = "system-tray"))]
   pub system_tray_manager: SystemTrayManager,
 }
@@ -2306,8 +2246,6 @@ struct UserMessageContext {
   webview_id_map: WebviewIdStore,
   #[cfg(all(desktop, feature = "global-shortcut"))]
   global_shortcut_manager: Arc<Mutex<WryShortcutManager>>,
-  #[cfg(feature = "clipboard")]
-  clipboard_manager: Arc<Mutex<Clipboard>>,
   #[cfg(all(desktop, feature = "system-tray"))]
   system_tray_manager: SystemTrayManager,
 }
@@ -2322,8 +2260,6 @@ fn handle_user_message<T: UserEvent>(
     webview_id_map,
     #[cfg(all(desktop, feature = "global-shortcut"))]
     global_shortcut_manager,
-    #[cfg(feature = "clipboard")]
-    clipboard_manager,
     windows,
     #[cfg(all(desktop, feature = "system-tray"))]
     system_tray_manager,
@@ -2724,8 +2660,6 @@ fn handle_user_message<T: UserEvent>(
     Message::GlobalShortcut(message) => {
       handle_global_shortcut_message(message, &global_shortcut_manager)
     }
-    #[cfg(feature = "clipboard")]
-    Message::Clipboard(message) => handle_clipboard_message(message, &clipboard_manager),
     Message::UserEvent(_) => (),
   }
 
@@ -2750,8 +2684,6 @@ fn handle_event_loop<T: UserEvent>(
     global_shortcut_manager,
     #[cfg(all(desktop, feature = "global-shortcut"))]
     global_shortcut_manager_handle,
-    #[cfg(feature = "clipboard")]
-    clipboard_manager,
     #[cfg(all(desktop, feature = "system-tray"))]
     system_tray_manager,
   } = context;
@@ -2991,8 +2923,6 @@ fn handle_event_loop<T: UserEvent>(
             webview_id_map,
             #[cfg(all(desktop, feature = "global-shortcut"))]
             global_shortcut_manager,
-            #[cfg(feature = "clipboard")]
-            clipboard_manager,
             windows,
             #[cfg(all(desktop, feature = "system-tray"))]
             system_tray_manager,

+ 0 - 1
core/tauri-runtime/Cargo.toml

@@ -52,4 +52,3 @@ devtools = [ ]
 system-tray = [ ]
 macos-private-api = [ ]
 global-shortcut = [ ]
-clipboard = [ ]

+ 0 - 16
core/tauri-runtime/src/lib.rs

@@ -431,15 +431,6 @@ pub trait GlobalShortcutManager: Debug + Clone + Send + Sync {
   fn unregister(&mut self, accelerator: &str) -> Result<()>;
 }
 
-/// Clipboard manager.
-#[cfg(feature = "clipboard")]
-pub trait ClipboardManager: Debug + Clone + Send + Sync {
-  /// Writes the text into the clipboard as plain text.
-  fn write_text<T: Into<String>>(&mut self, text: T) -> Result<()>;
-  /// Read the content in the clipboard as plain text.
-  fn read_text(&self) -> Result<Option<String>>;
-}
-
 pub trait EventLoopProxy<T: UserEvent>: Debug + Clone + Send + Sync {
   fn send_event(&self, event: T) -> Result<()>;
 }
@@ -453,9 +444,6 @@ pub trait Runtime<T: UserEvent>: Debug + Sized + 'static {
   /// The global shortcut manager type.
   #[cfg(all(desktop, feature = "global-shortcut"))]
   type GlobalShortcutManager: GlobalShortcutManager;
-  /// The clipboard manager type.
-  #[cfg(feature = "clipboard")]
-  type ClipboardManager: ClipboardManager;
   /// The tray handler type.
   #[cfg(all(desktop, feature = "system-tray"))]
   type TrayHandler: menu::TrayHandle;
@@ -480,10 +468,6 @@ pub trait Runtime<T: UserEvent>: Debug + Sized + 'static {
   #[cfg(all(desktop, feature = "global-shortcut"))]
   fn global_shortcut_manager(&self) -> Self::GlobalShortcutManager;
 
-  /// Gets the clipboard manager.
-  #[cfg(feature = "clipboard")]
-  fn clipboard_manager(&self) -> Self::ClipboardManager;
-
   /// Create a new webview window.
   fn create_window(&self, pending: PendingWindow<T, Self>) -> Result<DetachedWindow<T, Self>>;
 

+ 2 - 3
core/tauri/Cargo.toml

@@ -161,7 +161,6 @@ global-shortcut = [
   "tauri-runtime/global-shortcut",
   "tauri-runtime-wry/global-shortcut"
 ]
-clipboard = [ "tauri-runtime/clipboard", "tauri-runtime-wry/clipboard" ]
 dialog = [ "rfd" ]
 notification = [ "notify-rust" ]
 system-tray = [ "tauri-runtime/system-tray", "tauri-runtime-wry/system-tray" ]
@@ -189,8 +188,8 @@ api-all = [
   "app-all"
 ]
 clipboard-all = [ "clipboard-write-text", "clipboard-read-text" ]
-clipboard-read-text = [ "clipboard" ]
-clipboard-write-text = [ "clipboard" ]
+clipboard-read-text = [ ]
+clipboard-write-text = [ ]
 dialog-all = [ "dialog-open", "dialog-save", "dialog-message", "dialog-ask" ]
 dialog-ask = [ "dialog" ]
 dialog-confirm = [ "dialog" ]

+ 0 - 5
core/tauri/src/lib.rs

@@ -27,7 +27,6 @@
 //! - **rustls-tls**: Provides TLS support to connect over HTTPS using rustls.
 //! - **process-command-api**: Enables the [`api::process::Command`] APIs.
 //! - **global-shortcut**: Enables the global shortcut APIs.
-//! - **clipboard**: Enables the clipboard APIs.
 //! - **process-relaunch-dangerous-allow-symlink-macos**: Allows the [`api::process::current_binary`] function to allow symlinks on macOS (this is dangerous, see the Security section in the documentation website).
 //! - **dialog**: Enables the [`api::dialog`] module.
 //! - **notification**: Enables the [`api::notification`] module.
@@ -313,10 +312,6 @@ pub use {
   scope::*,
 };
 
-#[cfg(feature = "clipboard")]
-#[cfg_attr(doc_cfg, doc(cfg(feature = "clipboard")))]
-pub use self::runtime::ClipboardManager;
-
 #[cfg(all(desktop, feature = "global-shortcut"))]
 #[cfg_attr(doc_cfg, doc(cfg(feature = "global-shortcut")))]
 pub use self::runtime::GlobalShortcutManager;

+ 1 - 36
core/tauri/src/test/mock_runtime.rs

@@ -39,14 +39,11 @@ type ShortcutMap = HashMap<String, Box<dyn Fn() + Send + 'static>>;
 #[derive(Clone)]
 pub struct RuntimeContext {
   shortcuts: Arc<Mutex<ShortcutMap>>,
-  clipboard: Arc<Mutex<Option<String>>>,
 }
 
 impl fmt::Debug for RuntimeContext {
   fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-    f.debug_struct("RuntimeContext")
-      .field("clipboard", &self.clipboard)
-      .finish()
+    f.debug_struct("RuntimeContext").finish()
   }
 }
 
@@ -173,24 +170,6 @@ impl tauri_runtime::GlobalShortcutManager for MockGlobalShortcutManager {
   }
 }
 
-#[cfg(feature = "clipboard")]
-#[derive(Debug, Clone)]
-pub struct MockClipboardManager {
-  context: RuntimeContext,
-}
-
-#[cfg(feature = "clipboard")]
-impl tauri_runtime::ClipboardManager for MockClipboardManager {
-  fn write_text<T: Into<String>>(&mut self, text: T) -> Result<()> {
-    self.context.clipboard.lock().unwrap().replace(text.into());
-    Ok(())
-  }
-
-  fn read_text(&self) -> Result<Option<String>> {
-    Ok(self.context.clipboard.lock().unwrap().clone())
-  }
-}
-
 #[derive(Debug, Clone)]
 pub struct MockWindowBuilder {}
 
@@ -648,8 +627,6 @@ pub struct MockRuntime {
   pub context: RuntimeContext,
   #[cfg(all(desktop, feature = "global-shortcut"))]
   global_shortcut_manager: MockGlobalShortcutManager,
-  #[cfg(feature = "clipboard")]
-  clipboard_manager: MockClipboardManager,
   #[cfg(all(desktop, feature = "system-tray"))]
   tray_handler: MockTrayHandler,
 }
@@ -658,17 +635,12 @@ impl MockRuntime {
   fn init() -> Self {
     let context = RuntimeContext {
       shortcuts: Default::default(),
-      clipboard: Default::default(),
     };
     Self {
       #[cfg(all(desktop, feature = "global-shortcut"))]
       global_shortcut_manager: MockGlobalShortcutManager {
         context: context.clone(),
       },
-      #[cfg(feature = "clipboard")]
-      clipboard_manager: MockClipboardManager {
-        context: context.clone(),
-      },
       #[cfg(all(desktop, feature = "system-tray"))]
       tray_handler: MockTrayHandler {
         context: context.clone(),
@@ -683,8 +655,6 @@ impl<T: UserEvent> Runtime<T> for MockRuntime {
   type Handle = MockRuntimeHandle;
   #[cfg(all(desktop, feature = "global-shortcut"))]
   type GlobalShortcutManager = MockGlobalShortcutManager;
-  #[cfg(feature = "clipboard")]
-  type ClipboardManager = MockClipboardManager;
   #[cfg(all(desktop, feature = "system-tray"))]
   type TrayHandler = MockTrayHandler;
   type EventLoopProxy = EventProxy;
@@ -713,11 +683,6 @@ impl<T: UserEvent> Runtime<T> for MockRuntime {
     self.global_shortcut_manager.clone()
   }
 
-  #[cfg(feature = "clipboard")]
-  fn clipboard_manager(&self) -> Self::ClipboardManager {
-    self.clipboard_manager.clone()
-  }
-
   fn create_window(&self, pending: PendingWindow<T, Self>) -> Result<DetachedWindow<T, Self>> {
     Ok(DetachedWindow {
       label: pending.label,

+ 1 - 7
examples/api/src/App.svelte

@@ -14,7 +14,6 @@
   import Shortcuts from './views/Shortcuts.svelte'
   import Shell from './views/Shell.svelte'
   import Updater from './views/Updater.svelte'
-  import Clipboard from './views/Clipboard.svelte'
   import WebRTC from './views/WebRTC.svelte'
   import App from './views/App.svelte'
 
@@ -95,11 +94,6 @@
       component: Updater,
       icon: 'i-codicon-cloud-download'
     },
-    !isMobile && {
-      label: 'Clipboard',
-      component: Clipboard,
-      icon: 'i-codicon-clippy'
-    },
     {
       label: 'WebRTC',
       component: WebRTC,
@@ -334,7 +328,7 @@
       </span>
       <span
         title="Close"
-        class="hover:bg-red-700 dark:hover:bg-red-700 hover:text-darkPrimaryText active:bg-red-700/90 dark:active:bg-red-700/90 active:text-darkPrimaryText  "
+        class="hover:bg-red-700 dark:hover:bg-red-700 hover:text-darkPrimaryText active:bg-red-700/90 dark:active:bg-red-700/90 active:text-darkPrimaryText"
         on:click={close}
       >
         <div class="i-codicon-chrome-close" />

+ 0 - 32
examples/api/src/views/Clipboard.svelte

@@ -1,32 +0,0 @@
-<script>
-  import { writeText, readText } from '@tauri-apps/api/clipboard'
-
-  export let onMessage
-  let text = 'clipboard message'
-
-  function write() {
-    writeText(text)
-      .then(() => {
-        onMessage('Wrote to the clipboard')
-      })
-      .catch(onMessage)
-  }
-
-  function read() {
-    readText()
-      .then((contents) => {
-        onMessage(`Clipboard contents: ${contents}`)
-      })
-      .catch(onMessage)
-  }
-</script>
-
-<div class="flex gap-1">
-  <input
-    class="grow input"
-    placeholder="Text to write to the clipboard"
-    bind:value={text}
-  />
-  <button class="btn" type="button" on:click={write}>Write</button>
-  <button class="btn" type="button" on:click={read}>Read</button>
-</div>