import type OpenFin from '@openfin/core';
import { RegistrationMetaInfo } from '../../client-api/src/index';
export type { RegistrationMetaInfo };
/**
 * Create a topic.
 * If the OpenFin identity creating the topic is running in a platform, the search topic will be sandboxed to the platform.
 * In order to subscribe to a sandboxed search topic, the UUID of the platform must be specified explicitly or the subscribing OpenFin identity must be running in the platform.
 * @param req the topic create request.
 */
export declare const create: () => Promise<SearchTopic>;
/**
 * Subscribe to an existing search topic.
 * @param req the subscribe request.
 */
export declare const subscribe: () => Promise<SearchTopicClient>;
/**
 * Search API object that is injected in the window.
 */
export type SearchAPI = {
    create: typeof create;
    subscribe: typeof subscribe;
};
/**
 * A response to a search from a search provider.
 */
export interface SearchProviderResponse {
    /**
     * The search provider that responded with the search results.
     */
    provider: SearchProviderInfo;
    /**
     * If the search result succeeds for this provider, results of the search will be set.
     */
    results?: SearchResult[];
    /**
     * A context with custom data to pass through search
     */
    context?: any;
    /**
     * If the search failed for this provider, error will be set.
     */
    error?: Error;
}
/**
 * The search request.
 */
export interface SearchRequest {
    /**
     * The search query.
     */
    query: string;
    /**
     * Additional custom context that can be used for searching.
     */
    context?: any;
    /**
     * A list of search provider names to execute the search request against.
     */
    targets?: string[];
}
/**
 * A generator that returns search responses from all providers that have currently responded.
 *
 * More documentation on Javascript Generators can be found [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator).
 */
export type SearchProviderResponseGenerator = AsyncGenerator<SearchProviderResponse[], SearchProviderResponse[], SearchProviderResponse[]>;
/**
 * Describes the state of the search response generator.
 */
export declare enum SearchProviderResponseGeneratorState {
    /**
     * The generator is in the process of fetching the initial set of results from search providers.
     */
    Fetching = "fetching",
    /**
     * The generator has fetched all initial results, and is now waiting for search providers with
     * open {@link SearchListenerResponse} streams to push new or updated search results.
     */
    Fetched = "fetched",
    /**
     * All open {@link SearchListenerResponse} streams have closed, completing the request.
     * In this state, the set of responses returned by `generator.next()` are final.
     */
    Complete = "complete"
}
/**
 * Extended search provider response generator with additional properties about the search request.
 */
export interface SearchProviderResponseGeneratorExtended extends SearchProviderResponseGenerator {
    /**
     * The id of the search request.
     */
    id: string;
    /**
     * The state of the search provider response generator.
     */
    state: SearchProviderResponseGeneratorState;
    /**
     * Notifies all search providers related to this search request
     * that the search requester is no longer listening for new or updated search results.
     * @experimental
     */
    close: () => void;
}
/**
 * Called when a remote OpenFin identity, such as a view, attempts to connect
 * to the search topic.
 *
 * Returning false will reject said request.
 *
 * ```js
 *  const allowedHosts = ["www.company.com"];
 *  searchTopic.onSubscription(identity => {
 *   const info = await fin.View.wrapSync(identity).getInfo();
 *   const url = new URL(info.url);
 *
 *   return allowedHosts.includes(url.host);
 * });
 * ```
 */
export type SubscriptionListener = (identity: OpenFin.Identity) => Promise<boolean>;
/**
 * Called when a remote OpenFin identity, such as a view, disconnects from a Search topic.
 */
export type DisconnectListener = (identity: OpenFin.Identity) => Promise<void>;
/**
 * Called when search provider deregisters from SearchTopic
 */
export type DeregisterListener = () => void | Promise<void>;
/**
 * Called when search provider registers to SearchTopic
 */
export type RegisterListener = (searchProvider?: SearchProviderInfo) => void | Promise<void>;
/**
 * The client returned from subscribing as a secondary node to a search topic, which is managed by a primary node.
 * Can be used to interact with a search topic.
 */
