@dee-wan/cache 1.0.1 → 2.0.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.
Files changed (57) hide show
  1. package/README.md +208 -3
  2. package/dist/chunk-A4WV6RY4.js +311 -0
  3. package/dist/chunk-A4WV6RY4.js.map +1 -0
  4. package/dist/chunk-AENVFT2S.js +6 -0
  5. package/dist/chunk-AENVFT2S.js.map +1 -0
  6. package/dist/chunk-E6OZZ5UX.js +133 -0
  7. package/dist/chunk-E6OZZ5UX.js.map +1 -0
  8. package/dist/chunk-JPK2AF7X.js +18 -0
  9. package/dist/chunk-JPK2AF7X.js.map +1 -0
  10. package/dist/chunk-LAXBP5DQ.js +330 -0
  11. package/dist/chunk-LAXBP5DQ.js.map +1 -0
  12. package/dist/chunk-LHOK33GI.js +12 -0
  13. package/dist/chunk-LHOK33GI.js.map +1 -0
  14. package/dist/chunk-M4UOCIDQ.js +557 -0
  15. package/dist/chunk-M4UOCIDQ.js.map +1 -0
  16. package/dist/chunk-NFBMWKY5.js +54 -0
  17. package/dist/chunk-NFBMWKY5.js.map +1 -0
  18. package/dist/chunk-O3KHMFHX.js +425 -0
  19. package/dist/chunk-O3KHMFHX.js.map +1 -0
  20. package/dist/chunk-WJNCFFF3.js +637 -0
  21. package/dist/chunk-WJNCFFF3.js.map +1 -0
  22. package/dist/chunk-WKZ7TKGM.js +82 -0
  23. package/dist/chunk-WKZ7TKGM.js.map +1 -0
  24. package/dist/chunk-ZBYAKDNZ.js +45 -0
  25. package/dist/chunk-ZBYAKDNZ.js.map +1 -0
  26. package/dist/chunk-ZCMZJKGN.js +78 -0
  27. package/dist/chunk-ZCMZJKGN.js.map +1 -0
  28. package/dist/client.d.ts +63 -0
  29. package/dist/client.js +260 -0
  30. package/dist/client.js.map +1 -0
  31. package/dist/cloudflare/index.d.ts +15 -2
  32. package/dist/cloudflare/index.js +413 -45
  33. package/dist/cloudflare/index.js.map +1 -1
  34. package/dist/d1/config.d.ts +41 -0
  35. package/dist/d1/config.js +102 -0
  36. package/dist/d1/config.js.map +1 -0
  37. package/dist/d1/index.d.ts +80 -0
  38. package/dist/d1/index.js +218 -0
  39. package/dist/d1/index.js.map +1 -0
  40. package/dist/d1/response-lease.d.ts +9 -0
  41. package/dist/d1/response-lease.js +44 -0
  42. package/dist/d1/response-lease.js.map +1 -0
  43. package/dist/index.d.ts +2 -2
  44. package/dist/index.js +3 -616
  45. package/dist/index.js.map +1 -1
  46. package/dist/profile--LBtbQI_.d.ts +30 -0
  47. package/dist/response-lease-DeeM-ofO.d.ts +19 -0
  48. package/dist/response-lease.d.ts +7 -0
  49. package/dist/response-lease.js +14 -0
  50. package/dist/response-lease.js.map +1 -0
  51. package/dist/response-warmup-BWQvnT1G.d.ts +38 -0
  52. package/dist/scoped-read.d.ts +12 -0
  53. package/dist/scoped-read.js +30 -0
  54. package/dist/scoped-read.js.map +1 -0
  55. package/dist/{types-DwtU0KpX.d.ts → types-CtErcz2a.d.ts} +25 -1
  56. package/docs/cache-contract.md +49 -1
  57. package/package.json +31 -2
