Repository: tauri-apps/tauri
File: core/tauri/src/command/authority.rs (Rust)

Code before:
          "global scope not available for app commands"
        ))
      })
      .and_then(|plugin| {
        command
          .message
          .webview
          .manager()
          .runtime_authority
          .scope_manager
          .get_global_scope_typed(command.message.webview.app_handle(), plugin)
          .map_err(InvokeError::from_error)
      })
      .map(GlobalScope)
  }
}

#[derive(Debug)]
pub struct ScopeManager {
  command_scope: BTreeMap<ScopeKey, ResolvedScope>,
  global_scope: BTreeMap<String, ResolvedScope>,
  command_cache: BTreeMap<ScopeKey, TypeMap![Send + Sync]>,
  global_scope_cache: TypeMap![Send + Sync],
}

/// Marks a type as an scope object.
///
/// Usually you will just rely on [`serde::de::DeserializeOwned`] instead of implementing it manually,
/// though this is useful if you need to do some initialization logic on the type itself.
pub trait ScopeObject: Sized + Send + Sync + Debug + 'static {
  /// The error type.
  type Error: std::error::Error;
  /// Deserialize the raw scope value.
  fn deserialize<R: Runtime>(app: &AppHandle<R>, raw: Value) -> Result<Self, Self::Error>;
}

impl<T: Send + Sync + Debug + DeserializeOwned + 'static> ScopeObject for T {
  type Error = serde_json::Error;
  fn deserialize<R: Runtime>(_app: &AppHandle<R>, raw: Value) -> Result<Self, Self::Error> {
    serde_json::from_value(raw.into())
  }
}

impl ScopeManager {
  pub(crate) fn get_global_scope_typed<R: Runtime, T: ScopeObject>(
    &self,
    app: &AppHandle<R>,
    plugin: &str,
  ) -> crate::Result<&ScopeValue<T>> {
    match self.global_scope_cache.try_get() {
      Some(cached) => Ok(cached),

Review comment (suggestion):
```suggestion
/// Marks a type as a scope object.
```

Code after:
          "global scope not available for app commands"
        ))
      })
      .and_then(|plugin| {
        command
          .message
          .webview
          .manager()
          .runtime_authority
          .scope_manager
          .get_global_scope_typed(command.message.webview.app_handle(), plugin)
          .map_err(InvokeError::from_error)
      })
      .map(GlobalScope)
  }
}

#[derive(Debug)]
pub struct ScopeManager {
  command_scope: BTreeMap<ScopeKey, ResolvedScope>,
  global_scope: BTreeMap<String, ResolvedScope>,
  command_cache: BTreeMap<ScopeKey, TypeMap![Send + Sync]>,
  global_scope_cache: TypeMap![Send + Sync],
}

/// Marks a type as a scope object.
///
/// Usually you will just rely on [`serde::de::DeserializeOwned`] instead of implementing it manually,
/// though this is useful if you need to do some initialization logic on the type itself.
pub trait ScopeObject: Sized + Send + Sync + Debug + 'static {
  /// The error type.
  type Error: std::error::Error;
  /// Deserialize the raw scope value.
  fn deserialize<R: Runtime>(app: &AppHandle<R>, raw: Value) -> Result<Self, Self::Error>;
}

impl<T: Send + Sync + Debug + DeserializeOwned + 'static> ScopeObject for T {
  type Error = serde_json::Error;
  fn deserialize<R: Runtime>(_app: &AppHandle<R>, raw: Value) -> Result<Self, Self::Error> {
    serde_json::from_value(raw.into())
  }
}

impl ScopeManager {
  pub(crate) fn get_global_scope_typed<R: Runtime, T: ScopeObject>(
    &self,
    app: &AppHandle<R>,
    plugin: &str,
  ) -> crate::Result<&ScopeValue<T>> {
    match self.global_scope_cache.try_get() {
      Some(cached) => Ok(cached),