Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 26 additions & 8 deletions src/runtime/internal/cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,12 +122,32 @@ export function defineCachedFunction<T, ArgsT extends unknown[] = any[]>(
if (opts.maxAge && !opts.swr /* TODO: respect staleMaxAge */) {
setOpts = { ttl: opts.maxAge };
}
const promise = useStorage()
.setItem(cacheKey, entry, setOpts)
.catch((error) => {
let cacheEntry = entry;
let setItem = useStorage().setItem;
if (
opts.stream &&
entry.value &&
typeof entry.value === "object" &&
"body" in entry.value &&
entry.value.body instanceof ReadableStream
) {
const [cacheStream, resStream] = entry.value.body.tee();
cacheEntry = {
...entry,
value: {
...entry.value,
body: cacheStream,
},
};
entry.value.body = resStream;
setItem = useStorage().setItemRaw;
}
const promise = setItem(cacheKey, cacheEntry, setOpts).catch(
(error) => {
console.error(`[cache] Cache write error.`, error);
useNitroApp().captureError(error, { event, tags: ["cache"] });
});
}
);
if (typeof event?.req?.waitUntil === "function") {
event.req.waitUntil(promise);
}
Expand Down Expand Up @@ -270,11 +290,9 @@ export function defineCachedEventHandler(
const rawValue = await handler(event);
const res = await toResponse(rawValue, event);

// Stringified body
// TODO: support binary responses
const body = await res.text();
const body = opts.stream ? res.body : await res.text();

if (!res.headers.has("etag")) {
if (!res.headers.has("etag") && !(body instanceof ReadableStream)) {
res.headers.set("etag", `W/"${hash(body)}"`);
}

Expand Down
4 changes: 4 additions & 0 deletions src/types/runtime/cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ export interface CacheOptions<T = any, ArgsT extends unknown[] = any[]> {
swr?: boolean;
staleMaxAge?: number;
base?: string;
/**
* If true, the response body will be passed to the cache as a ReadableStream.
*/
stream?: boolean;
}

export interface ResponseCacheEntry {
Expand Down