@mothepro/fancy-p2p
Version:
A quick and efficient way to form p2p groups in the browser
76 lines (75 loc) • 3.28 kB
TypeScript
import { Emitter, Listener } from 'fancy-emitter';
import type { Name, LobbyID } from '@mothepro/signaling-lobby';
import { SimpleClient } from './Client.js';
import { MySimplePeer, Sendable } from './Peer.js';
/** Represent where we are in the process of connecting to some peers. */
export declare const enum State {
/** Still attempting to connect to the server. */
OFFLINE = 0,
/** We are now connected to the server in lobby, waiting to make a group or join a group. */
LOBBY = 1,
/** We have accepted a group and trying to make the RTCs. */
LOADING = 2,
/** The connections with peers are set and we can now broadcast messages. */
READY = 3
}
export default class<T extends Sendable = Sendable> {
readonly state: State;
/** Activated when the state changes, Cancels when finalized, Deactivates when error is throw. */
readonly stateChange: Emitter<State>;
/** Activated when a client joins the lobby. */
readonly lobbyConnection: Listener<SimpleClient>;
/** The peers who's connections are still open */
readonly peers: MySimplePeer<T>[];
/** Generator for random integers that will be consistent across connections within [-2 ** 31, 2 ** 31). */
private rng?;
private readonly server;
protected assert(valid: State, message?: string): true;
/**
* Generates a random number in [0,1), same as Math.random()
* If `isInt` is true, then an integer in range [-2 ** 31, 2 ** 31) is generated instead.
*
* `state` must be `State.READY`.
*/
readonly random: (isInt?: boolean) => number;
/**
* Propose a group with other clients connected to this lobby.
*
* `state` must be `State.LOBBY`.
*/
readonly proposeGroup: (...members: SimpleClient[]) => void;
/**
* Whether a group with the following memebers has been proposed or answered.
*
* `state` must be `State.LOBBY`.
*/
readonly groupExists: (...members: SimpleClient[]) => boolean;
/**
* Send data to all connected peers.
*
* `state` must be `State.READY`.
*/
readonly broadcast: (data: T, includeSelf?: boolean) => void;
constructor({ name, stuns, lobby, server: { address, version }, fallback, retries, timeout }: {
/** Name used to connect to lobby with */
name: Name;
/** STUN servers to use to initialize P2P connections */
stuns: string[];
/** Lobby ID to use for this app */
lobby: LobbyID;
/** Settings for the signaling server */
server: {
/** The address of the signaling server */
address: URL | string;
/** The version of `@mothepro/signaling-lobby` the signaling server is running */
version: string;
};
/** Whether to use the signaling server as a fallback when a direct connection to peer can not be established. */
fallback?: boolean;
/** Number of times to attempt to make an RTC connection, if negative direct p2p connections will not be attempted. Defaults to 1 */
retries?: number;
/** The number of milliseconds to wait before giving up on the connection. Doesn't give up by default */
timeout?: number;
});
private bindServerState;
}