import IPostMessage from '../IPostMessage';
import { BroadcastedValueMessage, ClosedMessage, StatusMessage } from './syncMessages';
import { StatusEvent } from './syncEvents';
import ISync from './ISync';
/**
 * The `SyncEngine` enum defines the available synchronization engines that can be used to synchronize devices.
 * Each engine has its own method of connecting devices and synchronizing data.
 */
export declare enum SyncEngine {
    /** Use external sync server. Device will connect to the server via websocket. */
    SyncServer = "sync-server",
    /** Synchronize directly with other devices in the local network via UDP and TCP. */
    P2PLocal = "p2p-local",
    /**
     * Synchronize directly with other devices in the local network via UDP.
     * @deprecated use {@link P2PLocal}
     */
    Udp = "udp"
}
/**
 * Options for sync-server synchronization.
 */
export interface ConnectSyncServerOptions {
    engine?: SyncEngine.SyncServer;
    uri?: string;
}
/**
 * Options for P2P local synchronization.
 */
export interface ConnectP2PLocalOptions {
    engine: SyncEngine.P2PLocal;
}
/** @deprecated use SyncEngine.P2PLocal and ConnectP2PLocalOptions */
export interface ConnectUdpOptions {
    engine: SyncEngine.Udp;
}
type SynchronizationEngineOptions = ConnectSyncServerOptions | ConnectP2PLocalOptions | ConnectUdpOptions;
/**
 * The `sos.sync` API groups together methods for synchronization of multiple devices. Devices are synchronized either through an external
 * server or one of the devices becomes a master device.
 */