@@ -0,0 +1,218 @@
1
+ import { cacheD1Read } from '../chunk-LAXBP5DQ.js';
2
+ export { cacheD1Env, cacheD1Read, createD1CacheRuntime, d1CacheEpoch, d1PrismaCacheExtension, sameD1CacheDatabase, withD1PrismaCache, wrapD1Handler } from '../chunk-LAXBP5DQ.js';
3
+ import '../chunk-NFBMWKY5.js';
4
+ import { d1SessionBookmarkFloor, advanceD1SessionBookmarks, trackD1SessionSource, runPrimaryD1SessionSource, responseD1SessionBookmarks, varyD1Bookmarks } from '../chunk-WJNCFFF3.js';
5
+ export { d1SessionCacheHooks, d1SessionWarmupRequest, fenceD1Writes, prismaD1SessionDatabase, regionalD1MetadataTtl, runD1PrismaScope, runD1SessionOperation, runIsolatedD1Session, runPrimaryD1SessionSource, sessionD1Env, wrapD1ReadSessionHandler } from '../chunk-WJNCFFF3.js';
6
+ import '../chunk-LHOK33GI.js';
7
+ import '../chunk-M4UOCIDQ.js';
8
+ import { D1_BOOKMARK_HEADER, decodeD1Bookmarks, serializeD1Bookmarks } from '../chunk-ZBYAKDNZ.js';
9
+ import '../chunk-WKZ7TKGM.js';
10
+ import { regionalKey, regionalRead, regionalWrite } from '../chunk-E6OZZ5UX.js';
11
+ import '../chunk-OQRNVGQE.js';
12
+ import '../chunk-ZCMZJKGN.js';
13
+ export { isD1BindingName } from '../chunk-AENVFT2S.js';
14
+
15
+ // src/d1/json-read.ts
16
+ var MAX_BODY_BYTES = 1e6;
17
+ var sensitiveHeaders = /* @__PURE__ */ new Set(["authorization", "cookie", "proxy-authorization", "x-api-key", "x-site-token", "x-capability", "x-capability-token"]);
18
+ var ephemeralHeaders = /* @__PURE__ */ new Set(["cf-ray", "x-request-id", "traceparent", "tracestate", "cf-connecting-ip", "x-forwarded-for"]);
19
+ var hopHeaders = /* @__PURE__ */ new Set(["connection", "keep-alive", "proxy-authenticate", "proxy-authorization", "te", "trailer", "transfer-encoding", "upgrade"]);
20
+ function requestIdentity(request) {
21
+ if (request.method !== "GET") return null;
22
+ for (const name of ["range", "if-match", "if-none-match", "if-modified-since", "if-unmodified-since", "if-range", "x-capability", "x-capability-token", "x-site-token", "x-api-key", "authorization"]) if (request.headers.has(name)) return null;
23
+ const url = new URL(request.url);
24
+ if (/(?:^|\/)(?:capability|capabilities)(?:\/|$)/i.test(url.pathname)) return null;
25
+ for (const name of url.searchParams.keys()) if (/^(?:preview|token|capability|capability_token)$/i.test(name)) return null;
26
+ const headers = [...request.headers.entries()].filter(([name]) => !sensitiveHeaders.has(name.toLowerCase()) && !ephemeralHeaders.has(name.toLowerCase())).sort(([a], [b]) => a.localeCompare(b));
27
+ return { url: url.toString(), headers };
28
+ }
29
+ async function responseEntry(response) {
30
+ if (response.status !== 200 || response.headers.has("set-cookie") || response.headers.has("content-disposition") || response.headers.has("transfer-encoding") || response.headers.has("content-encoding")) return null;
31
+ if (!/^application\/(?:[a-z0-9.+-]*\+)?json(?:\s*;|$)/i.test(response.headers.get("content-type") ?? "")) return null;
32
+ const vary = response.headers.get("vary");
33
+ if (vary && vary.split(",").some((name) => name.trim() === "*" || (sensitiveHeaders.has(name.trim().toLowerCase()) || ephemeralHeaders.has(name.trim().toLowerCase())))) return null;
34
+ const length = response.headers.get("content-length");
35
+ if (length !== null && (!/^(?:0|[1-9]\d*)$/.test(length) || !Number.isSafeInteger(Number(length)) || Number(length) > MAX_BODY_BYTES)) return null;
36
+ const reader = response.clone().body?.getReader();
37
+ if (!reader) return null;
38
+ const chunks = [];
39
+ let size = 0;
40
+ let timer;
41
+ try {
42
+ const timeout = new Promise((_, reject) => {
43
+ timer = setTimeout(() => reject(new Error("buffered body timeout")), 1e3);
44
+ });
45
+ for (; ; ) {
46
+ const next = await Promise.race([reader.read(), timeout]);
47
+ if (next.done) break;
48
+ size += next.value.byteLength;
49
+ if (size > MAX_BODY_BYTES) return null;
50
+ chunks.push(next.value);
51
+ }
52
+ } finally {
53
+ if (timer !== void 0) clearTimeout(timer);
54
+ void reader.cancel().catch(() => void 0);
55
+ }
56
+ if (length !== null && size !== Number(length)) return null;
57
+ const joined = new Uint8Array(size);
58
+ let offset = 0;
59
+ for (const chunk of chunks) {
60
+ joined.set(chunk, offset);
61
+ offset += chunk.byteLength;
62
+ }
63
+ const body = new TextDecoder("utf-8", { fatal: true, ignoreBOM: false }).decode(joined);
64
+ try {
65
+ JSON.parse(body);
66
+ } catch {
67
+ return null;
68
+ }
69
+ const headers = [...response.headers.entries()].filter(([name]) => !hopHeaders.has(name.toLowerCase()));
70
+ return { status: response.status, statusText: response.statusText, headers, body };
71
+ }
72
+ async function cacheD1JsonRead(database, options, load) {
73
+ if (options.buffered !== true) return load();
74
+ let identity2;
75
+ try {
76
+ identity2 = requestIdentity(options.request);
77
+ } catch {
78
+ return load();
79
+ }
80
+ if (identity2 === null) return load();
81
+ let original;
82
+ const entry = await cacheD1Read(database, {
83
+ key: ["json-response-v1", options.key, identity2],
84
+ scope: options.scope,
85
+ ...options.dependencies ? { dependencies: options.dependencies } : {},
86
+ ...options.ttlMs !== void 0 ? { ttlMs: options.ttlMs } : {},
87
+ cacheable: (value) => value !== null
88
+ }, async () => {
89
+ original = await load();
90
+ try {
91
+ return await responseEntry(original);
92
+ } catch {
93
+ return null;
94
+ }
95
+ });
96
+ if (original) return original;
97
+ if (!entry || entry.status !== 200 || typeof entry.statusText !== "string" || typeof entry.body !== "string" || !Array.isArray(entry.headers) || !entry.headers.every((header) => Array.isArray(header) && header.length === 2 && typeof header[0] === "string" && typeof header[1] === "string" && !hopHeaders.has(header[0].toLowerCase()) && header[0].toLowerCase() !== "set-cookie" && header[0].toLowerCase() !== "content-disposition")) return load();
98
+ try {
99
+ JSON.parse(entry.body);
100
+ const headers = new Headers(entry.headers);
101
+ if (headers.has("content-encoding") || !/^application\/(?:[a-z0-9.+-]*\+)?json(?:\s*;|$)/i.test(headers.get("content-type") ?? "")) return load();
102
+ const vary = headers.get("vary");
103
+ if (vary && vary.split(",").some((name) => name.trim() === "*" || sensitiveHeaders.has(name.trim().toLowerCase()) || ephemeralHeaders.has(name.trim().toLowerCase()))) return load();
104
+ return new Response(entry.body, { status: entry.status, statusText: entry.statusText, headers });
105
+ } catch {
106
+ return load();
107
+ }
108
+ }
109
+
110
+ // src/d1/regional-response.ts
111
+ var sensitive = /^(?:cookie|authorization|proxy-authorization|(?:x-)?api-key|(?:x-)?site-token|(?:x-)?site-key|(?:x-)?capability(?:-token)?|x-preview|preview)$/i;
112
+ var ephemeral = /^(?:cf-ray|x-request-id|traceparent|tracestate|cf-connecting-ip|x-forwarded-for)$/i;
113
+ var hop = /^(?:connection|keep-alive|proxy-authenticate|proxy-authorization|te|trailer|transfer-encoding|upgrade)$/i;
114
+ var conditional = /^(?:range|if-match|if-none-match|if-modified-since|if-unmodified-since|if-range)$/i;
115
+ function identity(request) {
116
+ if (request.method !== "GET") return null;
117
+ const url = new URL(request.url);
118
+ if (/(?:^|\/)(?:capability|capabilities)(?:\/|$)/i.test(url.pathname)) return null;
119
+ if ([...url.searchParams.keys()].some((name) => /^(?:preview|token|capability|capability_token)$/i.test(name))) return null;
120
+ if ((request.headers.get("cache-control") ?? "").split(",").some((part) => /^\s*(?:no-cache|no-store)(?:\s*=|\s*$)/i.test(part))) return null;
121
+ const headers = [];
122
+ for (const [name, value] of request.headers) {
123
+ if (sensitive.test(name) || conditional.test(name) || /(?:^|[-_])(?:capability|preview)(?:[-_]|$)/i.test(name)) return null;
124
+ if (!ephemeral.test(name) && name.toLowerCase() !== D1_BOOKMARK_HEADER.toLowerCase()) headers.push([name, value]);
125
+ }
126
+ headers.sort(([a], [b]) => a.localeCompare(b));
127
+ return [url.toString(), headers];
128
+ }
129
+ function eligible(headers) {
130
+ const control = headers.get("cache-control") ?? "";
131
+ const directives = control.split(",").map((part) => part.trim());
132
+ if (!directives.some((part) => /^public$/i.test(part)) || directives.some((part) => /^(?:private|no-store|no-cache)(?:\s*=|$)/i.test(part))) return false;
133
+ if (!directives.some((part) => /^s-maxage\s*=\s*"?[1-9]\d*"?$/i.test(part))) return false;
134
+ for (const [name] of headers) if (hop.test(name)) return false;
135
+ const vary = headers.get("vary");
136
+ return !vary || vary.split(",").every((part) => {
137
+ const name = part.trim();
138
+ return !!name && name !== "*" && !sensitive.test(name) && !ephemeral.test(name) && !conditional.test(name) && !hop.test(name) && !/(?:^|[-_])(?:capability|preview)(?:[-_]|$)/i.test(name);
139
+ });
140
+ }
141
+ function reconstruct(value) {
142
+ if (!value || typeof value !== "object") return null;
143
+ const entry = value;
144
+ if (entry.status !== 200 || typeof entry.statusText !== "string" || typeof entry.body !== "string" || !Array.isArray(entry.headers) || !entry.headers.every((header) => Array.isArray(header) && header.length === 2 && typeof header[0] === "string" && typeof header[1] === "string")) return null;
145
+ try {
146
+ if (new TextEncoder().encode(entry.body).byteLength > 1e6) return null;
147
+ JSON.parse(entry.body);
148
+ const headers = new Headers(entry.headers);
149
+ const length = headers.get("content-length");
150
+ if (length !== null && (!/^(?:0|[1-9]\d*)$/.test(length) || Number(length) !== new TextEncoder().encode(entry.body).byteLength)) return null;
151
+ if (!eligible(headers) || headers.has("set-cookie") || headers.has("content-disposition") || headers.has("content-encoding") || !/^application\/(?:[a-z0-9.+-]*\+)?json(?:\s*;|$)/i.test(headers.get("content-type") ?? "")) return null;
152
+ headers.set("cache-control", "public, max-age=0, must-revalidate");
153
+ return new Response(entry.body, { status: 200, statusText: entry.statusText, headers });
154
+ } catch {
155
+ return null;
156
+ }
157
+ }
158
+ async function cacheRegionalResponse(request, options, load) {
159
+ let requestIdentity2;
160
+ try {
161
+ requestIdentity2 = identity(request);
162
+ } catch {
163
+ return load();
164
+ }
165
+ if (requestIdentity2 === null || typeof options.namespace !== "string" || !options.namespace.trim()) return load();
166
+ const floor = d1SessionBookmarkFloor();
167
+ const key = await regionalKey(options.ttlMs, ["http-response", floor ? "session-v1" : null, options.namespace, options.ttlMs, requestIdentity2]);
168
+ if (!key) return load();
169
+ const cached = await regionalRead(key, options.ttlMs);
170
+ if (cached) {
171
+ const response2 = reconstruct(cached.value);
172
+ if (response2) {
173
+ if (!floor) return response2;
174
+ const raw = response2.headers.get(D1_BOOKMARK_HEADER);
175
+ const source = decodeD1Bookmarks(raw);
176
+ if (raw && source && Object.entries(floor).every(([id, bookmark]) => source[id] && source[id] >= bookmark)) {
177
+ advanceD1SessionBookmarks(source);
178
+ return response2;
179
+ }
180
+ void response2.body?.cancel().catch(() => void 0);
181
+ }
182
+ }
183
+ const started = Date.now();
184
+ const tracked = await trackD1SessionSource(() => runPrimaryD1SessionSource(load));
185
+ let response = tracked.value;
186
+ const bookmarks = responseD1SessionBookmarks(response.headers, tracked.bookmarks);
187
+ if (bookmarks) {
188
+ const headers = new Headers(response.headers);
189
+ const encoded = serializeD1Bookmarks(bookmarks);
190
+ if (encoded) headers.set(D1_BOOKMARK_HEADER, encoded);
191
+ varyD1Bookmarks(headers);
192
+ response = new Response(response.body, { status: response.status, statusText: response.statusText, headers });
193
+ }
194
+ if (!eligible(response.headers)) return response;
195
+ let entry;
196
+ try {
197
+ entry = await responseEntry(response);
198
+ } catch {
199
+ return response;
200
+ }
201
+ if (!entry) return response;
202
+ const output = reconstruct(entry);
203
+ if (!output) return response;
204
+ const sharedAge = (response.headers.get("cache-control") ?? "").split(",").map((part) => /^\s*s-maxage\s*=\s*"?([1-9]\d*)"?\s*$/i.exec(part)).filter((match) => match !== null).map((match) => Number(match[1]));
205
+ const fill = regionalWrite(key, Math.min(options.ttlMs, ...sharedAge.map((age) => age * 1e3)), started, entry);
206
+ if (options.waitUntil) {
207
+ try {
208
+ options.waitUntil(fill);
209
+ } catch {
210
+ await fill;
211
+ }
212
+ } else await fill;
213
+ return output;
214
+ }
215
+
216
+ export { cacheD1JsonRead, cacheRegionalResponse };
217
+ //# sourceMappingURL=index.js.map
218
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/d1/json-read.ts","../../src/d1/regional-response.ts"],"names":["identity","requestIdentity","response"],"mappings":"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","file":"index.js","sourcesContent":["import type { D1Database } from '@cloudflare/workers-types';\nimport { cacheD1Read, type D1ReadOptions } from './read';\n\nconst MAX_BODY_BYTES = 1_000_000;\nconst sensitiveHeaders = new Set(['authorization', 'cookie', 'proxy-authorization', 'x-api-key', 'x-site-token', 'x-capability', 'x-capability-token']);\nconst ephemeralHeaders = new Set(['cf-ray', 'x-request-id', 'traceparent', 'tracestate', 'cf-connecting-ip', 'x-forwarded-for']);\nconst hopHeaders = new Set(['connection', 'keep-alive', 'proxy-authenticate', 'proxy-authorization', 'te', 'trailer', 'transfer-encoding', 'upgrade']);\n\nexport interface D1JsonReadOptions extends Omit<D1ReadOptions<never>, 'cacheable' | 'regionalTtlMs'> {\n request: Request;\n buffered?: true;\n}\n\nexport interface JsonResponseEntry {\n status: number;\n statusText: string;\n headers: [string, string][];\n body: string;\n}\n\nfunction requestIdentity(request: Request): unknown | null {\n if (request.method !== 'GET') return null;\n for (const name of ['range', 'if-match', 'if-none-match', 'if-modified-since', 'if-unmodified-since', 'if-range', 'x-capability', 'x-capability-token', 'x-site-token', 'x-api-key', 'authorization']) if (request.headers.has(name)) return null;\n const url = new URL(request.url);\n if (/(?:^|\\/)(?:capability|capabilities)(?:\\/|$)/i.test(url.pathname)) return null;\n for (const name of url.searchParams.keys()) if (/^(?:preview|token|capability|capability_token)$/i.test(name)) return null;\n const headers = [...request.headers.entries()].filter(([name]) => !sensitiveHeaders.has(name.toLowerCase()) && !ephemeralHeaders.has(name.toLowerCase())).sort(([a], [b]) => a.localeCompare(b));\n return { url: url.toString(), headers };\n}\n\nexport async function responseEntry(response: Response): Promise<JsonResponseEntry | null> {\n if (response.status !== 200 || response.headers.has('set-cookie') || response.headers.has('content-disposition') || response.headers.has('transfer-encoding') || response.headers.has('content-encoding')) return null;\n if (!/^application\\/(?:[a-z0-9.+-]*\\+)?json(?:\\s*;|$)/i.test(response.headers.get('content-type') ?? '')) return null;\n const vary = response.headers.get('vary');\n if (vary && vary.split(',').some((name) => name.trim() === '*' || (sensitiveHeaders.has(name.trim().toLowerCase()) || ephemeralHeaders.has(name.trim().toLowerCase())))) return null;\n const length = response.headers.get('content-length');\n if (length !== null && (!/^(?:0|[1-9]\\d*)$/.test(length) || !Number.isSafeInteger(Number(length)) || Number(length) > MAX_BODY_BYTES)) return null;\n const reader = response.clone().body?.getReader();\n if (!reader) return null;\n const chunks: Uint8Array[] = [];\n let size = 0;\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n const timeout = new Promise<never>((_, reject) => { timer = setTimeout(() => reject(new Error('buffered body timeout')), 1000); });\n for (;;) {\n const next = await Promise.race([reader.read(), timeout]);\n if (next.done) break;\n size += next.value.byteLength;\n if (size > MAX_BODY_BYTES) return null;\n chunks.push(next.value);\n }\n } finally {\n if (timer !== undefined) clearTimeout(timer);\n void reader.cancel().catch(() => undefined);\n }\n if (length !== null && size !== Number(length)) return null;\n const joined = new Uint8Array(size);\n let offset = 0;\n for (const chunk of chunks) { joined.set(chunk, offset); offset += chunk.byteLength; }\n const body = new TextDecoder('utf-8', { fatal: true, ignoreBOM: false }).decode(joined);\n try { JSON.parse(body); } catch { return null; }\n const headers: [string, string][] = [...response.headers.entries()].filter(([name]) => !hopHeaders.has(name.toLowerCase()));\n return { status: response.status, statusText: response.statusText, headers, body };\n}\n\nexport async function cacheD1JsonRead(database: D1Database, options: D1JsonReadOptions, load: () => Promise<Response>): Promise<Response> {\n if (options.buffered !== true) return load();\n let identity: unknown | null;\n try { identity = requestIdentity(options.request); } catch { return load(); }\n if (identity === null) return load();\n let original: Response | undefined;\n const entry = await cacheD1Read<JsonResponseEntry | null>(database, {\n key: ['json-response-v1', options.key, identity],\n scope: options.scope,\n ...(options.dependencies ? { dependencies: options.dependencies } : {}),\n ...(options.ttlMs !== undefined ? { ttlMs: options.ttlMs } : {}),\n cacheable: (value) => value !== null,\n }, async () => {\n original = await load();\n try { return await responseEntry(original); } catch { return null; }\n });\n if (original) return original;\n if (!entry || entry.status !== 200 || typeof entry.statusText !== 'string' || typeof entry.body !== 'string' || !Array.isArray(entry.headers) || !entry.headers.every((header) => Array.isArray(header) && header.length === 2 && typeof header[0] === 'string' && typeof header[1] === 'string' && !hopHeaders.has(header[0].toLowerCase()) && header[0].toLowerCase() !== 'set-cookie' && header[0].toLowerCase() !== 'content-disposition')) return load();\n try {\n JSON.parse(entry.body);\n const headers = new Headers(entry.headers);\n if (headers.has('content-encoding') || !/^application\\/(?:[a-z0-9.+-]*\\+)?json(?:\\s*;|$)/i.test(headers.get('content-type') ?? '')) return load();\n const vary = headers.get('vary');\n if (vary && vary.split(',').some((name) => name.trim() === '*' || sensitiveHeaders.has(name.trim().toLowerCase()) || ephemeralHeaders.has(name.trim().toLowerCase()))) return load();\n return new Response(entry.body, { status: entry.status, statusText: entry.statusText, headers });\n } catch { return load(); }\n}\n","import { responseEntry, type JsonResponseEntry } from './json-read';\nimport { regionalKey, regionalRead, regionalWrite } from './regional';\nimport { D1_BOOKMARK_HEADER, decodeD1Bookmarks, serializeD1Bookmarks } from './bookmarks';\nimport { d1SessionBookmarkFloor, trackD1SessionSource, responseD1SessionBookmarks, advanceD1SessionBookmarks, varyD1Bookmarks, runPrimaryD1SessionSource } from './session';\n\nexport interface RegionalResponseOptions {\n namespace: string;\n ttlMs: number;\n waitUntil?: (promise: Promise<void>) => void;\n}\n\nconst sensitive = /^(?:cookie|authorization|proxy-authorization|(?:x-)?api-key|(?:x-)?site-token|(?:x-)?site-key|(?:x-)?capability(?:-token)?|x-preview|preview)$/i;\nconst ephemeral = /^(?:cf-ray|x-request-id|traceparent|tracestate|cf-connecting-ip|x-forwarded-for)$/i;\nconst hop = /^(?:connection|keep-alive|proxy-authenticate|proxy-authorization|te|trailer|transfer-encoding|upgrade)$/i;\nconst conditional = /^(?:range|if-match|if-none-match|if-modified-since|if-unmodified-since|if-range)$/i;\n\nfunction identity(request: Request): unknown | null {\n if (request.method !== 'GET') return null;\n const url = new URL(request.url);\n if (/(?:^|\\/)(?:capability|capabilities)(?:\\/|$)/i.test(url.pathname)) return null;\n if ([...url.searchParams.keys()].some((name) => /^(?:preview|token|capability|capability_token)$/i.test(name))) return null;\n if ((request.headers.get('cache-control') ?? '').split(',').some((part) => /^\\s*(?:no-cache|no-store)(?:\\s*=|\\s*$)/i.test(part))) return null;\n const headers: [string, string][] = [];\n for (const [name, value] of request.headers) {\n if (sensitive.test(name) || conditional.test(name) || /(?:^|[-_])(?:capability|preview)(?:[-_]|$)/i.test(name)) return null;\n if (!ephemeral.test(name) && name.toLowerCase() !== D1_BOOKMARK_HEADER.toLowerCase()) headers.push([name, value]);\n }\n headers.sort(([a], [b]) => a.localeCompare(b));\n return [url.toString(), headers];\n}\n\nfunction eligible(headers: Headers): boolean {\n const control = headers.get('cache-control') ?? '';\n const directives = control.split(',').map((part) => part.trim());\n if (!directives.some((part) => /^public$/i.test(part)) || directives.some((part) => /^(?:private|no-store|no-cache)(?:\\s*=|$)/i.test(part))) return false;\n if (!directives.some((part) => /^s-maxage\\s*=\\s*\"?[1-9]\\d*\"?$/i.test(part))) return false;\n for (const [name] of headers) if (hop.test(name)) return false;\n const vary = headers.get('vary');\n return !vary || vary.split(',').every((part) => {\n const name = part.trim();\n return !!name && name !== '*' && !sensitive.test(name) && !ephemeral.test(name) && !conditional.test(name) && !hop.test(name) && !/(?:^|[-_])(?:capability|preview)(?:[-_]|$)/i.test(name);\n });\n}\n\nfunction reconstruct(value: unknown): Response | null {\n if (!value || typeof value !== 'object') return null;\n const entry = value as Partial<JsonResponseEntry>;\n if (entry.status !== 200 || typeof entry.statusText !== 'string' || typeof entry.body !== 'string' || !Array.isArray(entry.headers) || !entry.headers.every((header) => Array.isArray(header) && header.length === 2 && typeof header[0] === 'string' && typeof header[1] === 'string')) return null;\n try {\n if (new TextEncoder().encode(entry.body).byteLength > 1_000_000) return null;\n JSON.parse(entry.body);\n const headers = new Headers(entry.headers);\n const length = headers.get('content-length');\n if (length !== null && (!/^(?:0|[1-9]\\d*)$/.test(length) || Number(length) !== new TextEncoder().encode(entry.body).byteLength)) return null;\n if (!eligible(headers) || headers.has('set-cookie') || headers.has('content-disposition') || headers.has('content-encoding') || !/^application\\/(?:[a-z0-9.+-]*\\+)?json(?:\\s*;|$)/i.test(headers.get('content-type') ?? '')) return null;\n headers.set('cache-control', 'public, max-age=0, must-revalidate');\n return new Response(entry.body, { status:200, statusText:entry.statusText, headers });\n } catch { return null; }\n}\n\nexport async function cacheRegionalResponse(request: Request, options: RegionalResponseOptions, load: () => Promise<Response>): Promise<Response> {\n let requestIdentity: unknown | null;\n try { requestIdentity = identity(request); } catch { return load(); }\n if (requestIdentity === null || typeof options.namespace !== 'string' || !options.namespace.trim()) return load();\n const floor = d1SessionBookmarkFloor();\n const key = await regionalKey(options.ttlMs, ['http-response', floor ? 'session-v1' : null, options.namespace, options.ttlMs, requestIdentity]);\n if (!key) return load();\n const cached = await regionalRead(key, options.ttlMs);\n if (cached) {\n const response = reconstruct(cached.value);\n if (response) {\n if (!floor) return response;\n const raw = response.headers.get(D1_BOOKMARK_HEADER);\n const source = decodeD1Bookmarks(raw);\n if (raw && source && Object.entries(floor).every(([id, bookmark]) => source[id] && source[id] >= bookmark)) {\n advanceD1SessionBookmarks(source);\n return response;\n }\n void response.body?.cancel().catch(() => undefined);\n }\n }\n const started = Date.now();\n const tracked = await trackD1SessionSource(() => runPrimaryD1SessionSource(load));\n let response = tracked.value;\n const bookmarks = responseD1SessionBookmarks(response.headers, tracked.bookmarks);\n if (bookmarks) {\n const headers = new Headers(response.headers);\n const encoded = serializeD1Bookmarks(bookmarks);\n if (encoded) headers.set(D1_BOOKMARK_HEADER, encoded);\n varyD1Bookmarks(headers);\n response = new Response(response.body, { status:response.status, statusText:response.statusText, headers });\n }\n if (!eligible(response.headers)) return response;\n let entry: JsonResponseEntry | null;\n try { entry = await responseEntry(response); } catch { return response; }\n if (!entry) return response;\n const output = reconstruct(entry);\n if (!output) return response;\n const sharedAge = (response.headers.get('cache-control') ?? '').split(',').map((part) => /^\\s*s-maxage\\s*=\\s*\"?([1-9]\\d*)\"?\\s*$/i.exec(part)).filter((match): match is RegExpExecArray => match !== null).map((match) => Number(match[1]));\n const fill = regionalWrite(key, Math.min(options.ttlMs, ...sharedAge.map((age) => age * 1000)), started, entry);\n if (options.waitUntil) {\n try { options.waitUntil(fill); } catch { await fill; }\n } else await fill;\n return output;\n}\n"]}
@@ -0,0 +1,9 @@
1
+ import { D as D1CacheProfile } from '../profile--LBtbQI_.js';
2
+ export { f as forwardD1ReadLease, l as limitD1ReadLeaseUntil, w as wrapD1ReadLeaseOrigin } from '../response-lease-DeeM-ofO.js';
3
+ import { R as ReadResponseWarmupOptions } from '../response-warmup-BWQvnT1G.js';
4
+
5
+ declare function wrapD1ReadResponseLease<Env extends object, Context>(handler: (request: Request, env: Env, context: Context) => Promise<Response>, profile: D1CacheProfile, options?: {
6
+ warmup?: ReadResponseWarmupOptions;
7
+ }): (request: Request, env: Env, context: Context) => Promise<Response>;
8
+
9
+ export { wrapD1ReadResponseLease };
@@ -0,0 +1,44 @@
1
+ import { d1CacheRuntime } from '../chunk-LAXBP5DQ.js';
2
+ import '../chunk-NFBMWKY5.js';
3
+ import { createReadResponseLease } from '../chunk-O3KHMFHX.js';
4
+ export { forwardReadLease as forwardD1ReadLease, limitReadResponseLeaseUntil as limitD1ReadLeaseUntil, wrapReadResponseLeaseOrigin as wrapD1ReadLeaseOrigin } from '../chunk-O3KHMFHX.js';
5
+ import '../chunk-JPK2AF7X.js';
6
+ import '../chunk-A4WV6RY4.js';
7
+ import '../chunk-WJNCFFF3.js';
8
+ import '../chunk-LHOK33GI.js';
9
+ import '../chunk-M4UOCIDQ.js';
10
+ import '../chunk-ZBYAKDNZ.js';
11
+ import '../chunk-WKZ7TKGM.js';
12
+ import '../chunk-E6OZZ5UX.js';
13
+ import '../chunk-OQRNVGQE.js';
14
+ import '../chunk-ZCMZJKGN.js';
15
+ import { isD1BindingName } from '../chunk-AENVFT2S.js';
16
+
17
+ // src/d1/read-response-lease.ts
18
+ function wrapD1ReadResponseLease(handler, profile, options) {
19
+ return createReadResponseLease(handler, (env) => {
20
+ const config = profile.readResponseLease;
21
+ if (!config) return null;
22
+ const rawSeconds = Reflect.get(env, `${profile.envPrefix}_READ_ACCESS_SECONDS`);
23
+ const seconds = typeof rawSeconds === "string" && /^(?:0|[1-9]\d{0,2})$/.test(rawSeconds) ? Number(rawSeconds) : 0;
24
+ const release = Reflect.get(env, config.deploymentEnv);
25
+ const database = Reflect.get(env, config.databaseBinding);
26
+ const runtime = database && typeof database === "object" ? d1CacheRuntime(database) : void 0;
27
+ if (!isD1BindingName(config.databaseBinding, profile) || typeof release !== "string" || !release.trim() || !runtime?.readsEnabled || !runtime.regionalIdentity) return null;
28
+ return { config: options?.warmup ? { ...config, warmup: options.warmup } : config, seconds, identity: () => {
29
+ const identities = [];
30
+ for (const [name, value] of Object.entries(env)) {
31
+ if (!isD1BindingName(name, profile)) continue;
32
+ const dependency = value && typeof value === "object" ? d1CacheRuntime(value) : void 0;
33
+ if (!dependency?.readsEnabled || !dependency.regionalIdentity) return null;
34
+ identities.push([name, dependency.databaseId, dependency.generation, dependency.coordinatorName, dependency.regionalIdentity]);
35
+ }
36
+ identities.sort((a, b) => String(a).localeCompare(String(b)));
37
+ return ["d1-response-lease-v2", profile, release, identities];
38
+ } };
39
+ });
40
+ }
41
+
42
+ export { wrapD1ReadResponseLease };
43
+ //# sourceMappingURL=response-lease.js.map
44
+ //# sourceMappingURL=response-lease.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/d1/read-response-lease.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAMO,SAAS,uBAAA,CAAqD,OAAA,EAA8E,OAAA,EAAyB,OAAA,EAAuH;AACjS,EAAA,OAAO,uBAAA,CAAwB,OAAA,EAAS,CAAC,GAAA,KAAQ;AAC/C,IAAA,MAAM,SAAS,OAAA,CAAQ,iBAAA;AACvB,IAAA,IAAI,CAAC,QAAQ,OAAO,IAAA;AACpB,IAAA,MAAM,aAAsB,OAAA,CAAQ,GAAA,CAAI,KAAK,CAAA,EAAG,OAAA,CAAQ,SAAS,CAAA,oBAAA,CAAsB,CAAA;AACvF,IAAA,MAAM,OAAA,GAAU,OAAO,UAAA,KAAe,QAAA,IAAY,sBAAA,CAAuB,KAAK,UAAU,CAAA,GAAI,MAAA,CAAO,UAAU,CAAA,GAAI,CAAA;AACjH,IAAA,MAAM,OAAA,GAAmB,OAAA,CAAQ,GAAA,CAAI,GAAA,EAAK,OAAO,aAAa,CAAA;AAC9D,IAAA,MAAM,QAAA,GAAoB,OAAA,CAAQ,GAAA,CAAI,GAAA,EAAK,OAAO,eAAe,CAAA;AACjE,IAAA,MAAM,UAAU,QAAA,IAAY,OAAO,aAAa,QAAA,GAAW,cAAA,CAAe,QAAQ,CAAA,GAAI,MAAA;AACtF,IAAA,IAAI,CAAC,eAAA,CAAgB,MAAA,CAAO,iBAAiB,OAAO,CAAA,IAAK,OAAO,OAAA,KAAY,QAAA,IAAY,CAAC,OAAA,CAAQ,IAAA,MAAU,CAAC,OAAA,EAAS,gBAAgB,CAAC,OAAA,CAAQ,kBAAkB,OAAO,IAAA;AACvK,IAAA,OAAO,EAAE,MAAA,EAAQ,OAAA,EAAS,MAAA,GAAS,EAAE,GAAG,MAAA,EAAQ,MAAA,EAAO,OAAA,CAAQ,MAAA,EAAO,GAAI,MAAA,EAAQ,OAAA,EAAS,UAAU,MAAM;AACzG,MAAA,MAAM,aAAwB,EAAC;AAC/B,MAAA,KAAA,MAAW,CAAC,IAAA,EAAM,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,GAAG,CAAA,EAAG;AAC/C,QAAA,IAAI,CAAC,eAAA,CAAgB,IAAA,EAAM,OAAO,CAAA,EAAG;AACrC,QAAA,MAAM,aAAa,KAAA,IAAS,OAAO,UAAU,QAAA,GAAW,cAAA,CAAe,KAAK,CAAA,GAAI,MAAA;AAChF,QAAA,IAAI,CAAC,UAAA,EAAY,YAAA,IAAgB,CAAC,UAAA,CAAW,kBAAkB,OAAO,IAAA;AACtE,QAAA,UAAA,CAAW,IAAA,CAAK,CAAC,IAAA,EAAM,UAAA,CAAW,UAAA,EAAY,UAAA,CAAW,UAAA,EAAY,UAAA,CAAW,eAAA,EAAiB,UAAA,CAAW,gBAAgB,CAAC,CAAA;AAAA,MAC/H;AACA,MAAA,UAAA,CAAW,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,MAAA,CAAO,CAAC,CAAA,CAAE,aAAA,CAAc,MAAA,CAAO,CAAC,CAAC,CAAC,CAAA;AAC5D,MAAA,OAAO,CAAC,sBAAA,EAAwB,OAAA,EAAS,OAAA,EAAS,UAAU,CAAA;AAAA,IAC9D,CAAA,EAAE;AAAA,EACJ,CAAC,CAAA;AACH","file":"response-lease.js","sourcesContent":["import { d1CacheRuntime } from './env';\nimport { isD1BindingName, type D1CacheProfile } from './profile';\nimport { createReadResponseLease, type ReadResponseWarmupOptions } from '../response-lease';\n\nexport { limitReadResponseLeaseUntil as limitD1ReadLeaseUntil, wrapReadResponseLeaseOrigin as wrapD1ReadLeaseOrigin, forwardReadLease as forwardD1ReadLease } from '../response-lease';\n\nexport function wrapD1ReadResponseLease<Env extends object, Context>(handler: (request: Request, env: Env, context: Context) => Promise<Response>, profile: D1CacheProfile, options?: { warmup?: ReadResponseWarmupOptions }): (request: Request, env: Env, context: Context) => Promise<Response> {\n return createReadResponseLease(handler, (env) => {\n const config = profile.readResponseLease;\n if (!config) return null;\n const rawSeconds: unknown = Reflect.get(env, `${profile.envPrefix}_READ_ACCESS_SECONDS`);\n const seconds = typeof rawSeconds === 'string' && /^(?:0|[1-9]\\d{0,2})$/.test(rawSeconds) ? Number(rawSeconds) : 0;\n const release: unknown = Reflect.get(env, config.deploymentEnv);\n const database: unknown = Reflect.get(env, config.databaseBinding);\n const runtime = database && typeof database === 'object' ? d1CacheRuntime(database) : undefined;\n if (!isD1BindingName(config.databaseBinding, profile) || typeof release !== 'string' || !release.trim() || !runtime?.readsEnabled || !runtime.regionalIdentity) return null;\n return { config: options?.warmup ? { ...config, warmup:options.warmup } : config, seconds, identity: () => {\n const identities: unknown[] = [];\n for (const [name, value] of Object.entries(env)) {\n if (!isD1BindingName(name, profile)) continue;\n const dependency = value && typeof value === 'object' ? d1CacheRuntime(value) : undefined;\n if (!dependency?.readsEnabled || !dependency.regionalIdentity) return null;\n identities.push([name, dependency.databaseId, dependency.generation, dependency.coordinatorName, dependency.regionalIdentity]);\n }\n identities.sort((a, b) => String(a).localeCompare(String(b)));\n return ['d1-response-lease-v2', profile, release, identities];\n } };\n });\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { d as CacheExtensionOptions, I as InvalidationTarget } from './types-DwtU0KpX.js';
2
- export { e as CacheShape, C as CacheStore, f as CacheTestHooks, D as DecimalConstructor, G as GeneratedCacheConfig, g as RelationInfo } from './types-DwtU0KpX.js';
1
+ import { f as CacheExtensionOptions, g as InvalidationTarget } from './types-CtErcz2a.js';
2
+ export { h as CacheShape, C as CacheStore, i as CacheTestHooks, D as DecimalConstructor, G as GeneratedCacheConfig, I as InspectFencesRequest, a as InspectFencesResponse, j as RelationInfo } from './types-CtErcz2a.js';
3
3
 
4
4
  declare class CacheUnavailableError extends Error {
5
5
  constructor(cause: unknown);