npm package: @oakshade/squirrel
Description: Intelligent API caching with TypeScript - 100x faster responses, 99% fewer API calls
Author: Sajith Weerathunge
Latest version: 1.0.3

# @oakshade/squirrel 🐿️

[![npm version](https://img.shields.io/npm/v/@oakshade/squirrel.svg)](https://www.npmjs.com/package/@oakshade/squirrel)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
[![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/)

> Intelligent API caching with TypeScript - **100x faster responses, 99% fewer API calls**

---

## Features

- **100x Faster** - Cached responses in milliseconds vs seconds
- **99% Fewer API Calls** - Request deduplication for concurrent users (100 users → 1 API call)
- **Error Resilient** - Stale cache fallback when APIs fail
- **Full TypeScript** - Complete type safety
- **Automatic** - One-line API calls with smart caching
- **Production Ready** - Memory management, auto-cleanup, statistics

---

## 📦 Installation

```bash
npm install @oakshade/squirrel
```

or

```bash
yarn add @oakshade/squirrel
```

---

## 🚀 Quick Start

```ts
import { Squirrel } from '@oakshade/squirrel';

const cache = new Squirrel();
```

---

## 🧪 Demo 1: Basic API Caching

Cache an API response for **5 minutes** and instantly serve repeated requests.

```ts
import { Squirrel } from '@oakshade/squirrel';

// Create cache
const cache = new Squirrel();

// DEMO 1: Basic Caching
async function getWeather() {
  return cache.fetch(
    `https://api.open-meteo.com/v1/forecast?latitude=52.52&longitude=13.41&current_weather=true`,
    {
      ttl: 300, // 5 minutes
    }
  );
}

// User checks for weather
const start1 = Date.now();
const weather1 = await getWeather();
const time1 = Date.now() - start1;

// Same user checks again 1 second later
const start2 = Date.now();
const weather2 = await getWeather();
const time2 = Date.now() - start2;

console.log(`First check: ${time1}ms (API call)`);
console.log(
  `Second check: ${time2}ms (Cached) ${Math.round(time1 / time2)}x faster!`
);
console.log(`${weather1.current_weather.temperature}°C`);
console.log(`${weather2.current_weather.temperature}°C`);
```

✅ **Result:**
Second request is served from cache in milliseconds.

---

## 🧨 Demo 2: Flash Sale / High Concurrency Protection

Prevent API overload when **hundreds of users request the same data simultaneously**.

```ts
import { Squirrel } from '@oakshade/squirrel';

// Create cache
const cache = new Squirrel();

async function getProduct(productId) {
  const url = `https://jsonplaceholder.typicode.com/posts/${productId}`;
  return cache.fetch(url, {
    ttl: 60,
  });
}

// Simulate 100 users hitting "Refresh" at same time
const startTime = Date.now();

const userRequests = Array(100)
  .fill(null)
  .map((_, i) => getProduct('1').then(() => ({ user: i + 1 })));

await Promise.all(userRequests);

const totalTime = Date.now() - startTime;

console.log(`Flash sale starts! ${userRequests.length} users check product #1`);
console.log(`Total time: ${totalTime}ms`);
console.log(`API calls made: 1 (not ${userRequests.length})`);
console.log(
  `Each user got response in ${Math.round(totalTime / userRequests.length)}ms`
);
```

✅ **Result:**
Only **one API call**, regardless of traffic spike.

---

## 📴 Demo 3: Offline Support with Stale Cache

Serve cached data even when the network fails.

```ts
import { Squirrel } from '@oakshade/squirrel';

const newsCache = new Squirrel();

async function loadNews() {
  const url = 'https://jsonplaceholder.typicode.com/posts/1';
  return newsCache.fetch(url, {
    ttl: 300,
    onCacheMiss: () => console.log(`Fetching fresh news...`),
    onCacheHit: () => console.log('Showing cached news'),
  });
}

// User opens app (online)
const news = await loadNews();

// User goes offline and opens app again
const offlineFetcher = async () => {
  throw new Error('No internet connection');
};

const offlineNews = await newsCache.fetch(
  'https://jsonplaceholder.typicode.com/posts/1',
  {
    fetcher: offlineFetcher,
    staleOnError: true,
  }
);
```

✅ **Result:**
Your app keeps working **even without internet**.

---

## 📊 Demo 4: Dashboard with Batch Fetching

Load multiple widgets efficiently with **one optimized cache layer**.

```ts
import { Squirrel } from '@oakshade/squirrel';

async function demoDashboard() {
  const dashboardCache = new Squirrel();

  const widgets = [
    { id: 'users', url: 'https://jsonplaceholder.typicode.com/users', ttl: 60 },
    { id: 'posts', url: 'https://jsonplaceholder.typicode.com/posts', ttl: 30 },
    {
      id: 'comments',
      url: 'https://jsonplaceholder.typicode.com/comments',
      ttl: 30,
    },
    {
      id: 'albums',
      url: 'https://jsonplaceholder.typicode.com/albums',
      ttl: 300,
    },
    {
      id: 'photos',
      url: 'https://jsonplaceholder.typicode.com/photos',
      ttl: 300,
    },
  ];

  // First load - all widgets fresh
  const firstLoadStart = Date.now();
  const firstResults = await dashboardCache.batchFetch(
    widgets.map((w) => ({
      url: w.url,
      options: { ttl: w.ttl, cacheKey: `widget:${w.id}` },
    }))
  );
  const firstLoadTime = Date.now() - firstLoadStart;

  // User refreshes dashboard
  const refreshStart = Date.now();
  await dashboardCache.batchFetch(
    widgets.map((w) => ({
      url: w.url,
      options: { cacheKey: `widget:${w.id}` },
    }))
  );
  const refreshTime = Date.now() - refreshStart;

  return dashboardCache;
}

demoDashboard();
```

✅ **Result:**
Instant dashboard refresh with **zero unnecessary API calls**.

---

## 🧠 Why Squirrel?

| Problem         | Solution               |
| --------------- | ---------------------- |
| API rate limits | Request deduplication  |
| Slow dashboards | Batch fetch + cache    |
| Offline users   | Stale-on-error support |
| Traffic spikes  | Single-flight requests |

---

## 🛠️ Ideal Use Cases

- Admin dashboards
- SaaS platforms
- Flash sales
- News & media apps
- Mobile & offline-first apps
- High-traffic APIs

---

## 📄 License

MIT License © Oakshade

---

## 🌱 Contributing

Pull requests are welcome.
If you find a bug or have a feature request, please open an issue.

---

**Built for speed. Designed for scale.** 🚀
🐿️ _Cache smarter with Squirrel._