From 3b99cb7d4c4e1fd0e0eacedd01ab39f139ff7bdc Mon Sep 17 00:00:00 2001 From: Jon Staab Date: Wed, 3 Sep 2025 17:31:19 -0700 Subject: [PATCH] Fix throttle function, add retryAuth --- packages/lib/__tests__/Tools.test.ts | 15 ++++++--------- packages/lib/src/Tools.ts | 5 +++-- packages/net/src/auth.ts | 16 ++++++++++++++-- 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/packages/lib/__tests__/Tools.test.ts b/packages/lib/__tests__/Tools.test.ts index dec66a9..a1d02b9 100644 --- a/packages/lib/__tests__/Tools.test.ts +++ b/packages/lib/__tests__/Tools.test.ts @@ -147,14 +147,14 @@ describe("Tools", () => { batchFn("b") batchFn("c") - await vi.advanceTimersByTimeAsync(100) + await vi.advanceTimersByTimeAsync(300) // Second batch batchFn("d") batchFn("e") batchFn("f") - await vi.advanceTimersByTimeAsync(100) + await vi.advanceTimersByTimeAsync(110) expect(processBatch).toHaveBeenCalledTimes(4) expect(processBatch).toHaveBeenCalledWith(["a"]) @@ -233,11 +233,10 @@ describe("Tools", () => { // Subsequent calls within throttle window should return cached value expect(throttledGet()).toBe(1) - expect(throttledGet()).toBe(1) expect(getValue).toHaveBeenCalledTimes(1) // After throttle window, should update value - await vi.advanceTimersByTimeAsync(100) + await vi.advanceTimersByTimeAsync(300) // the previous 2 called will have been batched, and the next throttledGet increase the counter to 3 expect(throttledGet()).toBe(3) expect(getValue).toHaveBeenCalledTimes(3) @@ -253,17 +252,15 @@ describe("Tools", () => { // Multiple calls within window for (let i = 0; i < 4; i++) { - throttledGet() + expect(throttledGet()).toBe(1) await vi.advanceTimersByTimeAsync(20) // 20ms each, still within 100ms window } expect(getValue).toHaveBeenCalledTimes(1) - // After window await vi.advanceTimersByTimeAsync(100) - // the previous called will have been batched, and the next throttledGet increase the counter to 3 - expect(throttledGet()).toBe(3) - expect(getValue).toHaveBeenCalledTimes(3) + expect(throttledGet()).toBe(2) + expect(getValue).toHaveBeenCalledTimes(2) }) it("should handle zero throttle time", () => { diff --git a/packages/lib/src/Tools.ts b/packages/lib/src/Tools.ts index 68044ae..40b6e0b 100644 --- a/packages/lib/src/Tools.ts +++ b/packages/lib/src/Tools.ts @@ -1109,9 +1109,10 @@ export const throttle = any>(ms: number, f: F) => if (nextArgs) { f(...nextArgs) nextArgs = undefined + setTimeout(unpause, ms) + } else { + paused = false } - - paused = false } return (...thisArgs: Parameters) => { diff --git a/packages/net/src/auth.ts b/packages/net/src/auth.ts index 31fada5..595dbb6 100644 --- a/packages/net/src/auth.ts +++ b/packages/net/src/auth.ts @@ -29,6 +29,8 @@ export type AuthStateEvents = { [AuthStateEvent.Status]: (status: AuthStatus) => void } +type Sign = (event: StampedEvent) => Promise + export class AuthState extends EventEmitter { challenge: string | undefined request: string | undefined @@ -89,7 +91,7 @@ export class AuthState extends EventEmitter { this.emit(AuthStateEvent.Status, status) } - async doAuth(sign: (event: StampedEvent) => Promise) { + async doAuth(sign: Sign) { if (!this.challenge) { throw new Error("Attempted to authenticate with no challenge") } @@ -111,7 +113,7 @@ export class AuthState extends EventEmitter { } } - async attemptAuth(sign: (event: StampedEvent) => Promise) { + async attemptAuth(sign: Sign) { this.socket.attemptToOpen() if (![AuthStatus.Forbidden, AuthStatus.Ok].includes(this.status)) { @@ -131,6 +133,16 @@ export class AuthState extends EventEmitter { } } + async retryAuth(sign: Sign) { + if (this.challenge) { + this.request = undefined + this.details = undefined + this.setStatus(AuthStatus.Requested) + } + + await this.attemptAuth(sign) + } + cleanup() { this.removeAllListeners() this._unsubscribers.forEach(call)