/**
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @format
 */
import { SandyPluginDefinition } from './SandyPluginDefinition';
import { BasePluginInstance, BasePluginClient } from './PluginBase';
import { FlipperLib } from './FlipperLib';
import { Device } from './DevicePlugin';
import { Atom, ReadOnlyAtom } from '../state/atom';
import { ServerAddOnControls, EventsContract, MethodsContract } from 'flipper-common';
import type { FC } from 'react';
type PreventIntersectionWith<Contract extends Record<string, any>> = {
    [Key in keyof Contract]?: never;
};
type Message = {
    method: string;
    params?: any;
};
/**
 * API available to a plugin factory
 */
export interface PluginClient<Events extends EventsContract = {}, Methods extends MethodsContract = {}, ServerAddOnEvents extends EventsContract & PreventIntersectionWith<Events> = {}, ServerAddOnMethods extends MethodsContract & PreventIntersectionWith<Methods> = {}> extends BasePluginClient<ServerAddOnEvents, ServerAddOnMethods> {
    /**
     * Identifier that uniquely identifies the connected application
     */
    readonly appId: string;
    /**
     * Identifier that uniquely identifies the application bundle
     */
    readonly bundleId: string;
    /**
     * Registered name for the connected application
     */
    readonly appName: string;
    readonly isActivated: () => boolean;
    readonly isConnected: boolean;
    readonly connected: ReadOnlyAtom<boolean>;
    /**
     * the onConnect event is fired whenever the plugin is connected to it's counter part on the device.
     * For most plugins this event is fired if the user selects the plugin,
     * for background plugins when the initial connection is made.
     *
     * @returns an unsubscribe callback
     */
    onConnect(cb: () => void): () => void;
    /**
     * The counterpart of the `onConnect` handler.
     * Will also be fired before the plugin is cleaned up if the connection is currently active:
     * - when the client disconnects
     * - when the plugin is disabled
     *
     * @returns an unsubscribe callback
     */
    onDisconnect(cb: () => void): () => void;
    /**
     * Subscribe to a specific event arriving from the device.
     *
     * Messages can only arrive if the plugin is enabled and connected.
     * For background plugins messages will be batched and arrive the next time the plugin is connected.
     *
     * @returns an unsubscribe callback
     */
    onMessage<Event extends keyof Events>(event: Event, callback: (params: Events[Event]) => void): () => void;
    /**
     * Subscribe to all messages arriving from the devices not handled by another listener.
     *
     * This handler is untyped, and onMessage should be favored over using onUnhandledMessage if the event name is known upfront.
     *
     * @returns an unsubscribe callback
     */
    onUnhandledMessage(callback: (event: string, params: any) => void): () => void;
    /**
     * Send a message to the connected client
     */
    send<Method extends keyof Methods>(method: Method, params: Parameters<Methods[Method]>[0]): ReturnType<Methods[Method]>;
    /**
     * Checks if a method is available on the client implementation
     */
    supportsMethod(method: keyof Methods): Promise<boolean>;
    /**
     * opens a different plugin by id, optionally providing a deeplink to bring the plugin to a certain state
     */
    selectPlugin(pluginId: string, deeplinkPayload?: unknown): void;
}
/**
 * Internal API exposed by Flipper, and wrapped by FlipperPluginInstance to be passed to the
 * Plugin Factory. For internal purposes only
 */
export interface RealFlipperClient {
    id: string;
    connected: Atom<boolean>;
    query: {
        app: string;
        app_id?: string;
        os: string;
        device: string;
        device_id: string;
    };
    device: Device;
    plugins: Set<string>;
    isBackgroundPlugin(pluginId: string): boolean;
    initPlugin(pluginId: string): void;
    deinitPlugin(pluginId: string): void;
    call(api: string, method: string, fromPlugin: boolean, params?: Object): Promise<Object>;
    supportsMethod(api: string, method: string): Promise<boolean>;
}
export type PluginFactory<Events extends EventsContract, Methods extends MethodsContract, ServerAddOnEvents extends EventsContract & PreventIntersectionWith<Events>, ServerAddOnMethods extends MethodsContract & PreventIntersectionWith<Methods>> = (client: PluginClient<Events, Methods, ServerAddOnEvents, ServerAddOnMethods>) => object;
export type FlipperPluginComponent = FC<{}>;
export declare class SandyPluginInstance extends BasePluginInstance {
    static is(thing: any): thing is SandyPluginInstance;
    /** base client provided by Flipper */
    readonly realClient: RealFlipperClient;
    /** client that is bound to this instance */
    readonly client: PluginClient<any, any, any, any>;
    /** connection alive? */
    readonly connected: Atom<boolean>;
    constructor(serverAddOnControls: ServerAddOnControls, flipperLib: FlipperLib, definition: SandyPluginDefinition, realClient: RealFlipperClient, pluginKey: string, initialStates?: Record<string, any>);
    activate(): void;
    deactivate(): void;
    connect(): void;
    disconnect(): void;
    destroy(): void;
    receiveMessages(messages: Message[]): void;
    toJSON(): string;
    protected get serverAddOnOwner(): string;
    private assertConnected;
}
export {};
//# sourceMappingURL=Plugin.d.ts.map