export interface SearchTopicClient {
    /**
     * Obtain information about all search providers listening in on the topic.
     */
    getAllProviders(): Promise<SearchProviderInfo[]>;
    /**
     * Execute a search on the search topic.
     *
     * The generator returned by this function can be called multiple times, returning the current list of search provider responses.
     * As more search providers respond to the search request the returned list of responses will grow in length.
     *
     * When all the search providers have responded to the search request, the generator will return the final
     * set of search response under the `value` attribute and set the 'done' attribute set to true.
     *
     * If no targets are included in request, will search against all search providers.
     * @param request the request object that contains parameters to base the search on.
     *
     * @experimental
     */
    search(request: SearchRequest): Promise<SearchProviderResponseGeneratorExtended>;
    /**
     * Register a search provider.
     * @param provider the search provider to register.
     */
    register(provider: SearchProvider): Promise<RegistrationMetaInfo>;
    /**
     * Deregister a search provider by its name.
     * @param name the name of the search provider to deregister
     */
    deregister(name: string): Promise<void>;
    /**
     * Dispatch a search result back to the search provider.
     * It is then the search providers duty to perform what ever action was chosen.
     * @param providerId the id of the search provider to send the search result back to.
     * @param result the search result to send back to the search provider.
     * @param action the action for the search provider to perform with the search result.
     * @param identity optionally provide the identity of the dispatcher, otherwise the current identity will be used.
     */
    dispatch(providerId: string, result: SearchResult, action: Action, identity?: OpenFin.Identity): Promise<any>;
    /**
     * Disconnect from the search topic.
     * NOTE: All search providers registered by this search client will be deregistered.
     */
    disconnect(): Promise<void>;
    /** The channel client for the search topic. */
    channel: OpenFin.ChannelClient;
}
/**
 * A search topic created by the primary node.
 */
export interface SearchTopic extends Omit<SearchTopicClient, 'channel'> {
    /**
     * Add a subscription listener that will be called when ever a search client subscribes
     * to this topic.
     *
     * Returning false in said listener will reject the request.
     * @param listener the listener to add.
     */
    onSubscription(listener: SubscriptionListener): void;
    /**
     * Remove a listener.
     * @param listener the listener to remove.
     */
    removeListener(listener: (...args: any[]) => any): void;
    /**
     * Add a listener that will be called when ever a search client disconnects from this topic.
     * @param listener the listener to add.
     */
    onDisconnect(listener: DisconnectListener): void;
    /**
     * Add a listener that will be called whenever a search provider registers
     * @param listener the listener to add
     */
    onRegister(listener: RegisterListener): void;
    /**
     * Add a listener that will be called whenever a search provider deregisters
     * @param listener the listener to add.
     */
    onDeregister(listener: DeregisterListener): void;
    /** The channel provider for the search topic. */
    channel: OpenFin.ChannelProvider;
}
/**
 * Information about a search provider.
 */
export interface SearchProviderInfo {
    /**
     * A unique ID used to identify the search provider.
     */
    id: string;
    /**
     * A UI friendly title for the search provider.
     */
    title: string;
    /**
     * A placeholder text that would be put into the empty search field for the selected provider for home in landing mode.
     */
    inputLandingPlaceholder?: string;
    /**
     * The OpenFin identity that registered this search provider.
     */
    identity?: OpenFin.Identity;
    /**
     * The order to sort the score in. The default is `ascending`.
     * @experimental
     */
    scoreOrder?: ScoreOrder;
    /**
     * A keycode that can be used to interact with this Search Provider.
     */
    commandCode?: string;
    /**
     * A short description of the Search Provider.
     */
    description?: string;
    /**
     * An icon that a UI can display for the Search Provider.
     */
    icon: string;
    /**
     * A flag to indicate this provider will not be displayed as a command.
     */
    hidden?: boolean;
    /**
     * A title to display above the result list in a UI when targeting this specific Search Provider.
     */
    listTitle?: string;
    /**
     * The placeholder string to be displayed in a UI when targeting this specific Search Provider.
     */
    inputPlaceholder?: string;
    /**
     * Logo to show render when targeting this specific Search Provider.
     */
    logoUrl?: string;
    /**
     * If set, focusing on a search result will trigger onResultDispatch callback.
     */
    dispatchFocusEvents?: boolean;
    /**
     *  version of client SDK,  set by the API
     */
    clientAPIVersion?: string;
    /**
     * Optional subheader configuration for the home landing page.
     */
    subHeader?: {
        /**
         * First title text to display in the subheader.
         */
        title1?: string;
        /**
         * Second title text to display in the subheader (renders on a new line).
         */
        title2?: string;
        /**
         * Subtitle text to display in the subheader.
         */
        subtitle?: string;
        /**
         * URL of the icon to display in the subheader.
         */
        icon?: string;
    };
}
/**
 * The order to sort scored search results in.
 */
