Fix throttle function, add retryAuth

This commit is contained in:
Jon Staab
2025-09-03 17:31:19 -07:00
parent f009801c84
commit 3b99cb7d4c
3 changed files with 23 additions and 13 deletions
+6 -9
View File
@@ -147,14 +147,14 @@ describe("Tools", () => {
batchFn("b") batchFn("b")
batchFn("c") batchFn("c")
await vi.advanceTimersByTimeAsync(100) await vi.advanceTimersByTimeAsync(300)
// Second batch // Second batch
batchFn("d") batchFn("d")
batchFn("e") batchFn("e")
batchFn("f") batchFn("f")
await vi.advanceTimersByTimeAsync(100) await vi.advanceTimersByTimeAsync(110)
expect(processBatch).toHaveBeenCalledTimes(4) expect(processBatch).toHaveBeenCalledTimes(4)
expect(processBatch).toHaveBeenCalledWith(["a"]) expect(processBatch).toHaveBeenCalledWith(["a"])
@@ -233,11 +233,10 @@ describe("Tools", () => {
// Subsequent calls within throttle window should return cached value // Subsequent calls within throttle window should return cached value
expect(throttledGet()).toBe(1) expect(throttledGet()).toBe(1)
expect(throttledGet()).toBe(1)
expect(getValue).toHaveBeenCalledTimes(1) expect(getValue).toHaveBeenCalledTimes(1)
// After throttle window, should update value // 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 // the previous 2 called will have been batched, and the next throttledGet increase the counter to 3
expect(throttledGet()).toBe(3) expect(throttledGet()).toBe(3)
expect(getValue).toHaveBeenCalledTimes(3) expect(getValue).toHaveBeenCalledTimes(3)
@@ -253,17 +252,15 @@ describe("Tools", () => {
// Multiple calls within window // Multiple calls within window
for (let i = 0; i < 4; i++) { for (let i = 0; i < 4; i++) {
throttledGet() expect(throttledGet()).toBe(1)
await vi.advanceTimersByTimeAsync(20) // 20ms each, still within 100ms window await vi.advanceTimersByTimeAsync(20) // 20ms each, still within 100ms window
} }
expect(getValue).toHaveBeenCalledTimes(1) expect(getValue).toHaveBeenCalledTimes(1)
// After window
await vi.advanceTimersByTimeAsync(100) await vi.advanceTimersByTimeAsync(100)
// the previous called will have been batched, and the next throttledGet increase the counter to 3 expect(throttledGet()).toBe(2)
expect(throttledGet()).toBe(3) expect(getValue).toHaveBeenCalledTimes(2)
expect(getValue).toHaveBeenCalledTimes(3)
}) })
it("should handle zero throttle time", () => { it("should handle zero throttle time", () => {
+3 -2
View File
@@ -1109,10 +1109,11 @@ export const throttle = <F extends (...args: any[]) => any>(ms: number, f: F) =>
if (nextArgs) { if (nextArgs) {
f(...nextArgs) f(...nextArgs)
nextArgs = undefined nextArgs = undefined
} setTimeout(unpause, ms)
} else {
paused = false paused = false
} }
}
return (...thisArgs: Parameters<F>) => { return (...thisArgs: Parameters<F>) => {
if (!paused) { if (!paused) {
+14 -2
View File
@@ -29,6 +29,8 @@ export type AuthStateEvents = {
[AuthStateEvent.Status]: (status: AuthStatus) => void [AuthStateEvent.Status]: (status: AuthStatus) => void
} }
type Sign = (event: StampedEvent) => Promise<SignedEvent>
export class AuthState extends EventEmitter { export class AuthState extends EventEmitter {
challenge: string | undefined challenge: string | undefined
request: string | undefined request: string | undefined
@@ -89,7 +91,7 @@ export class AuthState extends EventEmitter {
this.emit(AuthStateEvent.Status, status) this.emit(AuthStateEvent.Status, status)
} }
async doAuth(sign: (event: StampedEvent) => Promise<SignedEvent>) { async doAuth(sign: Sign) {
if (!this.challenge) { if (!this.challenge) {
throw new Error("Attempted to authenticate with no 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<SignedEvent>) { async attemptAuth(sign: Sign) {
this.socket.attemptToOpen() this.socket.attemptToOpen()
if (![AuthStatus.Forbidden, AuthStatus.Ok].includes(this.status)) { 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() { cleanup() {
this.removeAllListeners() this.removeAllListeners()
this._unsubscribers.forEach(call) this._unsubscribers.forEach(call)