Copilot 5a8cc53cdd
Fix memory leak in axios.waiting and improve storage handling (#1140)
* Initial plan

* Fix axios.waiting memory leak when maxEntries is set

- Added cleanup of waiting map entries in response interceptor when cache state is not 'loading'
- This prevents memory leaks when entries are evicted from storage due to maxEntries limit
- Added comprehensive tests to verify the fix
- Updated existing test to reflect correct behavior

Co-authored-by: arthurfiorette <47537704+arthurfiorette@users.noreply.github.com>

* Remove pnpm-workspace.yaml build artifact and add to gitignore

Co-authored-by: arthurfiorette <47537704+arthurfiorette@users.noreply.github.com>

* Refactor: Extract resolveWaiting helper to reduce code duplication

- Created resolveWaiting helper function to centralize the logic for resolving and cleaning up waiting entries
- Simplified test error message to avoid redundancy
- This improves code maintainability by avoiding duplication

Co-authored-by: arthurfiorette <47537704+arthurfiorette@users.noreply.github.com>

* Implement timeout-based cleanup for waiting entries

- Add timeout mechanism to automatically clean up waiting entries after axios timeout period
- Use axios config timeout or default to 30 seconds if not configured
- This prevents memory leaks when entries are evicted from storage before response completes
- Updated tests to use short timeouts and wait for cleanup to complete

Note: This implements the approach requested by @arthurfiorette to use axios timeout
instead of immediately resolving/rejecting waiting entries when cache state is not loading.

Co-authored-by: arthurfiorette <47537704+arthurfiorette@users.noreply.github.com>

* Address PR feedback: Add configurable waitingTimeout and improve implementation

- Add waitingTimeout property to CacheProperties for configurable timeout
- Extract timeout logic to waiting-timeout.ts utility function
- Store request ID outside timeout callback to allow earlier GC
- Add unref() to timeout in Node.js to prevent keeping process alive
- Fix timeout logic to handle axios default timeout of 0
- Only create timeout when explicitly configured or config.timeout > 0

Changes address comments 2598940999, 2598944866, and 2598947753.

Co-authored-by: arthurfiorette <47537704+arthurfiorette@users.noreply.github.com>

* Simplify configuration: Remove waitingTimeout property, use config.timeout

- Removed waitingTimeout from CacheProperties (too much configuration)
- Moved timeout logic into createWaitingTimeout utility function
- Use config.timeout or axios.defaults.timeout for timeout value
- Only add finally handler if timeout was actually created
- Updated tests to use axios.defaults.timeout instead

Addresses comments 2599033372, 2599040440, and 2599040616.

Co-authored-by: arthurfiorette <47537704+arthurfiorette@users.noreply.github.com>

* Code cleanup: simplify comment and remove unnecessary variable

- Simplified comment on line 165 to explain WHY (prevent memory leaks) instead of WHAT
- Removed unnecessary requestId variable, passing config.id directly to createWaitingTimeout

Addresses feedback on lines 165 and 169.

Co-authored-by: arthurfiorette <47537704+arthurfiorette@users.noreply.github.com>

* Remove redundant condition check in waiting-timeout

The condition `timeout <= 0` is redundant since the logic above (lines 30-35)
already ensures that timeout is either a positive number or undefined.

Addresses comment 2599097978.

Co-authored-by: arthurfiorette <47537704+arthurfiorette@users.noreply.github.com>

* changes

* Fix maxEntries eviction logic, web storage quota handling, and update docs

**Code improvements:**
- Fixed memory storage maxEntries logic: now properly evicts when at capacity
- Fixed web storage isDomQuotaExceededError to work with jsdom's DOMException
- Added duck-typing check for DOMException to handle cross-context scenarios

**Documentation updates:**
- Added maxStaleAge parameter documentation for both memory and web storage
- Documented that memory storage now uses Map internally
- Updated default values in code examples (cleanupInterval: 5min, maxEntries: 1024)
- Added options section for web storage explaining all parameters

**Test fixes:**
- All 150 tests now passing
- Fixed web storage quota tests that were failing due to DOMException instanceof check

Addresses @arthurfiorette's request to review/improve code, update documentation, and fix tests.

Co-authored-by: arthurfiorette <47537704+arthurfiorette@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: arthurfiorette <47537704+arthurfiorette@users.noreply.github.com>
Co-authored-by: Arthur Fiorette <me@arthur.place>
2025-12-08 15:11:19 -03:00
2023-11-16 03:26:37 -03:00
2025-07-01 21:52:19 -03:00
2023-02-16 23:52:08 -03:00
2024-05-21 13:03:17 -03:00
2024-09-13 10:04:25 -03:00
2025-03-18 00:17:11 -03:00
2022-12-25 17:29:09 -03:00
2025-05-26 11:02:35 -03:00

Using this package? Please consider donating to support my open source work ❤️
Help axios-cache-interceptor grow! Star and share this amazing repository with your friends and co-workers!


Axios Cache Interceptor logo


License Codecov Downloads Bundlephobia Last commit



Axios Cache Interceptor

Cache interceptor for axios made with developers and performance in mind.


  • Faster!
  • 📦 Handy builds!
  • 🔩 Hassle free!
  • 🛠️ Rich Features!
  • 🌐 No network waste!
  • 🔑 TypeScript!

Axios Cache Interceptor is, as it name says, a interceptor for axios to handle caching. It was created to help developers call axios multiple times without having to worry about overloading the network or coding himself a simple and buggy cache system.




import Axios from 'axios';
import { setupCache } from 'axios-cache-interceptor';

const instance = Axios.create();
const axios = setupCache(instance);

const req1 = axios.get('https://arthur.place/');
const req2 = axios.get('https://arthur.place/');

const [res1, res2] = await Promise.all([req1, req2]);

res1.cached; // false
res2.cached; // true

License

Licensed under the MIT. See LICENSE for more informations.

FOSSA Status


Star History

Star History Chart

All Thanks To Our Contributors:


Description
📬 Small and efficient cache interceptor for axios. Etag, Cache-Contol, TTL, HTTP headers and more!
Readme MIT 68 MiB
Languages
TypeScript 98.8%
JavaScript 1.2%