Plan Checker (neues Studenten-Werkzeug, Seitenleiste + Admin → Plan-Checker- Merkmale): lädt einen Bauplan als PDF hoch und lässt ChatGPT oder Claude ihn gegen eine gepflegte Merkmalsliste prüfen. PDF-Rendering (pdf.js + @napi-rs/canvas) berücksichtigt jetzt Ebenen (Optional Content Groups) und WASM-Decoder korrekt, sendet eine Übersicht plus mehrere hochaufgelöste Kachel-Ausschnitte statt eines einzelnen, zu groben Bilds, und beide Anbieter bekommen dasselbe Bildmaterial. Jedes Prüfergebnis kann auf eines der gesendeten Bilder als Beleg verweisen (bildIndex) — als Screenshot im Ergebnis anklickbar, öffnet vergrößert in einem Modal statt eines von Chrome blockierten target=_blank-Links auf eine data:-URL. KI-Modellname ist jetzt pro Konto überschreibbar (Einstellungen → Mein Konto) für Drittanbieter mit abweichendem Modell-Katalog. Wochenbericht: dichte Kartenansicht bekommt einen Fokus-Modus — nur der Kommentar liegt offen, Leistungsphasen und Beteiligte stecken in aufklappbaren Abschnitten statt dauerhaft nebeneinander zu stehen. Projektbereich: Terminplan-Auslastung rechnet jetzt exakt wie der Auslastungs-Tab/die Wandtafel (statt einer unabhängigen, tageweisen Schätzung); die LPH-Fortschrittsliste im Dashboard zeigt nur noch die beauftragten Leistungsphasen. Wandtafel: Dashboard-Kopf mit Kennzahlen-Reihe und Panel-Reihe neu strukturiert, in den Blautönen des Firmenlogos; dieselbe Palette wurde anschließend auf den gesamten App-weiten Dark Mode übernommen. Dateibereinigung: nicht mehr benötigte Test-Uploads/Backups entfernt. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
11 KiB
Cache Store
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 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:
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 and a
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
- 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 and emits a 'maxSizeExceeded' event.
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])
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
- Type: {number}
The current total size, in bytes, of all stored response bodies.
memoryCacheStore.isFull()
- Returns: {boolean}
truewhen the store has reached itsmaxSizeormaxCountlimit,falseotherwise.
memoryCacheStore.get(key)
key{CacheKey} The request to look up. SeeCacheKey.- Returns: {GetResult|undefined} The matching cached response, or
undefinedwhen there is no fresh entry forkey. SeeGetResult.
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)
key{CacheKey} The request the response is being cached for. SeeCacheKey.value{CacheValue} The response metadata to store. SeeCacheValue.- Returns: {Writable|undefined} A writable stream that the response body is
written to, or
undefinedwhen 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)
key{CacheKey} The request whose cached responses should be removed. SeeCacheKey.- Returns: {undefined}
Removes every cached response stored for key.origin and key.path. Throws a
TypeError if key is not an object.
Event: 'maxSizeExceeded'
data{Object}size{number} The current total size, in bytes, of all stored responses.maxSize{number} The configuredmaxSizelimit.count{number} The current number of stored responses.maxCount{number} The configuredmaxCountlimit.
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
Stores cached responses in a SQLite database using the node:sqlite API.
The constructor throws when node:sqlite is not available.
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])
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 exceed2000000000(2 GB). Default:2000000000(2 GB).
maxCount and maxEntrySize must be non-negative integers; a TypeError is
thrown otherwise, or if maxEntrySize is greater than 2 GB.
sqliteCacheStore.close()
- Returns: {undefined}
Closes the connection to the underlying SQLite database.
sqliteCacheStore.size
- Type: {number}
The number of responses currently stored in the database.
sqliteCacheStore.get(key)
key{CacheKey} The request to look up. SeeCacheKey.- Returns: {GetResult|undefined} The matching cached response, or
undefinedwhen there is no fresh entry forkey. The returnedbodyis a {Buffer}. SeeGetResult.
Looks up a cached response for key, comparing the request method and every
header named in the stored vary map.
sqliteCacheStore.set(key, value)
key{CacheKey} The request the response is being cached for. SeeCacheKey.value{CacheValue} The response to store, with itsbodyset to a {Buffer}, an {Array} of {Buffer}, ornull. SeeCacheValue.- Returns: {undefined}
Writes a response into the database directly, without going through a stream. If
the body exceeds maxEntrySize, nothing is stored. 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().
sqliteCacheStore.createWriteStream(key, value)
key{CacheKey} The request the response is being cached for. SeeCacheKey.value{CacheValue} The response metadata to store. SeeCacheValue.- Returns: {Writable|undefined} A writable stream that the response body is
written to, or
undefinedwhen 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(). If the body exceeds
maxEntrySize, the stream is destroyed and nothing is stored.
sqliteCacheStore.delete(key)
key{CacheKey} The request whose cached responses should be removed. SeeCacheKey.- 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 aGetResult,undefined, or a {Promise} resolving to either.createWriteStream(key, value)— Return a {Writable} to receive the response body, orundefinedif the response cannot be stored.delete(key)— Remove all responses forkey. 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 satisfyVary. (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'sVaryheader mapped to the values they had in the original request. A value isnullwhen that header was absent from the original request. (optional)etag{string} The response's entity tag. (optional)cacheControlDirectives{Object} The parsedCache-Controldirectives 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:
Vary: content-encoding, accept
content-encoding: utf8
accept: application/json
the recorded map is:
{
'content-encoding': 'utf8',
accept: 'application/json'
}
If the original request did not include the accept header, its value is
recorded as null:
{
'content-encoding': 'utf8',
accept: null
}
GetResult
The value returned by get. It contains every field of
CacheValue plus the response body.
body{Readable|Iterable|AsyncIterable|Buffer|string} The cached response body. (optional)