diff --git a/dist/index.d.ts b/dist/index.d.ts index fd27383..bb8090c 100644 --- a/dist/index.d.ts +++ b/dist/index.d.ts @@ -7,6 +7,7 @@ export default class HyperswarmWeb extends EventEmitter { private _activeRelay; private _discovery; private _queuedEmActions; + private _connectionMutex; constructor(opts?: any); ready(): Promise; private ensureConnection; diff --git a/dist/index.d.ts.map b/dist/index.d.ts.map index 704820b..19e5ebb 100644 --- a/dist/index.d.ts.map +++ b/dist/index.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,OAAO,MAAM,uBAAuB,CAAC;AAW5C,OAAO,UAAU,MAAM,YAAY,CAAC;AAEpC,OAAO,YAAY,MAAM,eAAe,CAAC;AAEzC,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,YAAY;IACrD,OAAO,CAAC,QAAQ,CAAM;IACtB,OAAO,CAAC,OAAO,CAA0B;IACzC,OAAO,CAAC,YAAY,CAAa;IACjC,OAAO,CAAC,UAAU,CAAsB;IACxC,OAAO,CAAC,gBAAgB,CAAuB;gBACnC,IAAI,GAAE,GAAQ;IAO1B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAIR,gBAAgB;YA0DhB,iBAAiB;IAYzB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC;IAQ7D,IAAI,MAAM,IAAI,MAAM,EAAE,CAErB;IAEY,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI7C,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAUpC,WAAW,IAAI,IAAI;IAI1B,EAAE,CACA,SAAS,EAAE,MAAM,GAAG,MAAM,EAC1B,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,GACjC,UAAU;IAGb,WAAW,CACT,SAAS,EAAE,MAAM,GAAG,MAAM,EAC1B,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,GACjC,IAAI;IAIP,GAAG,CACD,SAAS,EAAE,MAAM,GAAG,MAAM,EAC1B,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,GACjC,UAAU;IAIb,cAAc,CACZ,SAAS,EAAE,MAAM,GAAG,MAAM,EAC1B,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,GACjC,IAAI;IAGP,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO;IAIzD,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,GAAG,IAAI;IAI1E,OAAO,CAAC,qBAAqB;IAS7B,OAAO,CAAC,qBAAqB;CAO9B"} \ No newline at end of file +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,OAAO,MAAM,uBAAuB,CAAC;AAW5C,OAAO,UAAU,MAAM,YAAY,CAAC;AAEpC,OAAO,YAAY,MAAM,eAAe,CAAC;AAGzC,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,YAAY;IACrD,OAAO,CAAC,QAAQ,CAAM;IACtB,OAAO,CAAC,OAAO,CAA0B;IACzC,OAAO,CAAC,YAAY,CAAa;IACjC,OAAO,CAAC,UAAU,CAAsB;IACxC,OAAO,CAAC,gBAAgB,CAAuB;IAE/C,OAAO,CAAC,gBAAgB,CAAsB;gBAClC,IAAI,GAAE,GAAQ;IAO1B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAIR,gBAAgB;YAiEhB,iBAAiB;IAYzB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC;IAQ7D,IAAI,MAAM,IAAI,MAAM,EAAE,CAErB;IAEY,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI7C,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAUpC,WAAW,IAAI,IAAI;IAI1B,EAAE,CACA,SAAS,EAAE,MAAM,GAAG,MAAM,EAC1B,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,GACjC,UAAU;IAGb,WAAW,CACT,SAAS,EAAE,MAAM,GAAG,MAAM,EAC1B,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,GACjC,IAAI;IAIP,GAAG,CACD,SAAS,EAAE,MAAM,GAAG,MAAM,EAC1B,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,GACjC,UAAU;IAIb,cAAc,CACZ,SAAS,EAAE,MAAM,GAAG,MAAM,EAC1B,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,GACjC,IAAI;IAGP,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO;IAIzD,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,GAAG,IAAI;IAI1E,OAAO,CAAC,qBAAqB;IAS7B,OAAO,CAAC,qBAAqB;CAO9B"} \ No newline at end of file diff --git a/dist/index.js b/dist/index.js index 6b6af89..6b6ebad 100644 --- a/dist/index.js +++ b/dist/index.js @@ -8,12 +8,14 @@ import { load } from "@lumeweb/libkernel-universal"; import Hyperswarm from "hyperswarm"; import randomNumber from "random-number-csprng"; import EventEmitter from "eventemitter2"; +import { Mutex } from "async-mutex"; export default class HyperswarmWeb extends EventEmitter { _options; _relays = new Set(); _activeRelay; _discovery; _queuedEmActions = []; + _connectionMutex = new Mutex(); constructor(opts = {}) { super(); opts.custodial = false; @@ -25,45 +27,51 @@ export default class HyperswarmWeb extends EventEmitter { } async ensureConnection() { const logErr = (await load()).logErr; + await this._connectionMutex.waitForUnlock(); + this._connectionMutex.acquire(); if (this._activeRelay) { return; } const relays = this.relays; - do { - const index = relays.length > 1 ? await randomNumber(0, relays.length - 1) : 0; - const relay = relays[index]; - let ret; - try { - ret = await this._discovery.discover(relay); - } - catch (e) { - logErr(e); - relays.splice(index, 1); - continue; - } - if (!ret) { - relays.splice(index, 1); - continue; - } - ret = ret; - const connection = `wss://${ret.host}:${ret.port}`; - if (!(await this.isServerAvailable(connection))) { - relays.splice(index, 1); - continue; - } - this._activeRelay = new Hyperswarm({ - dht: new DhtNode(new Stream(true, new WebSocket(connection)), this._options), - keyPair: this._options.keyPair, - }); - this._activeRelay.on("close", () => { - this._activeRelay = undefined; - }); - } while (relays.length > 0 && !this._activeRelay); + if (relays.length > 0) { + do { + const index = relays.length > 1 ? await randomNumber(0, relays.length - 1) : 0; + const relay = relays[index]; + let ret; + try { + ret = await this._discovery.discover(relay); + } + catch (e) { + logErr(e); + relays.splice(index, 1); + continue; + } + if (!ret) { + relays.splice(index, 1); + continue; + } + ret = ret; + const connection = `wss://${ret.host}:${ret.port}`; + if (!(await this.isServerAvailable(connection))) { + relays.splice(index, 1); + continue; + } + this._activeRelay = new Hyperswarm({ + dht: new DhtNode(new Stream(true, new WebSocket(connection)), this._options), + keyPair: this._options.keyPair, + }); + this._activeRelay.on("close", () => { + this._activeRelay = undefined; + }); + } while (relays.length > 0 && !this._activeRelay); + } if (!this._activeRelay) { + this._connectionMutex.release(); throw new Error("Failed to find an available relay"); } this._processQueuedActions(); await this._activeRelay.dht.ready(); + this._connectionMutex.release(); } async isServerAvailable(connection) { return new Promise((resolve) => {