pub fn plugin_with_client_privilege<D: Any + Send + Sync>(
        mut self,
        // This is a function to preserve a similar API interface with `.plugin()`
        plugin: impl Fn() -> Plugin<D> + Send + Sync,
        plugin_data: D,
    ) -> Self {
        let plugin = plugin();
        // If the plugin doesn't need client privileges, it shouldn't have them (even
        // though this is just a semantic thing)
        if plugin.env == PluginEnv::Server {
            panic!("attempted to register plugin that doesn't ever run on the client with `.plugin_with_client_privilege()`, you should use `.plugin()` instead")
        }
        // Insert the plugin data
        let plugin_data: Box<dyn Any + Send + Sync> = Box::new(plugin_data);
        let res = self.plugin_data.insert(plugin.name.clone(), plugin_data);
        // If there was an old value, there are two plugins with the same name, which is
        // very bad (arbitrarily inconsistent behavior overriding)
        if res.is_some() {
            panic!("two plugins have the same name '{}', which could lead to arbitrary and inconsistent behavior modification (please file an issue with the plugin that doesn't have the same name as its crate)", &plugin.name);
        }
        // Register functional and control actions using the plugin's provided registrar
        self.functional_actions = (plugin.functional_actions_registrar)(self.functional_actions);
        self.control_actions = (plugin.control_actions_registrar)(self.control_actions);

        self
    }
The same as `.plugin()`, but registers a plugin that can run on the
client-side. This is deliberately separated out to make conditional
compilation feasible and to emphasize to users what's increasing their
bundle sizes. Note that this should also be used for plugins that
run on both the client and server.
packages/perseus/src/plugins/plugins_list.rs