Security News
PyPI’s New Archival Feature Closes a Major Security Gap
PyPI now allows maintainers to archive projects, improving security and helping users make informed decisions about their dependencies.
cacheables
Advanced tools
A simple in-memory cache written in Typescript with automatic cache invalidation and an elegant syntax.
A simple in-memory cache with support of different cache policies and elegant syntax written in Typescript.
// without caching
fetch('https://some-url.com/api')
// with caching
cache.cacheable(() => fetch('https://some-url.com/api'), 'key')
npm install cacheables
https://codesandbox.io/s/quickstart-cacheables-5zh6h?file=/src/index.ts
// Import Cacheables
import { Cacheables } from "cacheables"
const apiUrl = "https://goweather.herokuapp.com/weather/Karlsruhe"
// Create a new cache instance
const cache = new Cacheables({
logTiming: true,
log: true
})
const wait = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms))
// Wrap the existing API call `fetch(apiUrl)` and assign a cache
// key `weather` to it. This example uses the cache policy 'max-age'
// which invalidates the cache after a certain time.
// The method returns a fully typed Promise just like `fetch(apiUrl)`
// would but with the benefit of caching the result.
const getWeatherData = () =>
cache.cacheable(() => fetch(apiUrl), 'weather', {
cachePolicy: 'max-age',
maxAge: 5000,
})
const start = async () => {
// Fetch some fresh weather data and store it in our cache.
const weatherData = await getWeatherData()
/** 3 seconds later **/
await wait(3000)
// The cached weather data is returned as the
// maxAge of 5 seconds did not yet expire.
const cachedWeatherData = await getWeatherData()
/** Another 3 seconds later **/
await wait(3000)
// Now that the maxAge is expired, the resource
// will be fetched and stored in our cache.
const freshWeatherData = await getWeatherData()
}
start()
cacheable
serves both as the getter and setter. This method will return a cached resource if available or use the provided argument resource
to fill the cache and return a value.
Be aware that there is no exclusive cache getter (like
cache.get('key)
). This is by design as the Promise provided by the first argument tocacheable
is used to infer the return type of the cached resource.
new Cacheables(options?): Cacheables
Cacheables
instance.options?: CacheOptions
interface CacheOptions {
enabled?: boolean // Enable/disable the cache, can be set anytime, default: true.
log?: boolean // Log hits to the cache, default: false.
logTiming?: boolean // Log the timing, default: false.
}
import { Cacheables } from 'cacheables'
const cache = new Cacheables({
logTiming: true
})
cache.cacheable(resource, key, options?): Promise<T>
key
) cacheable
decides on returning a cache based on the provided cache policy.resource
will be called and used to store a cache value with key key
and the value is returned.resource: () => Promise<T>
A function that returns a Promise<T>
.
key: string
A key to store the cache at.
See Cacheables.key() for a safe and easy way to generate unique keys.
options?: CacheableOptions
(optional)An object defining the cache policy and possibly other options in the future.
The default cache policy is cache-only
.
See Cache Policies.
type CacheableOptions = {
cachePolicy: 'cache-only' | 'network-only-non-concurrent' | 'network-only' | 'max-age' | 'stale-while-revalidate' // See cache policies for details
maxAge?: number // Required if cache policy is `max-age` and optional if cache policy is `stale-while-revalidate`
}
const cachedApiResponse = await cache.cacheable(
() => fetch('https://github.com/'),
'key',
{
cachePolicy: 'max-age',
maxAge: 10000
}
)
cache.delete(key: string): void
key: string
Delete a cache for a certain key.
cache.delete('key')
cache.clear(): void
Delete all cached resources.
cache.keys(): string[]
Returns all the cache keys
cache.isCached(key: string): boolean
key: string
Returns whether a cacheable is present for a certain key.
const aIsCached = cache.isCached('a')
Cacheables.key(...args: (string | number)[]): string
A static helper function to easily build safe and consistent cache keys.
const id = '5d3c5be6-2da4-11ec-8d3d-0242ac130003'
console.log(Cacheables.key('user', id))
// 'user:5d3c5be6-2da4-11ec-8d3d-0242ac130003'
Cacheables comes with multiple cache policies.
Each policy has different behaviour when it comes to preheating the cache (i.e. the first time it is requested) and balancing network requests.
Cache Policy | Behaviour |
---|---|
cache-only (default) | All requests should return a value from the cache. |
network-only | All requests should be handled by the network. Simultaneous requests trigger simultaneous network requests. |
network-only-non-concurrent | All requests should be handled by the network but no concurrent network requests are allowed. All requests made in the timeframe of a network request are resolved once that is finished. |
max-age | All requests should be checked against max-age. If max-age is expired, a network request is triggered. All requests made in the timeframe of a network request are resolved once that is finished. |
stale-while-revalidate | All requests immediately return a cached value. If no network request is running and maxAge is provided and reached or maxAge is not provided, a network request is triggered, 'silently' updating the cache in the background. After the network request finished, subsequent requests will receive the updated cached value. |
The default and simplest cache policy. If there is a cache, return it.
If there is no cache yet, all calls will be resolved by the first network request (i.e. non-concurrent).
cache.cacheable(() => fetch(url), 'a', { cachePolicy: 'cache-only' })
The opposite of cache-only
.
Simultaneous requests trigger simultaneous network requests.
cache.cacheable(() => fetch(url), 'a', { cachePolicy: 'network-only' })
A version of network-only
but only one network request is running at any point in time.
All requests should be handled by the network but no concurrent network requests are allowed. All requests made in the timeframe of a network request are resolved once that is finished.
cache.cacheable(() => fetch(url), 'a', { cachePolicy: 'network-only-non-concurrent' })
The cache policy max-age
defines after what time a cached value is treated as invalid.
All requests should be checked against max-age. If max-age is expired, a network request is triggered. All requests made in the timeframe of a network request are resolved once that is finished.
// Trigger a network request if the cached value is older than 1 second.
cache.cacheable(() => fetch(url), 'a', {
cachePolicy: 'max-age',
maxAge: 1000
})
The cache policy stale-while-revalidate
will return a cached value immediately and – if there is no network request already running and maxAge
is either provided and reached or not provided – trigger a network request to 'silently' update the cache in the background.
maxAge
// If there is a cache, return it but 'silently' update the cache.
cache.cacheable(() => fetch(url), 'a', { cachePolicy: 'stale-while-revalidate'})
maxAge
// If there is a cache, return it and 'silently' update the cache if it's older than 1 second.
cache.cacheable(() => fetch(url), 'a', {
cachePolicy: 'stale-while-revalidate',
maxAge: 1000
})
A single cacheable can be requested with different cache policies at any time.
// If there is a cache, return it.
cache.cacheable(() => fetch(url), 'a', { cachePolicy: 'cache-only' })
// If there is a cache, return it but 'silently' update the cache.
cache.cacheable(() => fetch(url), 'a', { cachePolicy: 'stale-while-revalidate' })
PRs welcome
The MIT License (MIT). Please see License File for more information.
FAQs
A simple in-memory cache written in Typescript with automatic cache invalidation and an elegant syntax.
The npm package cacheables receives a total of 1,669 weekly downloads. As such, cacheables popularity was classified as popular.
We found that cacheables demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
PyPI now allows maintainers to archive projects, improving security and helping users make informed decisions about their dependencies.
Research
Security News
Malicious npm package postcss-optimizer delivers BeaverTail malware, targeting developer systems; similarities to past campaigns suggest a North Korean connection.
Security News
CISA's KEV data is now on GitHub, offering easier access, API integration, commit history tracking, and automated updates for security teams and researchers.