Files
SnowLuma/.pnpm-store/v11/files/7a/76ed29a0aae751130dd923985f713b8948407dfc52cd7839bd8d2291a8aff620f87d410705b876b5b2ac8dbe89a33b4dfac5309296ddf80565a03d3b6b5eda
TanTan 2a69b23b47
Dev Build / cleanup (push) Canceled after 0s
Dev Build / typecheck (push) Canceled after 0s
Dev Build / build (linux-arm64, ubuntu-24.04-arm, linux-arm64) (push) Canceled after 0s
Dev Build / build (linux-x64, ubuntu-latest, linux-x64) (push) Canceled after 0s
Dev Build / build (win-x64, windows-latest, win32-x64) (push) Canceled after 0s
Dev Build / dispatch-dev-docker (push) Canceled after 0s
docs: 仓库链接指向本镜像仓库
2026-11-13 09:27:07 +08:00

376 lines
12 KiB
Plaintext

# Cache Store
<!--introduced_in=v7.0.0-->
<!--type=module-->
<!-- source_link=lib/cache/memory-cache-store.js -->
> Stability: 2 - Stable
A cache store is the storage backend used by the cache interceptor to persist
and retrieve cached responses. A store decides which stored response to serve
for a request by comparing the request against the response's `Vary` header, and
is expected to be compliant with [RFC&nbsp;9111][].
undici ships two stores. `MemoryCacheStore` keeps responses in memory, while
`SqliteCacheStore` persists them to a SQLite database. Both are available under
the `cacheStores` export:
```mjs
import { cacheStores } from 'undici'
const { MemoryCacheStore, SqliteCacheStore } = cacheStores
```
`SqliteCacheStore` requires the [`node:sqlite`][] API. The class is always
exported, but constructing one throws if `node:sqlite` is not available in the
running Node.js version.
A cache store implements three methods — `get(key)`, `createWriteStream(key,
value)`, and `delete(key)` — that operate on a [`CacheKey`](#cachekey) and a
[`CacheValue`](#cachevalue). Any object implementing this contract can be passed
to the cache interceptor, so custom stores (for example, backed by Redis or a
remote service) are supported as well.
## Class: `MemoryCacheStore`
<!-- YAML
added: v7.0.0
-->
* Extends: {EventEmitter}
Stores cached responses in memory. The store enforces upper bounds on the total
number of responses, the total size of all responses, and the size of any single
response. When a limit is exceeded, the store evicts approximately half of its
entries, least recently used first, and emits a
[`'maxSizeExceeded'`](#event-maxsizeexceeded) event.
```mjs
import { interceptors, cacheStores, Agent, setGlobalDispatcher } from 'undici'
const store = new cacheStores.MemoryCacheStore({ maxSize: 50 * 1024 * 1024 })
setGlobalDispatcher(
new Agent().compose(interceptors.cache({ store }))
)
```
### `new MemoryCacheStore([options])`
<!-- YAML
added: v7.0.0
-->
* `options` {Object} (optional)
* `maxCount` {number} The maximum number of responses to store. **Default:**
`1024`.
* `maxSize` {number} The maximum total size, in bytes, of all stored
responses. **Default:** `104857600` (100 MiB).
* `maxEntrySize` {number} The maximum size, in bytes, of a single response
body. Responses whose body exceeds this value are not cached. **Default:**
`5242880` (5 MiB).
* `errorCallback` {Function} A callback invoked with any error raised by the
store. (optional)
* `err` {Error}
Each of `maxCount`, `maxSize`, and `maxEntrySize` must be a non-negative
integer; a `TypeError` is thrown otherwise.
### `memoryCacheStore.size`
<!-- YAML
added: v7.0.0
-->
* Type: {number}
The current total size, in bytes, of all stored response bodies.
### `memoryCacheStore.isFull()`
<!-- YAML
added: v7.0.0
-->
* Returns: {boolean} `true` when the store has reached its `maxSize` or
`maxCount` limit, `false` otherwise.
### `memoryCacheStore.get(key)`
<!-- YAML
added: v7.0.0
-->
* `key` {CacheKey} The request to look up. See [`CacheKey`](#cachekey).
* Returns: {GetResult|undefined} The matching cached response, or `undefined`
when there is no fresh entry for `key`. See [`GetResult`](#getresult).
Looks up a cached response for `key`. A stored entry matches only when its
`method` equals `key.method`, its `deleteAt` time is in the future, and every
header listed in its `vary` map matches the corresponding header in
`key.headers`.
### `memoryCacheStore.createWriteStream(key, value)`
<!-- YAML
added: v7.0.0
-->
* `key` {CacheKey} The request the response is being cached for. See
[`CacheKey`](#cachekey).
* `value` {CacheValue} The response metadata to store. See
[`CacheValue`](#cachevalue).
* Returns: {Writable|undefined} A writable stream that the response body is
written to, or `undefined` when the response cannot be cached.
Returns a {Writable} stream used to write the response body into the store. When
the stream finishes, the entry is committed; if its accumulated size exceeds
`maxEntrySize`, the stream is destroyed and nothing is stored. Writing a new
entry whose `key` matches an existing one replaces that entry.
### `memoryCacheStore.delete(key)`
<!-- YAML
added: v7.0.0
-->
* `key` {CacheKey} The request whose cached responses should be removed. See
[`CacheKey`](#cachekey).
* Returns: {undefined}
Removes every cached response stored for `key.origin` and `key.path`. Throws a
`TypeError` if `key` is not an object.
### Event: `'maxSizeExceeded'`
<!-- YAML
added: v7.10.0
-->
* `data` {Object}
* `size` {number} The current total size, in bytes, of all stored responses.
* `maxSize` {number} The configured `maxSize` limit.
* `count` {number} The current number of stored responses.
* `maxCount` {number} The configured `maxCount` limit.
Emitted when the store exceeds its `maxSize` or `maxCount` limit, immediately
before entries are evicted. The event fires only once per overflow; it is not
emitted again until the store drops back below both limits.
## Class: `SqliteCacheStore`
<!-- YAML
added: v7.0.0
-->
Stores cached responses in a SQLite database using the [`node:sqlite`][] API.
The constructor throws when [`node:sqlite`][] is not available. Response bodies
larger than `compressThreshold` are stored compressed with zstd and
decompressed when read back, saving database space.
```mjs
import { interceptors, cacheStores, Agent, setGlobalDispatcher } from 'undici'
const store = new cacheStores.SqliteCacheStore({ location: './cache.db' })
setGlobalDispatcher(
new Agent().compose(interceptors.cache({ store }))
)
```
### `new SqliteCacheStore([options])`
<!-- YAML
added: v7.0.0
-->
* `options` {Object} (optional)
* `location` {string} The location of the SQLite database. Use `':memory:'`
for an in-memory database. **Default:** `':memory:'`.
* `maxCount` {number} The maximum number of responses to store. **Default:**
`Infinity`.
* `maxEntrySize` {number} The maximum size, in bytes, of a single response
body. Responses whose body exceeds this value are not cached. Must not
exceed `2000000000` (2 GB). **Default:** `2000000000` (2 GB).
* `compressThreshold` {number} The size, in bytes, above which a response
body is stored compressed with zstd. Responses with an easily compressible
Content-Type (e.g. json, xml, plain text) are compressed regardless of
size. Requires a Node version with zstd
support (22.19+); when unavailable, bodies are stored uncompressed.
**Default:** `1048576` (1 MiB).
`maxCount`, `maxEntrySize`, and `compressThreshold` must be non-negative
integers; a `TypeError` is thrown otherwise, or if `maxEntrySize` is greater
than 2 GB.
### `sqliteCacheStore.close()`
<!-- YAML
added: v7.0.0
-->
* Returns: {undefined}
Closes the connection to the underlying SQLite database.
### `sqliteCacheStore.size`
<!-- YAML
added: v7.0.0
-->
* Type: {number}
The number of responses currently stored in the database.
### `sqliteCacheStore.get(key)`
<!-- YAML
added: v7.0.0
-->
* `key` {CacheKey} The request to look up. See [`CacheKey`](#cachekey).
* Returns: {GetResult|undefined} The matching cached response, or `undefined`
when there is no fresh entry for `key`. The returned `body` is a {Buffer}.
See [`GetResult`](#getresult).
Looks up a cached response for `key`, comparing the request method and every
header named in the stored `vary` map. A body that was stored compressed is
decompressed before being returned.
### `sqliteCacheStore.set(key, value)`
<!-- YAML
added: v7.0.0
-->
* `key` {CacheKey} The request the response is being cached for. See
[`CacheKey`](#cachekey).
* `value` {CacheValue} The response to store, with its `body` set to a {Buffer},
an {Array} of {Buffer}, or `null`. See [`CacheValue`](#cachevalue).
* Returns: {undefined}
Writes a response into the database directly, without going through a stream. If
the body exceeds `maxEntrySize`, nothing is stored. A body larger than
`compressThreshold`, or with an easily compressible Content-Type (e.g. json,
xml, plain text), is compressed with zstd before being written. When an entry
already exists for `key` it is overwritten; otherwise a new row is inserted and
old entries are pruned to honour `maxCount`. This method is used internally by
[`sqliteCacheStore.createWriteStream()`](#sqlitecachestorecreatewritestreamkey-value).
### `sqliteCacheStore.createWriteStream(key, value)`
<!-- YAML
added: v7.0.0
-->
* `key` {CacheKey} The request the response is being cached for. See
[`CacheKey`](#cachekey).
* `value` {CacheValue} The response metadata to store. See
[`CacheValue`](#cachevalue).
* Returns: {Writable|undefined} A writable stream that the response body is
written to, or `undefined` when the response cannot be cached.
Returns a {Writable} stream used to write the response body into the store. When
the stream finishes, the buffered body is committed via
[`sqliteCacheStore.set()`](#sqlitecachestoresetkey-value), where bodies larger
than `compressThreshold` or with an easily compressible Content-Type are
compressed with zstd. If the body exceeds
`maxEntrySize`, the stream is destroyed and nothing is stored.
### `sqliteCacheStore.delete(key)`
<!-- YAML
added: v7.0.0
-->
* `key` {CacheKey} The request whose cached responses should be removed. See
[`CacheKey`](#cachekey).
* Returns: {undefined}
Removes every cached response stored for the URL derived from `key.origin` and
`key.path`. Throws a `TypeError` if `key` is not an object.
## Implementing a custom cache store
A cache store is any object that implements the `CacheStore` interface:
* `get(key)` — Look up a response. Returns a [`GetResult`](#getresult),
`undefined`, or a {Promise} resolving to either.
* `createWriteStream(key, value)` — Return a {Writable} to receive the response
body, or `undefined` if the response cannot be stored.
* `delete(key)` — Remove all responses for `key`. May return a {Promise}.
Returning a {Promise} from `get` or `delete` lets a store be backed by an
asynchronous resource; the cache interceptor awaits these values, including on
the revalidation and stale-while-revalidate paths.
### `CacheKey`
The request a response is being looked up or stored for.
* `origin` {string} The request origin.
* `method` {string} The request method.
* `path` {string} The request path.
* `headers` {Record<string, string|string[]>} The request headers, used to
satisfy `Vary`. (optional)
### `CacheValue`
The metadata of a cached response, excluding its body.
* `statusCode` {number} The response's HTTP status code.
* `statusMessage` {string} The response's HTTP status message.
* `headers` {Record<string, string|string[]>} The response headers.
* `vary` {Record<string, string|string[]|null>} The header names listed in the
response's `Vary` header mapped to the values they had in the original
request. A value is `null` when that header was absent from the original
request. (optional)
* `etag` {string} The response's entity tag. (optional)
* `cacheControlDirectives` {Object} The parsed `Cache-Control` directives of the
response. (optional)
* `cachedAt` {number} The time, in milliseconds, at which the response was
cached.
* `staleAt` {number} The time, in milliseconds, at which the response becomes
stale.
* `deleteAt` {number} The time, in milliseconds, at which the response must be
evicted. A store must not return a response once this time has passed.
The `vary` map drives response selection. For a response such as:
```http
Vary: content-encoding, accept
content-encoding: utf8
accept: application/json
```
the recorded map is:
```js
{
'content-encoding': 'utf8',
accept: 'application/json'
}
```
If the original request did not include the `accept` header, its value is
recorded as `null`:
```js
{
'content-encoding': 'utf8',
accept: null
}
```
### `GetResult`
The value returned by `get`. It contains every field of
[`CacheValue`](#cachevalue) plus the response body.
* `body` {Readable|Iterable|AsyncIterable|Buffer|string} The cached response
body. (optional)
[RFC&nbsp;9111]: https://www.rfc-editor.org/rfc/rfc9111.html
[`node:sqlite`]: https://nodejs.org/api/sqlite.html