"use strict"; import { EventEmitter } from 'events'; import Connection from '../transport/Connection.mjs'; class Peer extends EventEmitter { get address() { return this.connection.address; } get port() { return this.connection.port; } get remote_endpoint() { return { address: this.address, port: this.port }; } constructor(server, connection) { super(); this.id = null; /** * The parent server this Peer is part of. * @type {PeerServer} */ this.server = server; /** * The underlying Connection. * @type {Connection} */ this.connection = connection; // Fetch the remote's id } /** * Accepts an existing connection as a new Peer. * @param {Connection} connection The Connection to accept. * @return {Promise} A Promise that resolves once the initial handshake is complete. */ __accept(connection) { return new Promise((resolve, reject) => { this.connection = connection; this.connection.on("message-request-id", (msg) => { this.connection.id = msg.my_id; this.connection.send("id", { my_id: this.server.our_id }) .then(resolve, reject); }); }); } /** * Initiates the handshake after opening a new connection. * @return {Promise} A Promise that resolves after the initial peer handshake is complete. */ __initiate() { return new Promise((resolve, reject) => { this.connection.send("request-id", { my_id: this.server.our_id }) .then(() => { this.connection.once("message-id", (msg) => { this.id = msg.my_id; this.emit("connect"); resolve(); }); }, reject); }); } async destroy() { await this.connection.destroy(); this.emit("destroy"); this.removeAllListeners(); } } Peer.Initiate = function(server, address, port) { const conn = await Connection.Create(server.secret_join, address, port); const peer = new Peer(server, conn); await peer.__initiate(); } Peer.Accept = function(server, connection) { const peer = new Peer(server); await peer.__accept(connection); } export default Peer;