diff --git a/lib/plugin-hub-client.js b/lib/plugin-hub-client.js index 44d2584..65d7e74 100644 --- a/lib/plugin-hub-client.js +++ b/lib/plugin-hub-client.js @@ -28,112 +28,111 @@ const HUBS_SUBDOMAIN = 'hubs' * @typedef {(...args: [Error] | [null, T]) => void } CB */ -module.exports = { - name: 'hubClient', - needs: ['shse', 'net', 'set'], - manifest: { - connect: 'duplex', - }, - permissions: { - anonymous: { - allow: ['connect'], - }, - }, +/** + * @param {Peer} peer + * @param {any} config + */ +function initHubClient(peer, config) { + const hubs = new Map() - /** - * @param {Peer} peer - * @param {any} config - */ - init(peer, config) { - const hubs = new Map() + peer.multiserver.transport({ + name: 'tunnel', + create: makeTunnelPlugin(hubs, peer), + }) - peer.multiserver.transport({ - name: 'tunnel', - create: makeTunnelPlugin(hubs, peer), - }) - - // Setup discoveredAttendants source pull-stream - const _notifyDiscoveredAttendant = Notify() - function discoveredAttendants() { - return _notifyDiscoveredAttendant.listen() - } + // Setup discoveredAttendants source pull-stream + const _notifyDiscoveredAttendant = Notify() + function discoveredAttendants() { + return _notifyDiscoveredAttendant.listen() + } + // @ts-ignore + peer.close.hook(function (fn, args) { + _notifyDiscoveredAttendant?.end() // @ts-ignore - peer.close.hook(function (fn, args) { - _notifyDiscoveredAttendant?.end() - // @ts-ignore - fn.apply(this, args) - }) + fn.apply(this, args) + }) - return { - /** - * @param {`/${string}`} multiaddr - * @param {CB} cb - */ - addHub(multiaddr, cb) { - peer.set.add(HUBS_SUBDOMAIN, multiaddr, (err, _) => { + return { + /** + * @param {`/${string}`} multiaddr + * @param {CB} cb + */ + addHub(multiaddr, cb) { + peer.set.add(HUBS_SUBDOMAIN, multiaddr, (err, _) => { + // prettier-ignore + if (err) return cb(new Error('Failed to add Hub to my Set feed', {cause: err})) + peer.net.connect(multiaddr, (err, rpc) => { // prettier-ignore - if (err) return cb(new Error('Failed to add Hub to my Set feed', {cause: err})) - peer.net.connect(multiaddr, (err, rpc) => { - // prettier-ignore - if (err) return cb(new Error('Failed to connect to Hub after adding it to my Set feed', {cause: err})) - cb(null, void 0) - }) + if (err) return cb(new Error('Failed to connect to Hub after adding it to my Set feed', {cause: err})) + cb(null, void 0) }) - }, + }) + }, - /** - * @param {number} amount - * @param {CB>} cb - */ - getHubs(amount, cb) { - const source = peer.net.peers() - source(null, (err, peers) => { - if (err === true || !peers) return cb(null, []) - // prettier-ignore - if (err) return cb(new Error('Failed to get hubs', { cause: err })) - // @ts-ignore - const infoMap = /**@type {Map<`/${string}`, Info>}*/ (new Map(peers)) - const multiaddrs = peer.set.values(HUBS_SUBDOMAIN) - const hubs = [] - for (const multiaddr of multiaddrs) { - const stats = infoMap.get(multiaddr)?.stats ?? { failure: 1 } - hubs.push({ multiaddr, stats }) - } - hubs.sort((a, b) => (a.stats.failure ?? 1) - (b.stats.failure ?? 1)) - hubs.splice(amount) - const returnable = hubs.map((h) => h.multiaddr) - cb(null, returnable) - }) - }, - - /** - * @param {string} origin - * @returns {import('pull-stream').Duplex} - */ - connect(origin) { + /** + * @param {number} amount + * @param {CB>} cb + */ + getHubs(amount, cb) { + const source = peer.net.peers() + source(null, (err, peers) => { + if (err === true || !peers) return cb(null, []) + // prettier-ignore + if (err) return cb(new Error('Failed to get hubs', { cause: err })) // @ts-ignore - const hub = this.shse.pubkey - debug('received hubClient.connect(%s) via hub %s', origin, hub) - if (hubs.has(hub) && origin) { - debug('connect() will resolve because handler exists') - const handler = hubs.get(hub).handler - const [ins, outs] = DuplexPair() - handler(ins, origin) - return outs - } else { - return ErrorDuplex(`Could not connect to ${origin} via ${hub}`) + const infoMap = /**@type {Map<`/${string}`, Info>}*/ (new Map(peers)) + const multiaddrs = peer.set.values(HUBS_SUBDOMAIN) + const hubs = [] + for (const multiaddr of multiaddrs) { + const stats = infoMap.get(multiaddr)?.stats ?? { failure: 1 } + hubs.push({ multiaddr, stats }) } - }, + hubs.sort((a, b) => (a.stats.failure ?? 1) - (b.stats.failure ?? 1)) + hubs.splice(amount) + const returnable = hubs.map((h) => h.multiaddr) + cb(null, returnable) + }) + }, - // Internal method, needed for api-plugin.ts - getHubsMap() { - return hubs - }, + /** + * @param {string} origin + * @returns {import('pull-stream').Duplex} + */ + connect(origin) { + // @ts-ignore + const hub = this.shse.pubkey + debug('received hubClient.connect(%s) via hub %s', origin, hub) + if (hubs.has(hub) && origin) { + debug('connect() will resolve because handler exists') + const handler = hubs.get(hub).handler + const [ins, outs] = DuplexPair() + handler(ins, origin) + return outs + } else { + return ErrorDuplex(`Could not connect to ${origin} via ${hub}`) + } + }, - discoveredAttendants, + // Internal method, needed for api-plugin.ts + getHubsMap() { + return hubs + }, - // underscore so other modules IN THIS LIBRARY can use it - _notifyDiscoveredAttendant, - } + discoveredAttendants, + + // underscore so other modules IN THIS LIBRARY can use it + _notifyDiscoveredAttendant, + } +} + +exports.name = 'hubClient' +exports.init = initHubClient +exports.needs = ['shse', 'net', 'set'] +exports.manifest = { + connect: 'duplex', +} +exports.permissions = { + anonymous: { + allow: ['connect'], }, } diff --git a/package.json b/package.json index e3a7ff3..99b3b94 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,9 @@ "exports": { ".": { "require": "./lib/index.js" + }, + "./plugin": { + "require": "./lib/plugin-hub-client.js" } }, "type": "commonjs",