Skip to content

Commit a7497e4

Browse files
committed
fix(ramps-controller): clear LOADING state when request is aborted
1 parent d6678e1 commit a7497e4

File tree

2 files changed

+46
-4
lines changed

2 files changed

+46
-4
lines changed

packages/ramps-controller/src/RampsController.test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,30 @@ describe('RampsController', () => {
325325
});
326326
});
327327

328+
it('clears LOADING state from requests cache when aborted', async () => {
329+
await withController(async ({ controller }) => {
330+
const fetcher = async (signal: AbortSignal): Promise<string> => {
331+
return new Promise<string>((_resolve, reject) => {
332+
signal.addEventListener('abort', () => {
333+
reject(new Error('Aborted'));
334+
});
335+
});
336+
};
337+
338+
const requestPromise = controller.executeRequest('abort-key', fetcher);
339+
340+
expect(controller.state.requests['abort-key']?.status).toBe(
341+
RequestStatus.LOADING,
342+
);
343+
344+
controller.abortRequest('abort-key');
345+
346+
expect(controller.state.requests['abort-key']).toBeUndefined();
347+
348+
await expect(requestPromise).rejects.toThrow('Aborted');
349+
});
350+
});
351+
328352
it('throws if fetch completes after abort signal is triggered', async () => {
329353
await withController(async ({ controller }) => {
330354
const fetcher = async (signal: AbortSignal): Promise<string> => {

packages/ramps-controller/src/RampsController.ts

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -297,11 +297,27 @@ export class RampsController extends BaseController<
297297
if (pending) {
298298
pending.abortController.abort();
299299
this.#pendingRequests.delete(cacheKey);
300+
this.#removeRequestState(cacheKey);
300301
return true;
301302
}
302303
return false;
303304
}
304305

306+
/**
307+
* Removes a request state from the cache.
308+
*
309+
* @param cacheKey - The cache key to remove.
310+
*/
311+
#removeRequestState(cacheKey: string): void {
312+
this.update((state) => {
313+
const requests = state.requests as unknown as Record<
314+
string,
315+
RequestState | undefined
316+
>;
317+
delete requests[cacheKey];
318+
});
319+
}
320+
305321
/**
306322
* Gets the state of a specific cached request.
307323
*
@@ -322,8 +338,10 @@ export class RampsController extends BaseController<
322338
const maxSize = this.#requestCacheMaxSize;
323339

324340
this.update((state) => {
325-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
326-
const requests = state.requests as any;
341+
const requests = state.requests as unknown as Record<
342+
string,
343+
RequestState | undefined
344+
>;
327345
requests[cacheKey] = requestState;
328346

329347
// Evict oldest entries if cache exceeds max size
@@ -332,8 +350,8 @@ export class RampsController extends BaseController<
332350
if (keys.length > maxSize) {
333351
// Sort by timestamp (oldest first)
334352
const sortedKeys = keys.sort((a, b) => {
335-
const aTime = (requests[a]?.timestamp as number) ?? 0;
336-
const bTime = (requests[b]?.timestamp as number) ?? 0;
353+
const aTime = requests[a]?.timestamp ?? 0;
354+
const bTime = requests[b]?.timestamp ?? 0;
337355
return aTime - bTime;
338356
});
339357

0 commit comments

Comments
 (0)