@vinext/cloudflare 1.0.0-beta.7 → 1.0.0-beta.9
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/README.md +64 -22
- package/dist/cache/cdn-adapter-config.d.ts +16 -8
- package/dist/cache/cdn-adapter-config.js +57 -17
- package/dist/cache/cdn-adapter.d.ts +25 -24
- package/dist/cache/cdn-adapter.js +24 -20
- package/dist/cache/cdn-adapter.runtime.d.ts +9 -3
- package/dist/cache/cdn-adapter.runtime.js +63 -40
- package/dist/cache/cdn-adapter.worker.d.ts +31 -0
- package/dist/cache/cdn-adapter.worker.js +373 -0
- package/dist/cache/cdn-build-id.d.ts +4 -3
- package/dist/cache/cdn-build-id.js +5 -1
- package/dist/cache/kv-data-adapter.d.ts +25 -5
- package/dist/cache/kv-data-adapter.js +5 -1
- package/dist/cache/kv-data-adapter.runtime.d.ts +38 -4
- package/dist/cache/kv-data-adapter.runtime.js +115 -41
- package/dist/cache/kv-key.d.ts +4 -5
- package/dist/cache/response-store-adapter.d.ts +70 -0
- package/dist/cache/response-store-adapter.js +45 -0
- package/dist/cache/response-store-adapter.self-contained.worker.d.ts +18 -0
- package/dist/cache/response-store-adapter.self-contained.worker.js +12 -0
- package/dist/cache/response-store-adapter.service-binding.worker.d.ts +16 -0
- package/dist/cache/response-store-adapter.service-binding.worker.js +11 -0
- package/dist/cache/response-store-adapter.worker.d.ts +14 -0
- package/dist/cache/response-store-adapter.worker.js +264 -0
- package/dist/cache/response-store-cdn.runtime.d.ts +5 -0
- package/dist/cache/response-store-cdn.runtime.js +41 -0
- package/dist/cache/response-store-data.runtime.d.ts +34 -0
- package/dist/cache/response-store-data.runtime.js +289 -0
- package/dist/cacheability-artifact.d.ts +2 -3
- package/dist/cacheability-artifact.js +27 -1
- package/dist/cacheability-manifest-limits.d.ts +3 -4
- package/dist/cacheability-manifest-limits.js +1 -1
- package/dist/cacheability-probe.d.ts +8 -9
- package/dist/cacheability-probe.js +255 -91
- package/dist/cdn-warm.d.ts +31 -25
- package/dist/cdn-warm.js +228 -54
- package/dist/deploy-config.d.ts +11 -12
- package/dist/deploy-config.js +8 -3
- package/dist/deploy-help.d.ts +3 -4
- package/dist/deploy-help.js +20 -14
- package/dist/deploy.d.ts +35 -28
- package/dist/deploy.js +204 -95
- package/dist/images/images-optimizer.d.ts +3 -4
- package/dist/prerender-kv-populate.d.ts +3 -4
- package/dist/prerender-kv-populate.js +3 -2
- package/dist/tpr.d.ts +26 -74
- package/dist/tpr.js +45 -603
- package/dist/utils/cache-control-metadata.d.ts +3 -4
- package/dist/version-deploy.d.ts +17 -17
- package/dist/version-deploy.js +10 -5
- package/dist/worker-deployment-url.d.ts +3 -4
- package/dist/workers-dev-url.d.ts +2 -3
- package/dist/wrangler-config.d.ts +19 -0
- package/dist/wrangler-config.js +294 -0
- package/dist/wrangler-version-metadata.d.ts +2 -3
- package/package.json +13 -11
|
@@ -28,6 +28,10 @@ const DEFAULT_BINDING = "VINEXT_KV_CACHE";
|
|
|
28
28
|
const PATH_TAG_PREFIX = "_N_T_";
|
|
29
29
|
/** Max tag length to prevent KV key abuse. */
|
|
30
30
|
const MAX_TAG_LENGTH = 256;
|
|
31
|
+
/** The runtime rejects a lower `cacheTtl` with "Cache TTL must be at least 30". */
|
|
32
|
+
const MIN_KV_CACHE_TTL_SECONDS = 30;
|
|
33
|
+
/** Cloudflare caps a bulk `get()` at 100 keys per call. */
|
|
34
|
+
const KV_BULK_GET_LIMIT = 100;
|
|
31
35
|
/** Matches a valid base64 string (standard alphabet with optional padding). */
|
|
32
36
|
const BASE64_RE = /^[A-Za-z0-9+/]*={0,2}$/;
|
|
33
37
|
/**
|
|
@@ -98,14 +102,20 @@ var KVCacheHandler = class {
|
|
|
98
102
|
ttlSeconds;
|
|
99
103
|
/** Local in-memory cache for tag invalidation timestamps. Avoids redundant KV reads. */
|
|
100
104
|
_tagCache = /* @__PURE__ */ new Map();
|
|
105
|
+
/** Monotonic ordering for concurrent tag-cache fills and local invalidations. */
|
|
106
|
+
_tagCacheOrder = 0;
|
|
101
107
|
/** TTL (ms) for local tag cache entries. After this, re-fetch from KV. */
|
|
102
108
|
_tagCacheTtl;
|
|
109
|
+
/** Read options for entry keys only. `undefined` keeps the KV default cacheTtl. */
|
|
110
|
+
_entryReadOptions;
|
|
103
111
|
constructor(kvNamespace, options) {
|
|
104
112
|
this.kv = kvNamespace;
|
|
105
113
|
this.keySpace = createKvKeySpace(options?.appPrefix);
|
|
106
114
|
this.ctx = options?.ctx;
|
|
107
|
-
this.ttlSeconds = options?.ttlSeconds ??
|
|
115
|
+
this.ttlSeconds = options?.ttlSeconds ?? 2592e3;
|
|
108
116
|
this._tagCacheTtl = options?.tagCacheTtlMs ?? 5e3;
|
|
117
|
+
const entryCacheTtl = options?.entryCacheTtlSeconds;
|
|
118
|
+
this._entryReadOptions = typeof entryCacheTtl === "number" && Number.isFinite(entryCacheTtl) ? { cacheTtl: Math.max(MIN_KV_CACHE_TTL_SECONDS, Math.floor(entryCacheTtl)) } : void 0;
|
|
109
119
|
}
|
|
110
120
|
_entryKey(key) {
|
|
111
121
|
return this.keySpace.entryKey(key);
|
|
@@ -115,37 +125,64 @@ var KVCacheHandler = class {
|
|
|
115
125
|
}
|
|
116
126
|
async get(key, _ctx) {
|
|
117
127
|
const kvKey = this._entryKey(key);
|
|
118
|
-
const
|
|
128
|
+
const softTags = validUniqueTags(readStringArrayField(_ctx, "softTags"));
|
|
129
|
+
const entryRead = this._entryReadOptions ? this.kv.get(kvKey, this._entryReadOptions) : this.kv.get(kvKey);
|
|
130
|
+
let softTagCache = this._tagCache;
|
|
131
|
+
const softTagPrime = this._primeTagCache(softTags);
|
|
132
|
+
if (softTags.length > 0) {
|
|
133
|
+
const backgroundPrime = softTagPrime.catch(() => {});
|
|
134
|
+
const ctx = getRequestExecutionContext() ?? this.ctx;
|
|
135
|
+
if (ctx) ctx.waitUntil(backgroundPrime);
|
|
136
|
+
}
|
|
137
|
+
const raw = await entryRead;
|
|
119
138
|
if (!raw) return null;
|
|
120
139
|
let parsed;
|
|
121
140
|
try {
|
|
122
141
|
parsed = JSON.parse(raw);
|
|
123
142
|
} catch {
|
|
124
|
-
this.
|
|
143
|
+
this._deleteEntryReadInBackground(kvKey);
|
|
125
144
|
return null;
|
|
126
145
|
}
|
|
127
146
|
const entry = validateCacheEntry(parsed);
|
|
128
147
|
if (!entry) {
|
|
129
148
|
console.error("[vinext] Invalid cache entry shape for key:", key);
|
|
130
|
-
this.
|
|
149
|
+
this._deleteEntryReadInBackground(kvKey);
|
|
131
150
|
return null;
|
|
132
151
|
}
|
|
133
152
|
let restoredValue = null;
|
|
134
153
|
if (entry.value) {
|
|
135
154
|
restoredValue = restoreArrayBuffers(entry.value);
|
|
136
155
|
if (!restoredValue) {
|
|
137
|
-
this.
|
|
156
|
+
this._deleteEntryReadInBackground(kvKey);
|
|
138
157
|
return null;
|
|
139
158
|
}
|
|
140
159
|
}
|
|
141
|
-
|
|
142
|
-
|
|
160
|
+
const entryTags = validUniqueTags(entry.tags);
|
|
161
|
+
if (this._hasRevalidatedTag(entryTags, entry.lastModified, true)) {
|
|
162
|
+
this._deleteEntryReadInBackground(kvKey);
|
|
143
163
|
return null;
|
|
144
164
|
}
|
|
145
|
-
|
|
146
|
-
|
|
165
|
+
await softTagPrime;
|
|
166
|
+
while (softTagCache !== this._tagCache) {
|
|
167
|
+
softTagCache = this._tagCache;
|
|
168
|
+
await this._primeTagCache(softTags);
|
|
169
|
+
}
|
|
170
|
+
let invalidated = this._hasRevalidatedTag(entryTags, entry.lastModified, true);
|
|
171
|
+
if (!invalidated) {
|
|
172
|
+
await this._primeTagCache(entryTags);
|
|
173
|
+
while (softTagCache !== this._tagCache) {
|
|
174
|
+
softTagCache = this._tagCache;
|
|
175
|
+
await this._primeTagCache([.../* @__PURE__ */ new Set([...softTags, ...entryTags])]);
|
|
176
|
+
}
|
|
177
|
+
invalidated = this._hasRevalidatedTag(entryTags, entry.lastModified);
|
|
178
|
+
}
|
|
179
|
+
if (invalidated) {
|
|
180
|
+
this._deleteEntryReadInBackground(kvKey);
|
|
181
|
+
return null;
|
|
182
|
+
}
|
|
183
|
+
if (this._hasRevalidatedTag(softTags, entry.lastModified)) return null;
|
|
147
184
|
if (entry.expireAt !== void 0 && entry.expireAt !== null && Date.now() > entry.expireAt) {
|
|
148
|
-
this.
|
|
185
|
+
this._deleteEntryReadInBackground(kvKey);
|
|
149
186
|
return null;
|
|
150
187
|
}
|
|
151
188
|
const now = Date.now();
|
|
@@ -164,37 +201,63 @@ var KVCacheHandler = class {
|
|
|
164
201
|
};
|
|
165
202
|
}
|
|
166
203
|
/**
|
|
167
|
-
*
|
|
168
|
-
*
|
|
204
|
+
* Load the invalidation markers these tags still need into the local cache.
|
|
205
|
+
* Tags a recent read already cached cost nothing, so the entry-tag batch only
|
|
206
|
+
* pays for what the soft-tag batch did not already fetch.
|
|
169
207
|
*/
|
|
170
|
-
async
|
|
171
|
-
if (tags.length === 0) return
|
|
208
|
+
async _primeTagCache(tags) {
|
|
209
|
+
if (tags.length === 0) return;
|
|
210
|
+
const tagCache = this._tagCache;
|
|
172
211
|
const now = Date.now();
|
|
173
|
-
const
|
|
212
|
+
const missing = tags.filter((tag) => {
|
|
213
|
+
const cached = tagCache.get(tag);
|
|
214
|
+
if (cached && now - cached.fetchedAt < this._tagCacheTtl) return false;
|
|
215
|
+
if (cached) tagCache.delete(tag);
|
|
216
|
+
return true;
|
|
217
|
+
});
|
|
218
|
+
if (missing.length === 0) return;
|
|
219
|
+
const order = ++this._tagCacheOrder;
|
|
220
|
+
const markers = await this._readTagMarkers(missing.map((tag) => this._tagKey(tag)));
|
|
221
|
+
for (const tag of missing) {
|
|
222
|
+
const current = tagCache.get(tag);
|
|
223
|
+
if (current && current.order >= order) continue;
|
|
224
|
+
const marker = markers.get(this._tagKey(tag));
|
|
225
|
+
tagCache.set(tag, {
|
|
226
|
+
timestamp: marker ? Number(marker) : 0,
|
|
227
|
+
fetchedAt: now,
|
|
228
|
+
order
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Read every marker key, one round trip per 100-key chunk.
|
|
234
|
+
*
|
|
235
|
+
* Markers never take the entry `cacheTtl`: `revalidateTag()` writes them, so
|
|
236
|
+
* a longer colo cache would hide a publish from that colo for its span. They
|
|
237
|
+
* keep KV's own default cacheTtl of 60 s.
|
|
238
|
+
*/
|
|
239
|
+
async _readTagMarkers(keys) {
|
|
240
|
+
if (keys.length === 1) return /* @__PURE__ */ new Map([[keys[0], await this.kv.get(keys[0])]]);
|
|
241
|
+
const chunks = [];
|
|
242
|
+
for (let i = 0; i < keys.length; i += KV_BULK_GET_LIMIT) chunks.push(keys.slice(i, i + KV_BULK_GET_LIMIT));
|
|
243
|
+
const results = await Promise.all(chunks.map((chunk) => this.kv.get(chunk)));
|
|
244
|
+
const markers = /* @__PURE__ */ new Map();
|
|
245
|
+
for (const result of results) for (const [key, value] of result) markers.set(key, value);
|
|
246
|
+
return markers;
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Report whether any tag has an invalidation marker at or after `lastModified`.
|
|
250
|
+
* Call `_primeTagCache` for the same tags first — a tag with no cache entry
|
|
251
|
+
* counts as never invalidated. Pass `requireFresh` to call it before a prime,
|
|
252
|
+
* so an entry past `tagCacheTtlMs` does not answer for a tag it never re-read.
|
|
253
|
+
*/
|
|
254
|
+
_hasRevalidatedTag(tags, lastModified, requireFresh = false) {
|
|
255
|
+
const now = requireFresh ? Date.now() : 0;
|
|
174
256
|
for (const tag of tags) {
|
|
175
257
|
const cached = this._tagCache.get(tag);
|
|
176
|
-
if (cached
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
if (cached) this._tagCache.delete(tag);
|
|
180
|
-
uncachedTags.push(tag);
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
if (uncachedTags.length > 0) {
|
|
184
|
-
const tagResults = await Promise.all(uncachedTags.map((tag) => this.kv.get(this._tagKey(tag))));
|
|
185
|
-
for (let i = 0; i < uncachedTags.length; i++) {
|
|
186
|
-
const tagTime = tagResults[i];
|
|
187
|
-
const tagTimestamp = tagTime ? Number(tagTime) : 0;
|
|
188
|
-
this._tagCache.set(uncachedTags[i], {
|
|
189
|
-
timestamp: tagTimestamp,
|
|
190
|
-
fetchedAt: now
|
|
191
|
-
});
|
|
192
|
-
}
|
|
193
|
-
for (const tag of uncachedTags) {
|
|
194
|
-
const cached = this._tagCache.get(tag);
|
|
195
|
-
if (!cached || cached.timestamp === 0) continue;
|
|
196
|
-
if (Number.isNaN(cached.timestamp) || cached.timestamp >= lastModified) return true;
|
|
197
|
-
}
|
|
258
|
+
if (!cached || cached.timestamp === 0) continue;
|
|
259
|
+
if (requireFresh && now - cached.fetchedAt >= this._tagCacheTtl) continue;
|
|
260
|
+
if (Number.isNaN(cached.timestamp) || cached.timestamp >= lastModified) return true;
|
|
198
261
|
}
|
|
199
262
|
return false;
|
|
200
263
|
}
|
|
@@ -243,10 +306,12 @@ var KVCacheHandler = class {
|
|
|
243
306
|
const tagList = Array.isArray(tags) ? tags : [tags];
|
|
244
307
|
const now = Date.now();
|
|
245
308
|
const validTags = tagList.filter((t) => validateTag(t) !== null);
|
|
246
|
-
await Promise.all(validTags.map((tag) => this.kv.put(this._tagKey(tag), String(now), { expirationTtl:
|
|
309
|
+
await Promise.all(validTags.map((tag) => this.kv.put(this._tagKey(tag), String(now), { expirationTtl: 2592e3 })));
|
|
310
|
+
const order = ++this._tagCacheOrder;
|
|
247
311
|
for (const tag of validTags) this._tagCache.set(tag, {
|
|
248
312
|
timestamp: now,
|
|
249
|
-
fetchedAt: now
|
|
313
|
+
fetchedAt: now,
|
|
314
|
+
order
|
|
250
315
|
});
|
|
251
316
|
}
|
|
252
317
|
/**
|
|
@@ -302,7 +367,15 @@ var KVCacheHandler = class {
|
|
|
302
367
|
* fresh KVCacheHandler per request or invoke this method explicitly.
|
|
303
368
|
*/
|
|
304
369
|
resetRequestCache() {
|
|
305
|
-
this._tagCache
|
|
370
|
+
this._tagCache = /* @__PURE__ */ new Map();
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Clean up a bad entry only when this read cannot be an explicitly cached
|
|
374
|
+
* older version of the shared KV value. KV has no conditional delete, so a
|
|
375
|
+
* cached read must remain a non-destructive miss.
|
|
376
|
+
*/
|
|
377
|
+
_deleteEntryReadInBackground(kvKey) {
|
|
378
|
+
if (!this._entryReadOptions) this._deleteInBackground(kvKey);
|
|
306
379
|
}
|
|
307
380
|
/**
|
|
308
381
|
* Fire a KV delete in the background.
|
|
@@ -453,7 +526,8 @@ const createKvDataCacheAdapter = ({ env, options }) => {
|
|
|
453
526
|
return new KVCacheHandler(namespace, {
|
|
454
527
|
appPrefix: options?.appPrefix,
|
|
455
528
|
ttlSeconds: options?.ttlSeconds,
|
|
456
|
-
tagCacheTtlMs: options?.tagCacheTtlMs
|
|
529
|
+
tagCacheTtlMs: options?.tagCacheTtlMs,
|
|
530
|
+
entryCacheTtlSeconds: options?.entryCacheTtlSeconds
|
|
457
531
|
});
|
|
458
532
|
};
|
|
459
533
|
//#endregion
|
package/dist/cache/kv-key.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
//#region src/cache/kv-key.d.ts
|
|
2
2
|
/** Key prefix for cache entries. */
|
|
3
|
-
declare const ENTRY_PREFIX = "cache:";
|
|
4
|
-
type KvKeySpace = {
|
|
3
|
+
export declare const ENTRY_PREFIX = "cache:";
|
|
4
|
+
export type KvKeySpace = {
|
|
5
5
|
/** Prefix shared by every cache entry, including entries with hashed logical keys. */
|
|
6
6
|
entryPrefix: string;
|
|
7
7
|
entryKey(logicalKey: string): string;
|
|
@@ -11,6 +11,5 @@ type KvKeySpace = {
|
|
|
11
11
|
* Create the deterministic key namespace shared by runtime cache operations
|
|
12
12
|
* and deploy-time prerender population.
|
|
13
13
|
*/
|
|
14
|
-
declare function createKvKeySpace(appPrefix: string | undefined): KvKeySpace;
|
|
15
|
-
//#endregion
|
|
16
|
-
export { ENTRY_PREFIX, KvKeySpace, createKvKeySpace };
|
|
14
|
+
export declare function createKvKeySpace(appPrefix: string | undefined): KvKeySpace;
|
|
15
|
+
//#endregion
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
//#region src/cache/response-store-adapter.d.ts
|
|
2
|
+
export type ResponseStoreAdapterOptions = {
|
|
3
|
+
mode?: "self-contained" | "service-binding";
|
|
4
|
+
/** Split version-scoped metadata across this many Durable Objects. */
|
|
5
|
+
shards?: number;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Use Workers Response Store for both vinext response-stage and data caching.
|
|
9
|
+
* Service-binding mode keeps storage in a separate cache Worker. Self-contained
|
|
10
|
+
* mode keeps the same API and loopback in the application Worker.
|
|
11
|
+
*/
|
|
12
|
+
export declare function responseStoreAdapter(options?: ResponseStoreAdapterOptions): {
|
|
13
|
+
cdn: {
|
|
14
|
+
options?: undefined;
|
|
15
|
+
adapter: string;
|
|
16
|
+
output: {
|
|
17
|
+
entry: string;
|
|
18
|
+
matchesBuild({ plugins }: {
|
|
19
|
+
plugins: readonly {
|
|
20
|
+
name?: string;
|
|
21
|
+
}[];
|
|
22
|
+
}): boolean;
|
|
23
|
+
transformHostEntry({ code, id }: {
|
|
24
|
+
code: string;
|
|
25
|
+
id: string;
|
|
26
|
+
}): string | null;
|
|
27
|
+
type: "multi-stage";
|
|
28
|
+
};
|
|
29
|
+
capabilities: {
|
|
30
|
+
buildIdentity: "response-header";
|
|
31
|
+
isResponsePolicyHeader: (name: string) => boolean;
|
|
32
|
+
requestRouting: "uncached-stage";
|
|
33
|
+
warmup: "response-store";
|
|
34
|
+
};
|
|
35
|
+
} | {
|
|
36
|
+
options: {
|
|
37
|
+
shards: number;
|
|
38
|
+
};
|
|
39
|
+
adapter: string;
|
|
40
|
+
output: {
|
|
41
|
+
entry: string;
|
|
42
|
+
matchesBuild({ plugins }: {
|
|
43
|
+
plugins: readonly {
|
|
44
|
+
name?: string;
|
|
45
|
+
}[];
|
|
46
|
+
}): boolean;
|
|
47
|
+
transformHostEntry({ code, id }: {
|
|
48
|
+
code: string;
|
|
49
|
+
id: string;
|
|
50
|
+
}): string | null;
|
|
51
|
+
type: "multi-stage";
|
|
52
|
+
};
|
|
53
|
+
capabilities: {
|
|
54
|
+
buildIdentity: "response-header";
|
|
55
|
+
isResponsePolicyHeader: (name: string) => boolean;
|
|
56
|
+
requestRouting: "uncached-stage";
|
|
57
|
+
warmup: "response-store";
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
data: {
|
|
61
|
+
options?: undefined;
|
|
62
|
+
adapter: string;
|
|
63
|
+
} | {
|
|
64
|
+
options: {
|
|
65
|
+
shards: number;
|
|
66
|
+
};
|
|
67
|
+
adapter: string;
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
//#endregion
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { fileURLToPath } from "node:url";
|
|
2
|
+
//#region src/cache/response-store-adapter.ts
|
|
3
|
+
const CLOUDFLARE_WORKER_ENTRY_ID = "virtual:cloudflare/worker-entry";
|
|
4
|
+
/**
|
|
5
|
+
* Use Workers Response Store for both vinext response-stage and data caching.
|
|
6
|
+
* Service-binding mode keeps storage in a separate cache Worker. Self-contained
|
|
7
|
+
* mode keeps the same API and loopback in the application Worker.
|
|
8
|
+
*/
|
|
9
|
+
function responseStoreAdapter(options = {}) {
|
|
10
|
+
const mode = options.mode ?? "service-binding";
|
|
11
|
+
if (mode !== "service-binding" && mode !== "self-contained") throw new Error(`Unknown Workers Response Store mode: ${String(mode)}`);
|
|
12
|
+
if (options.shards !== void 0 && (!Number.isSafeInteger(options.shards) || options.shards <= 1)) throw new TypeError("Workers Response Store shards must be an integer greater than 1");
|
|
13
|
+
const runtimeOptions = options.shards === void 0 ? {} : { options: { shards: options.shards } };
|
|
14
|
+
const workerEntry = fileURLToPath(import.meta.resolve(mode === "self-contained" ? "./response-store-adapter.self-contained.worker.js" : "./response-store-adapter.service-binding.worker.js"));
|
|
15
|
+
const entrypoints = mode === "self-contained" ? "CacheMetadata, ResponseStoreBinding, ResponseStoreRevalidator" : "ResponseStoreClient, ResponseStoreRevalidator";
|
|
16
|
+
return {
|
|
17
|
+
cdn: {
|
|
18
|
+
adapter: fileURLToPath(import.meta.resolve("./response-store-cdn.runtime.js")),
|
|
19
|
+
...runtimeOptions,
|
|
20
|
+
output: {
|
|
21
|
+
entry: workerEntry,
|
|
22
|
+
matchesBuild({ plugins }) {
|
|
23
|
+
return plugins.some(({ name }) => name === "vite-plugin-cloudflare" || name?.startsWith("vite-plugin-cloudflare:"));
|
|
24
|
+
},
|
|
25
|
+
transformHostEntry({ code, id }) {
|
|
26
|
+
if ((id.charCodeAt(0) === 0 ? id.slice(1) : id) !== CLOUDFLARE_WORKER_ENTRY_ID) return null;
|
|
27
|
+
return `${code}\nexport { ${entrypoints} } from ${JSON.stringify(workerEntry)};\n`;
|
|
28
|
+
},
|
|
29
|
+
type: "multi-stage"
|
|
30
|
+
},
|
|
31
|
+
capabilities: {
|
|
32
|
+
buildIdentity: "response-header",
|
|
33
|
+
isResponsePolicyHeader: (name) => name.toLowerCase() === "cdn-cache-control" || name.toLowerCase() === "cloudflare-cdn-cache-control",
|
|
34
|
+
requestRouting: "uncached-stage",
|
|
35
|
+
warmup: "response-store"
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
data: {
|
|
39
|
+
adapter: fileURLToPath(import.meta.resolve("./response-store-data.runtime.js")),
|
|
40
|
+
...runtimeOptions
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
//#endregion
|
|
45
|
+
export { responseStoreAdapter };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { VinextResponseStoreEnv } from "./response-store-adapter.worker.js";
|
|
2
|
+
import "vinext/internal/server/cloudflare-workers-tracing";
|
|
3
|
+
import { ResponseStoreRevalidatorEntrypoint, WorkersResponseStoreEnv } from "@cloudflare/workers-response-store";
|
|
4
|
+
import { CacheMetadata as CacheMetadata$1, ResponseStoreBinding as ResponseStoreBinding$1 } from "@cloudflare/workers-response-store/service";
|
|
5
|
+
//#region src/cache/response-store-adapter.self-contained.worker.d.ts
|
|
6
|
+
export declare const CacheMetadata: typeof CacheMetadata$1;
|
|
7
|
+
export declare const ResponseStoreBinding: typeof ResponseStoreBinding$1;
|
|
8
|
+
export declare const ResponseStoreRevalidator: ResponseStoreRevalidatorEntrypoint<WorkersResponseStoreEnv>;
|
|
9
|
+
declare const _default: {
|
|
10
|
+
fetch(request: Request, env: VinextResponseStoreEnv, ctx: {
|
|
11
|
+
exports?: Record<string, unknown>;
|
|
12
|
+
passThroughOnException(): void;
|
|
13
|
+
props?: unknown;
|
|
14
|
+
waitUntil(promise: Promise<unknown>): void;
|
|
15
|
+
}): Promise<Response>;
|
|
16
|
+
};
|
|
17
|
+
//#endregion
|
|
18
|
+
export { _default as default };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { createVinextResponseStoreHandler, createVinextResponseStoreOptions } from "./response-store-adapter.worker.js";
|
|
2
|
+
import "vinext/internal/server/cloudflare-workers-tracing";
|
|
3
|
+
import { createWorkersResponseStore } from "@cloudflare/workers-response-store";
|
|
4
|
+
import { configuredCdnCacheAdapterOptions } from "virtual:vinext-cdn-cache-adapter";
|
|
5
|
+
//#region src/cache/response-store-adapter.self-contained.worker.ts
|
|
6
|
+
const responseStore = createWorkersResponseStore(createVinextResponseStoreOptions(configuredCdnCacheAdapterOptions));
|
|
7
|
+
const CacheMetadata = responseStore.entrypoints.CacheMetadata;
|
|
8
|
+
const ResponseStoreBinding = responseStore.entrypoints.ResponseStoreBinding;
|
|
9
|
+
const ResponseStoreRevalidator = responseStore.entrypoints.ResponseStoreRevalidator;
|
|
10
|
+
var response_store_adapter_self_contained_worker_default = createVinextResponseStoreHandler(responseStore);
|
|
11
|
+
//#endregion
|
|
12
|
+
export { CacheMetadata, ResponseStoreBinding, ResponseStoreRevalidator, response_store_adapter_self_contained_worker_default as default };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { VinextResponseStoreEnv } from "./response-store-adapter.worker.js";
|
|
2
|
+
import "vinext/internal/server/cloudflare-workers-tracing";
|
|
3
|
+
import { ResponseStoreClientEntrypoint, ResponseStoreRevalidatorEntrypoint, WorkersResponseStoreClientEnv } from "@cloudflare/workers-response-store";
|
|
4
|
+
//#region src/cache/response-store-adapter.service-binding.worker.d.ts
|
|
5
|
+
export declare const ResponseStoreClient: ResponseStoreClientEntrypoint;
|
|
6
|
+
export declare const ResponseStoreRevalidator: ResponseStoreRevalidatorEntrypoint<WorkersResponseStoreClientEnv>;
|
|
7
|
+
declare const _default: {
|
|
8
|
+
fetch(request: Request, env: VinextResponseStoreEnv, ctx: {
|
|
9
|
+
exports?: Record<string, unknown>;
|
|
10
|
+
passThroughOnException(): void;
|
|
11
|
+
props?: unknown;
|
|
12
|
+
waitUntil(promise: Promise<unknown>): void;
|
|
13
|
+
}): Promise<Response>;
|
|
14
|
+
};
|
|
15
|
+
//#endregion
|
|
16
|
+
export { _default as default };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { createVinextResponseStoreHandler, createVinextResponseStoreOptions } from "./response-store-adapter.worker.js";
|
|
2
|
+
import "vinext/internal/server/cloudflare-workers-tracing";
|
|
3
|
+
import { createWorkersResponseStoreClient } from "@cloudflare/workers-response-store";
|
|
4
|
+
import { configuredCdnCacheAdapterOptions } from "virtual:vinext-cdn-cache-adapter";
|
|
5
|
+
//#region src/cache/response-store-adapter.service-binding.worker.ts
|
|
6
|
+
const responseStore = createWorkersResponseStoreClient(createVinextResponseStoreOptions(configuredCdnCacheAdapterOptions));
|
|
7
|
+
const ResponseStoreClient = responseStore.entrypoints.ResponseStoreClient;
|
|
8
|
+
const ResponseStoreRevalidator = responseStore.entrypoints.ResponseStoreRevalidator;
|
|
9
|
+
var response_store_adapter_service_binding_worker_default = createVinextResponseStoreHandler(responseStore);
|
|
10
|
+
//#endregion
|
|
11
|
+
export { ResponseStoreClient, ResponseStoreRevalidator, response_store_adapter_service_binding_worker_default as default };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { WorkersResponseStore, WorkersResponseStoreClientEnv, WorkersResponseStoreEnv, WorkersResponseStoreOptions } from "@cloudflare/workers-response-store";
|
|
2
|
+
//#region src/cache/response-store-adapter.worker.d.ts
|
|
3
|
+
type WorkerExecutionContext = {
|
|
4
|
+
exports?: Record<string, unknown>;
|
|
5
|
+
passThroughOnException(): void;
|
|
6
|
+
props?: unknown;
|
|
7
|
+
waitUntil(promise: Promise<unknown>): void;
|
|
8
|
+
};
|
|
9
|
+
export type VinextResponseStoreEnv = WorkersResponseStoreClientEnv | WorkersResponseStoreEnv;
|
|
10
|
+
export declare function createVinextResponseStoreOptions<Env extends VinextResponseStoreEnv>(configuration?: Record<string, unknown>): WorkersResponseStoreOptions<Env>;
|
|
11
|
+
export declare function createVinextResponseStoreHandler(store: WorkersResponseStore): {
|
|
12
|
+
fetch(request: Request, env: VinextResponseStoreEnv, ctx: WorkerExecutionContext): Promise<Response>;
|
|
13
|
+
};
|
|
14
|
+
//#endregion
|