@decocms/blocks 7.63.0 → 7.64.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -1
- package/src/cms/index.ts +3 -2
- package/src/cms/resolve.ts +33 -23
- package/src/cms/sectionLoaders.ts +56 -43
- package/src/middleware/observability.ts +25 -21
- package/src/sdk/cacheStorage.test.ts +242 -0
- package/src/sdk/cacheStorage.ts +287 -0
- package/src/sdk/cachedLoader.ts +82 -63
- package/src/sdk/fetchCache.ts +35 -32
- package/src/sdk/otelHttpMeter.test.ts +45 -115
- package/src/sdk/otelHttpMeter.ts +24 -138
- package/src/sdk/responseCache.ts +79 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { CacheStorage } from "./cacheStorage";
|
|
2
|
+
|
|
3
|
+
interface StoredResponse {
|
|
4
|
+
status: number;
|
|
5
|
+
statusText: string;
|
|
6
|
+
headers: [string, string][];
|
|
7
|
+
body: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/** HTTP serialization belongs to the cache consumer, independent of its storage adapter. */
|
|
11
|
+
export function createResponseCache(storage: CacheStorage, scope: string) {
|
|
12
|
+
const keyFor = (request: Request) => JSON.stringify([scope, "responses", request.url]);
|
|
13
|
+
return {
|
|
14
|
+
async match(request: Request): Promise<Response | undefined> {
|
|
15
|
+
const raw = await storage.get(keyFor(request));
|
|
16
|
+
if (raw === null) return undefined;
|
|
17
|
+
try {
|
|
18
|
+
const stored = JSON.parse(raw) as StoredResponse;
|
|
19
|
+
const body = Uint8Array.from(atob(stored.body), (c) => c.charCodeAt(0));
|
|
20
|
+
return new Response([204, 205, 304].includes(stored.status) ? null : body, {
|
|
21
|
+
status: stored.status,
|
|
22
|
+
statusText: stored.statusText,
|
|
23
|
+
headers: stored.headers,
|
|
24
|
+
});
|
|
25
|
+
} catch {
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
async put(request: Request, response: Response): Promise<void> {
|
|
30
|
+
const cc = response.headers.get("Cache-Control") ?? "";
|
|
31
|
+
const ttl = Number(/(?:^|[,\s])max-age=(\d+)/i.exec(cc)?.[1] ?? 0);
|
|
32
|
+
if (!ttl || /(?:private|no-store|no-cache)/i.test(cc) || response.headers.has("set-cookie"))
|
|
33
|
+
return;
|
|
34
|
+
const expiresAt = Date.now() + ttl * 1000;
|
|
35
|
+
// Bound buffering before serialization; an oversized page can still stream to its caller.
|
|
36
|
+
const chunks: Uint8Array[] = [];
|
|
37
|
+
let size = 0;
|
|
38
|
+
const reader = response.body?.getReader();
|
|
39
|
+
if (reader) {
|
|
40
|
+
while (true) {
|
|
41
|
+
const { done, value } = await reader.read();
|
|
42
|
+
if (done) break;
|
|
43
|
+
size += value.byteLength;
|
|
44
|
+
if (size > 8 * 1024 * 1024) {
|
|
45
|
+
void reader.cancel().catch(() => {});
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
chunks.push(value);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
const bytes = new Uint8Array(size);
|
|
52
|
+
let offset = 0;
|
|
53
|
+
for (const chunk of chunks) {
|
|
54
|
+
bytes.set(chunk, offset);
|
|
55
|
+
offset += chunk.byteLength;
|
|
56
|
+
}
|
|
57
|
+
let binary = "";
|
|
58
|
+
for (let i = 0; i < bytes.length; i += 8192) {
|
|
59
|
+
binary += String.fromCharCode(...bytes.subarray(i, i + 8192));
|
|
60
|
+
}
|
|
61
|
+
const value: StoredResponse = {
|
|
62
|
+
status: response.status,
|
|
63
|
+
statusText: response.statusText,
|
|
64
|
+
headers: [...response.headers.entries()],
|
|
65
|
+
body: btoa(binary),
|
|
66
|
+
};
|
|
67
|
+
try {
|
|
68
|
+
await storage.set(keyFor(request), JSON.stringify(value), expiresAt);
|
|
69
|
+
} catch {
|
|
70
|
+
/* Cache writes must not fail the response or its waitUntil task. */
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
async delete(request: Request): Promise<boolean> {
|
|
74
|
+
// KV deletion has no "existed" result. Report an accepted deletion, avoiding an extra read.
|
|
75
|
+
await storage.delete(keyFor(request));
|
|
76
|
+
return true;
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
}
|