+28
-4
@@ -21,3 +21,3 @@ //#region src/types.d.ts | ||
| */ | ||
| type EventHandler = (event: HTTPEvent) => unknown | Promise<unknown>; | ||
| type EventHandler<E extends HTTPEvent = HTTPEvent> = (event: E) => unknown | Promise<unknown>; | ||
| /** | ||
@@ -81,2 +81,10 @@ * Stored cache entry wrapping a cached value with metadata. | ||
| /** | ||
| * Conditional cache header options passed to the `handleCacheHeaders` hook. | ||
| */ | ||
| interface CacheConditions { | ||
| modifiedTime?: Date; | ||
| maxAge?: number; | ||
| etag?: string; | ||
| } | ||
| /** | ||
| * Options for configuring cached HTTP handlers created by `defineCachedHandler`. | ||
@@ -86,3 +94,3 @@ * | ||
| */ | ||
| interface CachedEventHandlerOptions extends Omit<CacheOptions<ResponseCacheEntry, [HTTPEvent]>, "transform" | "validate"> { | ||
| interface CachedEventHandlerOptions<E extends HTTPEvent = HTTPEvent> extends Omit<CacheOptions<ResponseCacheEntry, [E]>, "transform" | "validate"> { | ||
| /** When `true`, only handles conditional headers (304 responses) without full response caching. */ | ||
@@ -92,2 +100,18 @@ headersOnly?: boolean; | ||
| varies?: string[] | readonly string[]; | ||
| /** | ||
| * Convert handler return value to a Response. | ||
| * Default: `rawValue instanceof Response ? rawValue : new Response(String(rawValue))`. | ||
| */ | ||
| toResponse?: (value: unknown, event: E) => Response | Promise<Response>; | ||
| /** | ||
| * Create the final cached Response from serialized cache entry data. | ||
| * Default: `new Response(body, init)`. | ||
| */ | ||
| createResponse?: (body: string | null, init: ResponseInit) => Response; | ||
| /** | ||
| * Check conditional request headers (etag/if-modified-since). | ||
| * Return `true` to short-circuit with a 304 response. | ||
| * Default: built-in if-none-match / if-modified-since check. | ||
| */ | ||
| handleCacheHeaders?: (event: E, conditions: CacheConditions) => boolean; | ||
| } | ||
@@ -119,3 +143,3 @@ //#endregion | ||
| */ | ||
| declare function defineCachedHandler(handler: EventHandler, opts?: CachedEventHandlerOptions): EventHandler; | ||
| declare function defineCachedHandler<E extends HTTPEvent = HTTPEvent>(handler: EventHandler<E>, opts?: CachedEventHandlerOptions<E>): EventHandler<E>; | ||
| //#endregion | ||
@@ -136,2 +160,2 @@ //#region src/storage.d.ts | ||
| //#endregion | ||
| export { type CacheEntry, type CacheOptions, type CachedEventHandlerOptions, type EventHandler, type HTTPEvent, type ResponseCacheEntry, type ServerRequest, type StorageInterface, cachedFunction, createMemoryStorage, defineCachedFunction, defineCachedHandler, setStorage, useStorage }; | ||
| export { type CacheConditions, type CacheEntry, type CacheOptions, type CachedEventHandlerOptions, type EventHandler, type HTTPEvent, type ResponseCacheEntry, type ServerRequest, type StorageInterface, cachedFunction, createMemoryStorage, defineCachedFunction, defineCachedHandler, setStorage, useStorage }; |
+12
-10
@@ -163,2 +163,5 @@ import { hash } from "ohash"; | ||
| const variableHeaderNames = (opts.varies || []).filter(Boolean).map((h) => h.toLowerCase()).sort(); | ||
| const _toResponse = opts.toResponse || ((rawValue) => rawValue instanceof Response ? rawValue : new Response(String(rawValue))); | ||
| const _createResponse = opts.createResponse || ((body, init) => new Response(body, init)); | ||
| const _handleCacheHeaders = opts.handleCacheHeaders || _defaultHandleCacheHeaders; | ||
| const _cachedHandler = cachedFunction(async (event) => { | ||
@@ -176,4 +179,3 @@ const filteredHeaders = [...event.req.headers.entries()].filter(([key]) => !variableHeaderNames.includes(key.toLowerCase())); | ||
| } | ||
| const rawValue = await handler(event); | ||
| const res = rawValue instanceof Response ? rawValue : new Response(String(rawValue)); | ||
| const res = await _toResponse(await handler(event), event); | ||
| const body = await res.text(); | ||
@@ -225,12 +227,12 @@ if (!res.headers.has("etag")) res.headers.set("etag", `W/"${hash(body)}"`); | ||
| if (opts.headersOnly) { | ||
| if (handleCacheHeaders(event, { maxAge: opts.maxAge })) return new Response(null, { status: 304 }); | ||
| if (_handleCacheHeaders(event, { maxAge: opts.maxAge })) return _createResponse(null, { status: 304 }); | ||
| return handler(event); | ||
| } | ||
| const response = await _cachedHandler(event); | ||
| if (handleCacheHeaders(event, { | ||
| if (_handleCacheHeaders(event, { | ||
| modifiedTime: new Date(response.headers["last-modified"]), | ||
| etag: response.headers.etag, | ||
| maxAge: opts.maxAge | ||
| })) return new Response(null, { status: 304 }); | ||
| return new Response(response.body, { | ||
| })) return _createResponse(null, { status: 304 }); | ||
| return _createResponse(response.body ?? null, { | ||
| status: response.status, | ||
@@ -245,8 +247,8 @@ statusText: response.statusText, | ||
| } | ||
| function handleCacheHeaders(event, opts) { | ||
| function _defaultHandleCacheHeaders(event, conditions) { | ||
| const ifNoneMatch = event.req.headers.get("if-none-match"); | ||
| if (ifNoneMatch && opts.etag && ifNoneMatch === opts.etag) return true; | ||
| if (ifNoneMatch && conditions.etag && ifNoneMatch === conditions.etag) return true; | ||
| const ifModifiedSince = event.req.headers.get("if-modified-since"); | ||
| if (ifModifiedSince && opts.modifiedTime) { | ||
| if (new Date(ifModifiedSince) >= opts.modifiedTime) return true; | ||
| if (ifModifiedSince && conditions.modifiedTime) { | ||
| if (new Date(ifModifiedSince) >= conditions.modifiedTime) return true; | ||
| } | ||
@@ -253,0 +255,0 @@ return false; |
+1
-1
| { | ||
| "name": "ocache", | ||
| "version": "0.1.1", | ||
| "version": "0.1.2", | ||
| "description": "Standalone caching utilities with TTL, SWR, and HTTP response caching", | ||
@@ -5,0 +5,0 @@ "license": "MIT", |
+19
-7
@@ -147,6 +147,6 @@ # ocache | ||
| ```ts | ||
| function defineCachedHandler( | ||
| handler: EventHandler, | ||
| opts: CachedEventHandlerOptions = defaultCacheOptions(), | ||
| ): EventHandler; | ||
| function defineCachedHandler<E extends HTTPEvent = HTTPEvent>( | ||
| handler: EventHandler<E>, | ||
| opts: CachedEventHandlerOptions<E> = defaultCacheOptions() as CachedEventHandlerOptions<E>, | ||
| ): EventHandler<E>; | ||
| ``` | ||
@@ -224,3 +224,3 @@ | ||
| ```ts | ||
| type EventHandler = (event: HTTPEvent) => unknown | Promise<unknown>; | ||
| type EventHandler<E extends HTTPEvent = HTTPEvent> = ( | ||
| ``` | ||
@@ -262,7 +262,19 @@ | ||
| ### `CacheConditions` | ||
| ```ts | ||
| interface CacheConditions | ||
| ``` | ||
| Conditional cache header options passed to the `handleCacheHeaders` hook. | ||
| --- | ||
| ### `CachedEventHandlerOptions` | ||
| ```ts | ||
| interface CachedEventHandlerOptions extends Omit< | ||
| CacheOptions<ResponseCacheEntry, [HTTPEvent]>, | ||
| interface CachedEventHandlerOptions< | ||
| E extends HTTPEvent = HTTPEvent, | ||
| > extends Omit< | ||
| CacheOptions<ResponseCacheEntry, [E]>, | ||
| "transform" | "validate" | ||
@@ -269,0 +281,0 @@ > |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
25493
6.3%254
0.79%304
4.11%0
-100%