export default class Sync implements ISync {
    private messagePrefix;
    private postMessage;
    static MESSAGE_PREFIX: string;
    private static DEFAULT_GROUP_NAME;
    private eventEmitter;
    /** @internal */
    constructor(messagePrefix: string, postMessage: IPostMessage<any>);
    /**
     * The `connect()` method initializes the device and connects it to the rest of the devices. This initializes the connection and is
     * mandatory to call, since synchronization is an optional feature and doesn’t get initialized by default to save resources and bandwidth.
     * You can optionally specify a custom sync server URI in case you are running the sync server in a custom location.
     *
     * :::info
     * All devices, that should be synchronized together, must select the same engine. Otherwise, they won't be able to communicate with each
     * other.
     * :::
     *
     * @param options.engine {SynchronizationEngineOptions} Synchronization engine to use.
     * @param options.uri Address of the sync server engine. Only relevant for sync-server. If omitted, the default server will be used.
     * @returns {Promise<void>} A promise that resolves when the connection is established.
     * @throws Error If unable to connect.
     * @throws Error If the `uri` is not a valid URL when using the sync-server engine.
     * @throws Error If the `engine` is not a valid synchronization engine.
     * @throws Error If any other error occurs during connection.
     * @since 5.7.0
     *
     * @example // {@link https://github.com/signageos/applet-examples/tree/master/examples/content-js-api/sync-video | How to use synchronizer in applet}
     * @example // {@link https://github.com/signageos/applet-examples/tree/master/examples/content-js-api/sync-mixed-content | How to synchronize mixed content}
     * @example
     * // use default engine
     * await sos.sync.connect();
     *
     * // use sync-server engine and default server
     * await sos.sync.connect({ engine: 'sync-server' });
     *
     * // use sync-server engine and custom server
     * await sos.sync.connect({ engine: 'sync-server', uri: syncServerUri });
     *
     * // use p2p-local engine
     * await sos.sync.connect({ engine: 'p2p-local' });
     */
    connect(options?: SynchronizationEngineOptions): Promise<void>;
    /**
     * @internal
     * @deprecated Use `connect({ engine: 'sync-server' })` instead.
     *
     * @since 1.0.32
     */
    connect(options?: string): Promise<void>;
    /**
     * The `close()` method disconnects the device from synchronization server and other devices. Recommended to call this method after the
     * synchronization is not required any longer.
     *
     * @returns {Promise<void>} A promise that resolves when the connection is closed.
     * @throws Error If unable to close the connection.
     * @since 1.0.32
     */
    close(): Promise<void>;
    /**
     * @deprecated use `sos.sync.joinGroup()` instead.
     * @since 1.0.32
     */
    init(groupName?: string, deviceIdentification?: string): Promise<void>;
    /**
     * The `joinGroup()` method joins a group of other devices. This method has to be called after `connect()` call. Before any communication
     * takes place, all participating devices have to be connected and recognize one another. Recommended to call this method early.
     *
     * @param options Options for joining a group.
     * @returns {Promise<void>} A promise that resolves when the device joins the group.
     * @throws Error If the group name is not a string.
     * @throws Error If the device identification is not a string.
     * @throws Error If unable to join the group.
     * @throws Error If any other error occurs during joining the group.
     * @since 5.7.0
     *
     * @example // {@link https://github.com/signageos/applet-examples/tree/master/examples/content-js-api/sync-video | How to use synchronizer in applet}
     * @example
     * await sos.sync.connect();
     * await sos.sync.joinGroup({ groupName: 'my-group', deviceIdentification: 'my-device-id' });
     */
    joinGroup(options: {
        groupName?: string;
        deviceIdentification?: string;
    }): Promise<void>;
    /**
     * The `leaveMethod` method leaves a group of devices.
     *
     * @param groupName The name of the group to leave. Defaults to the default group.
     * @returns {Promise<void>} A promise that resolves when the device leaves the group.
     * @throws Error If the group name is not a string.
     * @throws Error If unable to leave the group.
     * @throws Error If any other error occurs during leaving the group.
     * @since 5.7.0
     *
     * @example
     * await sos.sync.leaveGroup('my-group');
     */
    leaveGroup(groupName?: string): Promise<void>;
    /**
     * The `wait()` method synchronizes with other devices by waiting for other devices before proceeding.
     *
     * One way to synchronize devices is to make them wait for each other at a certain moment. This would be most commonly used before the
     * device hits “play” on a video, to make it wait for other devices so they all start playing the video at the same time.
     *
     * This method returns a promise that resolves once all the devices meet and are ready to continue together. Any action that results in
     * visible synchronized behavior should be triggered immediately after and any related background preparations should be called before to
     * prevent delays.
     *
     * Sometimes devices might go out of sync due to unpredictable conditions like loss of internet connection. To ensure re-sync of an out of
     * sync device, you can pass some data as the first argument. This can be any data that informs the whole group about what content is
     * about to play next. Once all devices are ready, data from the master device is passed to everyone and the rest of the data is ignored.
     * Therefore, when implementing your applet you should rely on the result data and not the data that is passed to the wait method as an
     * argument.
     *
     * @param data Optional data to pass to the group.
     * @param groupName The name of the group to wait for. Defaults to the default group.
     * @param timeout Timeout in milliseconds. If not specified, the default timeout is 30 seconds.
     * @returns {Promise<any>} A promise that resolves with the data from the master device when all devices are ready to continue.
     * @throws Error If the group name is not a string.
     * @throws Error If the timeout is not a number.
     * @throws Error If unable to wait for the group.
     * @throws Error If any other error occurs during waiting for the group.
     * @since 1.0.32
     *
     * @example
     * // wait for all devices in the group to be ready
     * await sos.sync.wait('someData', 'someRandomNameGroup').then((data) => {
     *     // this will be called once all devices are ready
     *     console.log('All devices are ready with data:', data);
     * });
     */
    wait(data?: any, groupName?: string, timeout?: number): Promise<any>;
    /**
     * The `cancelWait()` method aborts a wait on all devices in a group. Sometimes it's necessary to cancel a pending wait. One such
     * situation would be when the group has to make a sudden change in content or another behavior but there's a risk that part of the group
     * already called wait() and is waiting for the rest but the rest will never call it at this point. In order to gracefully clean up any
     * pending activity, use this method.
     *
     * :::warning
     * Any pending wait will be canceled and the promise will be rejected with an error.
     * :::
     *
     * @param groupName The name of the group to cancel the wait for. Defaults to the default group.
     * @returns {Promise<void>} A promise that resolves when the wait is canceled.
     * @throws Error If the group name is not a string.
     * @throws Error If unable to cancel the wait.
     * @throws Error If any other error occurs during canceling the wait.
     * @since 5.12.0
     *
     * @example
     * sos.sync.wait('someData', 'someRandomNameGroup').catch((err) => {
     *     // this will happen once cancelWait is called
     *     console.error('wait failed', err);
     * });
     *
     * // this will cause above wait promise to reject
     * await sos.sync.cancelWait('someRandomNameGroup');
     */
    cancelWait(groupName?: string): Promise<void>;
    /**
     * @deprecated use `sos.sync.broadcastValue()` instead.
     * @since 2.0.0
     */
    setValue(key: string, value: any, groupName?: string): Promise<void>;
    /**
     * The `broadcastValue()` method sends a key-value pair to all other devices in a specified group.
     *
     * @param groupName {String} The name of the group to broadcast the value to. Defaults to the default group.
     * @param key {String} The key to broadcast the value under.
     * @param value {any} The value to broadcast. It can be any valid type
     * @returns {Promise<void>} A promise that resolves when the value is broadcasted.
     * @throws Error If the group name is not a string.
     * @throws Error If the key is not a string.
     * @throws Error If the value is not a valid type (e.g. object, array, etc.).
     * @throws Error If unable to broadcast the value.
     * @throws Error If the value can't be sent
     * @since 5.7.0
     *
     * @example
     * // broadcast a value to all devices in the group
     * await sos.sync.broadcastValue({
     * 	groupName: 'my-group',
     * 	key: 'my-key',
     * 	value: 'my-value',
     * });
     *
     * // Received on the other devices:
     * sos.sync.onValue((key, value, groupName) => {
     * 	console.log(`Received value for key ${key} in group ${groupName}:`, value);
     * });
     *
     */
    broadcastValue({ groupName, key, value }: {
        groupName?: string;
        key: string;
        value: any;
    }): Promise<void>;
    /**
     * Returns true if the device is currently the master of the group.
     *
     * @param groupName The group name to check for master status. Defaults to the default group.
     * @return {Promise<boolean>} A promise that resolves with true if the device is the master, false otherwise.
     * @since 6.7.0
     */
    isMaster(groupName?: string): Promise<boolean>;
    /**
     * The `onValue()` method sets up a listener, which is called whenever the device receives a broadcasted message.
     *
     * @param listener The listener function to call when a value is broadcasted.
     * @returns {void} Returns when listener is set up.
     * @throws Error If the listener is not a function.
     * @since 2.0.0
     */
    onValue(listener: (key: string, value: any, groupName?: string) => void): void;
    /**
     * The `onStatus()` method sets up a listener, which is called periodically or whenever there is a change (i.e. new device
     * connects/disconnects to/from the group).
     *
     * @param listener The listener function to call when the status changes.
     * @returns {void} Returns when listener is set up.
     * @throws Error If the listener is not a function.
     * @since 2.1.0
     */
    onStatus(listener: (status: StatusEvent) => void): void;
    /**
     * The `onClosed()` method sets up a listener, which is called whenever the device is disconnected from the sync. If it closed because
     * `close()` was called, it will emit without any arguments. if it closed because of an error, it will emit with an error object as the
     * first argument.
     *
     * @param listener The listener function to call when the sync is closed.
     * @returns {void} Returns when listener is set up.
     * @throws Error If the listener is not a function.
     * @since 5.12.0
     */
    onClosed(listener: (error?: Error) => void): void;
    /**
     * The `removeEventListeners()` method removes all listeners set up on `sos.sync` object.
     *
     * @since 2.0.0
     */
    removeEventListeners(): void;
    /** @internal */
    handleMessageData(data: BroadcastedValueMessage | StatusMessage | ClosedMessage): void;
    private getMessage;
}
export {};
