-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Seperate loading and revalidating functions
- Loading branch information
1 parent
e844a93
commit 6955f3f
Showing
2 changed files
with
50 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,16 +2,11 @@ import CachePolicy from 'http-cache-semantics'; | |
|
||
export type RemoteCacheEntry = { data: string; expires: number; etag?: string }; | ||
|
||
export async function loadRemoteImage(src: string, etag?: string) { | ||
const opt = etag | ||
? { | ||
headers: { 'If-None-Match': etag }, | ||
} | ||
: undefined; | ||
const req = new Request(src, opt); | ||
export async function loadRemoteImage(src: string) { | ||
const req = new Request(src); | ||
const res = await fetch(req); | ||
|
||
if (!res.ok && res.status != 304) { | ||
if (!res.ok) { | ||
throw new Error( | ||
`Failed to load remote image ${src}. The request did not return a 200 OK response. (received ${res.status}))`, | ||
); | ||
|
@@ -28,6 +23,39 @@ export async function loadRemoteImage(src: string, etag?: string) { | |
}; | ||
} | ||
|
||
export async function revalidateRemoteImage(src: string, etag: string) { | ||
const req = new Request(src, { headers: { 'If-None-Match': etag } }); | ||
const res = await fetch(req); | ||
|
||
if (!res.ok && res.status != 304) { | ||
throw new Error( | ||
`Failed to revalidate cached remote image ${src}. The request did not return a 200 OK / 304 NOT MODIFIED response. (received ${res.status}))`, | ||
); | ||
} | ||
|
||
const data = Buffer.from(await res.arrayBuffer()); | ||
|
||
if (res.ok && !data.length) { | ||
// Server did not include body but indicated cache was stale | ||
return await loadRemoteImage(src); | ||
} | ||
|
||
// calculate an expiration date based on the response's TTL | ||
const policy = new CachePolicy( | ||
webToCachePolicyRequest(req), | ||
webToCachePolicyResponse( | ||
res.ok ? res : new Response(null, { status: 200, headers: res.headers }), | ||
), // 304 responses themselves are not cachable, so just pretend to get the refreshed TTL | ||
); | ||
const expires = policy.storable() ? policy.timeToLive() : 0; | ||
|
||
return { | ||
data, | ||
expires: Date.now() + expires, | ||
etag: res.headers.get('Etag'), | ||
}; | ||
} | ||
|
||
function webToCachePolicyRequest({ url, method, headers: _headers }: Request): CachePolicy.Request { | ||
let headers: CachePolicy.Headers = {}; | ||
// Be defensive here due to a cookie header bug in [email protected] + undici | ||
|