From 5d2f82dc330b8a0473a09eb0286f65bfbafd1ab5 Mon Sep 17 00:00:00 2001 From: HornedHeck <43969792+HornedHeck@users.noreply.github.com> Date: Tue, 28 Apr 2026 10:50:38 +0200 Subject: [PATCH 1/3] fix: Empty screen for signed user Ensure configuration fetch is finished before trying to use it. Signed-off-by: HornedHeck <43969792+HornedHeck@users.noreply.github.com> --- src/Client.ts | 38 +++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/src/Client.ts b/src/Client.ts index 3119525c..a7b16e85 100644 --- a/src/Client.ts +++ b/src/Client.ts @@ -199,6 +199,8 @@ export class Client extends AsyncEventEmitter { readonly connectionFailureCount: Accessor; #setConnectionFailureCount: Setter; #reconnectTimeout: number | undefined; + #configurationPromise: Promise | undefined; + #connectAttempt = 0; /** * Create Stoat.js Client @@ -253,7 +255,7 @@ export class Client extends AsyncEventEmitter { this.configured = configured; this.#setConfigured = setConfigured; - this.#fetchConfiguration(); + void this.#fetchConfiguration().catch((error) => this.emit("error", error)); const [ready, setReady] = createSignal(false); this.ready = ready; @@ -329,11 +331,24 @@ export class Client extends AsyncEventEmitter { * Connect to Revolt */ connect(): void { + void this.#connect().catch((error) => this.emit("error", error)); + } + + async #connect(): Promise { + const attempt = ++this.#connectAttempt; + clearTimeout(this.#reconnectTimeout); this.events.disconnect(); this.#setReady(false); + + await this.#fetchConfiguration(); + + if (attempt !== this.#connectAttempt) { + return; + } + this.events.connect( - this.configuration?.ws ?? "wss://stoat.chat/events", + this.configuration?.ws || "wss://stoat.chat/events", typeof this.#session === "string" ? this.#session : this.#session!.token, ); } @@ -342,10 +357,23 @@ export class Client extends AsyncEventEmitter { * Fetches the configuration of the server if it has not been already fetched. */ async #fetchConfiguration(): Promise { - if (!this.configuration) { - this.configuration = await this.api.get("/"); - this.#setConfigured(true); + if (this.configuration) { + return; } + + if (!this.#configurationPromise) { + this.#configurationPromise = this.api + .get("/") + .then((configuration) => { + this.configuration = configuration; + this.#setConfigured(true); + }) + .finally(() => { + this.#configurationPromise = undefined; + }); + } + + await this.#configurationPromise; } /** From bc042be9c14c9ce543951ae4591dbba1a312b3b4 Mon Sep 17 00:00:00 2001 From: HornedHeck <43969792+HornedHeck@users.noreply.github.com> Date: Thu, 30 Apr 2026 10:35:25 +0200 Subject: [PATCH 2/3] ref: Remove unnecessary void operator in fetchConfiguration Signed-off-by: HornedHeck <43969792+HornedHeck@users.noreply.github.com> --- src/Client.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Client.ts b/src/Client.ts index a7b16e85..ece18ac2 100644 --- a/src/Client.ts +++ b/src/Client.ts @@ -255,7 +255,7 @@ export class Client extends AsyncEventEmitter { this.configured = configured; this.#setConfigured = setConfigured; - void this.#fetchConfiguration().catch((error) => this.emit("error", error)); + this.#fetchConfiguration().catch((error) => this.emit("error", error)); const [ready, setReady] = createSignal(false); this.ready = ready; From 4bcd974adf6b5022d64159a284cfe1d62ae70513 Mon Sep 17 00:00:00 2001 From: HornedHeck <43969792+HornedHeck@users.noreply.github.com> Date: Thu, 7 May 2026 12:51:15 +0200 Subject: [PATCH 3/3] ref: Remove unneeded void Co-authored-by: Taureon <45183108+Taureon@users.noreply.github.com> Signed-off-by: HornedHeck <43969792+HornedHeck@users.noreply.github.com> --- src/Client.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Client.ts b/src/Client.ts index ece18ac2..bb3de279 100644 --- a/src/Client.ts +++ b/src/Client.ts @@ -331,7 +331,7 @@ export class Client extends AsyncEventEmitter { * Connect to Revolt */ connect(): void { - void this.#connect().catch((error) => this.emit("error", error)); + this.#connect().catch((error) => this.emit("error", error)); } async #connect(): Promise {