@@ -189,7 +189,8 @@ export class Client extends AsyncEventEmitter<Events> {
189189 readonly options : ClientOptions ;
190190 readonly events : EventClient < 1 > ;
191191
192- configuration : RevoltConfig | undefined ;
192+ readonly configuration : RevoltConfig | undefined ;
193+ #configLock?: Promise < void > ;
193194 #session: Session | undefined ;
194195 user : User | undefined ;
195196
@@ -203,8 +204,10 @@ export class Client extends AsyncEventEmitter<Events> {
203204 #setConnectionFailureCount: Setter < number > ;
204205 #reconnectTimeout: number | undefined ;
205206 #slowmodeTimers = new Map < string , ReturnType < typeof setTimeout > > ( ) ;
207+
206208 /**
207209 * Create Stoat.js Client
210+ * @param configuration Deprecated - Please use `Client.initConfig` if you need to override config.
208211 */
209212 constructor ( options ?: Partial < ClientOptions > , configuration ?: RevoltConfig ) {
210213 super ( ) ;
@@ -256,8 +259,6 @@ export class Client extends AsyncEventEmitter<Events> {
256259 this . configured = configured ;
257260 this . #setConfigured = setConfigured ;
258261
259- this . #fetchConfiguration( ) ;
260-
261262 const [ ready , setReady ] = createSignal ( false ) ;
262263 this . ready = ready ;
263264 this . #setReady = setReady ;
@@ -343,13 +344,28 @@ export class Client extends AsyncEventEmitter<Events> {
343344 }
344345
345346 /**
346- * Fetches the configuration of the server if it has not been already fetched.
347+ * Fetches the server config. This is called automatically by `login()` or `loginBot()`,
348+ * but you can call it first manually if you need to override any config options.
349+ *
350+ * Override example:
351+ * ```ts
352+ * await client.initConfig((config) => {
353+ * config.ws = "wss://example.com";
354+ * });
355+ * ```
347356 */
348- async #fetchConfiguration( ) : Promise < void > {
349- if ( ! this . configuration ) {
350- this . configuration = await this . api . get ( "/" ) ;
351- this . #setConfigured( true ) ;
357+ async initConfig ( preConfig ?: ( config : RevoltConfig ) => void ) : Promise < void > {
358+ if ( ! this . #configLock && ! this . configuration ) {
359+ //Create promise lock to avoid race condition
360+ this . #configLock = ( async ( ) => {
361+ //@ts -expect-error readonly override
362+ this . configuration = await this . api . get ( "/" ) ;
363+ preConfig ?.( this . configuration ) ;
364+ this . #setConfigured( true ) ;
365+ this . #configLock = undefined ;
366+ } ) ( ) ;
352367 }
368+ return this . #configLock;
353369 }
354370
355371 /**
@@ -370,7 +386,7 @@ export class Client extends AsyncEventEmitter<Events> {
370386 * @returns An on-boarding function if on-boarding is required, undefined otherwise
371387 */
372388 async login ( details : DataLogin ) : Promise < void > {
373- await this . #fetchConfiguration ( ) ;
389+ await this . initConfig ( ) ;
374390 const data = await this . api . post ( "/auth/session/login" , details ) ;
375391 if ( data . result === "Success" ) {
376392 this . #session = data ;
@@ -393,7 +409,7 @@ export class Client extends AsyncEventEmitter<Events> {
393409 * @param token Bot token
394410 */
395411 async loginBot ( token : string ) : Promise < void > {
396- await this . #fetchConfiguration ( ) ;
412+ await this . initConfig ( ) ;
397413 this . #session = token ;
398414 this . #updateHeaders( ) ;
399415 this . connect ( ) ;
@@ -614,10 +630,6 @@ export class Client extends AsyncEventEmitter<Events> {
614630 * Backend enforced limits for the logged in user
615631 */
616632 get limits ( ) : UserLimits | undefined {
617- if ( ! this . configured ( ) || ! this . user ) {
618- return ;
619- }
620-
621- return this . user . limits ;
633+ if ( this . configured ( ) && this . user ) return this . user . limits ;
622634 }
623635}
0 commit comments