export type ScoreOrder = 'ascending' | 'descending';
/**
 * The reason which triggered the search result dispatch callback.
 */
export declare enum ActionTrigger {
    /**
     * The search result dispatch was triggered with a regular user action (click, hotkey, etc.)
     */
    UserAction = "user-action",
    /**
     * The search result was dispatched back because the user has focused on another search result.
     */
    FocusChange = "focus-change",
    /**
     * The search result was dispatched back because there was a load error and the user requested a reload.
     */
    Reload = "reload"
}
/**
 * Each action is defined by its title and a hotkey
 */
export type Action = {
    name: string;
    hotkey?: string;
};
export declare enum SearchTagBackground {
    Active = "active",
    Default = "default"
}
export interface SearchTag {
    name: string;
    background: SearchTagBackground;
}
/**
 * Common properties of a {@link SearchResult | search result}.
 */
export interface SearchResult<A extends Action = Action> {
    /**
     * A unique ID for the search result.
     * Can be used to update a previously returned search result by calling
     * `searchRequestContext.respond(result)` with the same search result key.
     */
    key: string;
    /**
     * UI friendly name for the search result.
     */
    title: string;
    /**
     * Unused.
     * @experimental
     */
    description?: string;
    /**
     * Unused.
     * @experimental
     */
    shortDescription?: string;
    /**
     * An optional icon that can be used when displaying the search result in a UI.
     */
    icon?: string;
    /**
     * Used when sorting a list of search results for a single provider.
     * @experimental
     */
    score?: number;
    /**
     * Additional custom metadata about the search result.
     * Can be used when actioning the search result.
     */
    data?: any;
    /**
     * Actions that can be performed with this search result.
     * Used when dispatching search results back to the respective provider.
     */
    actions: A[];
    /**
     * Tags associated with the search result.
     */
    tags?: SearchTag[];
    /**
     * A label to render with the search result.
     */
    label?: string;
}
/**
 * Representation of a search request passed as a parameter to a {@link SearchProvider | SearchProvider's} `onUserInput` listener function.
 *
 * ```js
 * const provider = {
 *    name: "my-provider",
 *    title: "My Provider",
 *    onUserInput: (request) => {
 *       const query = request.query;
 *       return getMyResults(query);
 *    }
 * };
 * ```
 */
export interface SearchListenerRequest extends SearchRequest {
    /**
     * The ID of the search request.
     * Can be used to tie related search requests together between providers.
     */
    id: string;
    /**
     * Registers a listener that is called when the search request is
     * closed by the search requester.
     *
     * Can be used to cleanup pending queries:
     * ```js
     * async function onUserInput(request) {
     *   const myQuery = makeQuery(request.query);
     *
     *   request.onClose(() => {
     *      myQuery.cancel();
     *   });
     *
     *   const results = await myQuery.getResults();
     *   return { results };
     * }
     * ```
     *
     * @param listener the listener to call when the request is closed.
     */
    onClose(listener: () => void): void;
    /**
     * Remove a registered listener.
     *
     * ```ts
     *
     * function myListener(request, listener) {
     *     // Do something
     * }
     *
     * request.removeListener(myListener);
     * ```
     * @param listener the listener to remove.
     */
    removeListener(listener: () => void): void;
}
/**
 * Representation of a search response from a specific invocation of a {@link SearchProvider | SearchProvider's} `onUserInput` listener function.
 * Can optionally be used to push search results to the requester.
 *
 * ```js
 * function onUserInput(searchListenerRequest, searchListenerResponse) {
 *    searchListenerResponse.open();
 *
 *    const myLongRunningQuery = makeMyLongRunningQuery(searchListenerRequest.query);
 *    myLongRunningQuery.onNewResults(myNewResults => {
 *       searchListenerResponse.respond(myNewResults);
 *    });
 *
 *    searchListenerRequest.onClose(() => {
 *       myLongRunningQuery.close();
 *    });
 * }
 * ```
 */
