diff --git a/index.js b/index.js index 748fe92..7a53b1e 100644 --- a/index.js +++ b/index.js @@ -358,7 +358,66 @@ module.exports = class Protomux { return info ? info.opened > 0 : false; } - async createChannel({ + _createChannel({ + userData = null, + protocol, + aliases = [], + id = null, + unique = true, + handshake = null, + messages = [], + onopen = noop, + onclose = noop, + ondestroy = noop, + }) { + if (this.stream.destroyed) return null; + + const info = this._get(protocol, id, aliases); + if (unique && info.opened > 0) return null; + + if (info.incoming.length === 0) { + return new Channel( + this, + info, + userData, + protocol, + aliases, + id, + handshake, + messages, + onopen, + onclose, + ondestroy + ); + } + + this._remoteBacklog--; + + const remoteId = info.incoming.shift(); + const r = this._remote[remoteId - 1]; + if (r === null) return null; + + const session = new Channel( + this, + info, + userData, + protocol, + aliases, + id, + handshake, + messages, + onopen, + onclose, + ondestroy + ); + + session._remoteId = remoteId; + session._fullyOpenSoon(); + + return session; + } + + async _createChannelAsync({ userData = null, protocol, aliases = [], @@ -422,6 +481,14 @@ module.exports = class Protomux { return session; } + createChannel(options) { + if (this._slave) { + return this._createChannelAsync(options); + } + + return this._createChannel(options); + } + _pushBatch(localId, buffer) { if (this._batchState.end >= MAX_BATCH) { this._sendBatch(this._batch, this._batchState); @@ -463,7 +530,43 @@ module.exports = class Protomux { this.stream.write(state.buffer); } - async _get(protocol, id, aliases = []) { + _get(protocol, id, aliases = []) { + if (this._slave) { + return this._getAsync(protocol, id, aliases); + } + + return this.__get(protocol, id, aliases); + } + + async __get(protocol, id, aliases) { + const key = toKey(protocol, id); + + let info = this._infos.get(key); + if (info) return info; + + info = { + key, + protocol, + aliases: [], + id, + pairing: 0, + opened: 0, + incoming: [], + outgoing: [], + }; + this._infos.set(key, info); + + for (const alias of aliases) { + const key = toKey(alias, id); + info.aliases.push(key); + + this._infos.set(key, info); + } + + return info; + } + + async _getAsync(protocol, id, aliases = []) { const key = toKey(protocol, id); await this.pullInfos();