export interface SearchListenerResponse {
    /**
     * Open the response stream, notifying the search requester that
     * there are new or updated search results that have yet to be pushed
     * by the current provider.
     * @experimental
     *
     * ```ts
     * import type { SearchListenerResponse } from './my-shape-definition';
     * function openStream(response:SearchListenerResponse) {
     *      response.open();
     * }
     *
     * openStream();
     * ```
     */
    open(): void;
    /**
     * Close the response stream.
     * This notifies the requester that the current search provider is done sending results.
     *
     * ```ts
     * import type { SearchListenerResponse } from './my-shape-definition';
     * function closeStream(request:SearchListenerRequest, response:SearchListenerResponse) {
     *      response.close();
     * }
     *
     * closeStream();
     * ```
     * @experimental
     */
    close(): void;
    /**
     * Respond to the search request with new or updated search results.
     *
     * ```ts
     *
     * response.respond([
     *      { name: 'result-1' },
     *      { name: 'result-2' },
     *      { name: 'result-3' },
     * ]);
     *
     * ```
     *
     * @param results new or updated search results to respond with.
     * @experimental
     */
    respond(results: SearchResult[]): void;
    /**
     * Remove a search result from the list of responded search results.
     *
     * ```ts
     * response.revoke({ name: 'result-1' }, { name: 'result-2' });
     * ```
     * @param resultKeys the keys of the search results to revoke.
     * @experimental
     */
    revoke(...resultKeys: string[]): void;
    /**
     * Respond to the search request with new or updated search results context.
     * @param context The new or updated search result context to respond with.
     */
    updateContext(context: any): void;
}
/**
 * An object resolved from 'onUserInput' function containing results and optional context
 */
export interface SearchResponse {
    results: SearchResult[];
    context?: any;
}
/**
 * A function that listens for search requests on a search topic.
 * Returns a set of search results based on arguments provided.
 * @param request - The search request coming in
 * @param response - EXPERIMENTAL - streaming response
 */
export type UserInputListener = (request: SearchListenerRequest, response: SearchListenerResponse) => Promise<SearchResponse>;
/**
 * The triggered action that should be performed by the search provider.
 */
export type DispatchedAction = Action & {
    trigger: ActionTrigger;
};
/**
 * A search result that has been dispatched back to the {@link SearchProvider | SearchProvider's} `onResultDispatch` listener function.
 * Contains the action that should be performed by the search provider.
 *
 * ```js
 * const provider = {
 *    name: "my-provider",
 *    title: "My Provider",
 *    onUserInput: myOnUserInput,
 *    onResultDispatch: (dispatchedSearchResult) => {
 *       if (dispatchedSearchResult.action.name === "my-action") {
 *          doMyAction(dispatchedSearchResult);
 *       }
 *    }
 * };
 * ```
 */
export interface DispatchedSearchResult extends SearchResult {
    /**
     * The selected action for the search provider to perform.
     */
    action: DispatchedAction;
    /**
     * The OpenFin identity that dispatched this search result.
     */
    dispatcherIdentity: OpenFin.Identity;
}
/**
 * A listener called when a search result generated by this provider is dispatched.
 *
 * ```js
 * searchTopic.dispatch("My Provider Name", searchResult, "My Action");
 * ```
 */
export type ResultDispatchListener = (result: DispatchedSearchResult) => void;
/**
 * A search provider listens for search requests on a search topic and returns search results.
 * It optionally can also perform custom actions when a search result is dispatched back to the provider.
 */
export interface SearchProvider extends SearchProviderInfo {
    /**
     * The search listener for the search provider.
     *
     * When a search is requested on the subscribed search topic, this
     * listener will be called and have the opportunity to return search results.
     */
    onUserInput: UserInputListener;
    /**
     * An optional listener for actioning search results.
     *
     * When this search provider returns search results via its `onUserInput` listener,
     * the receiver of the results can select and dispatch a single result back to the provider.
     *
     * It is then up to the search provider to perform the custom requested action.
     */
    onResultDispatch?: ResultDispatchListener;
}
