@vinext/cloudflare 1.0.0-beta.0 → 1.0.0-beta.2
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/dist/cache/kv-data-adapter.runtime.d.ts +4 -3
- package/dist/cache/kv-data-adapter.runtime.js +16 -13
- package/dist/cache/kv-key.d.ts +15 -0
- package/dist/cache/kv-key.js +43 -0
- package/dist/deploy.js +30 -22
- package/dist/prerender-kv-populate.js +4 -6
- package/dist/tpr.d.ts +1 -1
- package/dist/tpr.js +4 -3
- package/package.json +5 -4
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { KvDataAdapterOptions } from "./kv-data-adapter.js";
|
|
2
|
+
import { ENTRY_PREFIX } from "./kv-key.js";
|
|
2
3
|
import { ExecutionContextLike } from "vinext/shims/request-context";
|
|
3
4
|
import { CacheHandler, CacheHandlerValue, IncrementalCacheValue } from "vinext/shims/cache";
|
|
4
5
|
|
|
@@ -28,8 +29,6 @@ type KVNamespace = {
|
|
|
28
29
|
cursor?: string;
|
|
29
30
|
}>;
|
|
30
31
|
};
|
|
31
|
-
/** Key prefix for cache entries. */
|
|
32
|
-
declare const ENTRY_PREFIX = "cache:";
|
|
33
32
|
/**
|
|
34
33
|
* Cloudflare KV data cache handler.
|
|
35
34
|
*
|
|
@@ -53,7 +52,7 @@ declare const ENTRY_PREFIX = "cache:";
|
|
|
53
52
|
*/
|
|
54
53
|
declare class KVCacheHandler implements CacheHandler {
|
|
55
54
|
private kv;
|
|
56
|
-
private
|
|
55
|
+
private keySpace;
|
|
57
56
|
private ctx;
|
|
58
57
|
private ttlSeconds;
|
|
59
58
|
/** Local in-memory cache for tag invalidation timestamps. Avoids redundant KV reads. */
|
|
@@ -66,6 +65,8 @@ declare class KVCacheHandler implements CacheHandler {
|
|
|
66
65
|
ttlSeconds?: number; /** TTL in milliseconds for the local tag cache. Defaults to 5000ms. */
|
|
67
66
|
tagCacheTtlMs?: number;
|
|
68
67
|
});
|
|
68
|
+
private _entryKey;
|
|
69
|
+
private _tagKey;
|
|
69
70
|
get(key: string, _ctx?: Record<string, unknown>): Promise<CacheHandlerValue | null>;
|
|
70
71
|
/**
|
|
71
72
|
* Check tag invalidation markers for stored tags or read-time soft tags.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { ENTRY_PREFIX, createKvKeySpace } from "./kv-key.js";
|
|
1
2
|
import { isUnknownRecord, readCacheControlNumberField } from "../utils/cache-control-metadata.js";
|
|
2
|
-
import { Buffer } from "node:buffer";
|
|
3
3
|
import { getRequestExecutionContext } from "vinext/shims/request-context";
|
|
4
|
+
import { Buffer } from "node:buffer";
|
|
4
5
|
//#region src/cache/kv-data-adapter.runtime.ts
|
|
5
6
|
/**
|
|
6
7
|
* Cloudflare KV data cache — implementation + runtime factory.
|
|
@@ -23,10 +24,6 @@ import { getRequestExecutionContext } from "vinext/shims/request-context";
|
|
|
23
24
|
*/
|
|
24
25
|
/** Default KV namespace binding name read from the Worker `env`. */
|
|
25
26
|
const DEFAULT_BINDING = "VINEXT_KV_CACHE";
|
|
26
|
-
/** Key prefix for tag invalidation timestamps. */
|
|
27
|
-
const TAG_PREFIX = "__tag:";
|
|
28
|
-
/** Key prefix for cache entries. */
|
|
29
|
-
const ENTRY_PREFIX = "cache:";
|
|
30
27
|
/** Prefix used by revalidatePath for path-based tags. */
|
|
31
28
|
const PATH_TAG_PREFIX = "_N_T_";
|
|
32
29
|
/** Max tag length to prevent KV key abuse. */
|
|
@@ -96,7 +93,7 @@ function isPathChildOf(path, prefix) {
|
|
|
96
93
|
*/
|
|
97
94
|
var KVCacheHandler = class {
|
|
98
95
|
kv;
|
|
99
|
-
|
|
96
|
+
keySpace;
|
|
100
97
|
ctx;
|
|
101
98
|
ttlSeconds;
|
|
102
99
|
/** Local in-memory cache for tag invalidation timestamps. Avoids redundant KV reads. */
|
|
@@ -105,13 +102,19 @@ var KVCacheHandler = class {
|
|
|
105
102
|
_tagCacheTtl;
|
|
106
103
|
constructor(kvNamespace, options) {
|
|
107
104
|
this.kv = kvNamespace;
|
|
108
|
-
this.
|
|
105
|
+
this.keySpace = createKvKeySpace(options?.appPrefix);
|
|
109
106
|
this.ctx = options?.ctx;
|
|
110
107
|
this.ttlSeconds = options?.ttlSeconds ?? 720 * 3600;
|
|
111
108
|
this._tagCacheTtl = options?.tagCacheTtlMs ?? 5e3;
|
|
112
109
|
}
|
|
110
|
+
_entryKey(key) {
|
|
111
|
+
return this.keySpace.entryKey(key);
|
|
112
|
+
}
|
|
113
|
+
_tagKey(tag) {
|
|
114
|
+
return this.keySpace.tagKey(tag);
|
|
115
|
+
}
|
|
113
116
|
async get(key, _ctx) {
|
|
114
|
-
const kvKey = this.
|
|
117
|
+
const kvKey = this._entryKey(key);
|
|
115
118
|
const raw = await this.kv.get(kvKey);
|
|
116
119
|
if (!raw) return null;
|
|
117
120
|
let parsed;
|
|
@@ -178,7 +181,7 @@ var KVCacheHandler = class {
|
|
|
178
181
|
}
|
|
179
182
|
}
|
|
180
183
|
if (uncachedTags.length > 0) {
|
|
181
|
-
const tagResults = await Promise.all(uncachedTags.map((tag) => this.kv.get(this.
|
|
184
|
+
const tagResults = await Promise.all(uncachedTags.map((tag) => this.kv.get(this._tagKey(tag))));
|
|
182
185
|
for (let i = 0; i < uncachedTags.length; i++) {
|
|
183
186
|
const tagTime = tagResults[i];
|
|
184
187
|
const tagTimestamp = tagTime ? Number(tagTime) : 0;
|
|
@@ -229,7 +232,7 @@ var KVCacheHandler = class {
|
|
|
229
232
|
};
|
|
230
233
|
const expirationTtl = revalidateAt !== null ? this.ttlSeconds : void 0;
|
|
231
234
|
const metadata = JSON.stringify({ tags }).length <= 1024 ? { tags } : void 0;
|
|
232
|
-
return this._put(this.
|
|
235
|
+
return this._put(this._entryKey(key), JSON.stringify(entry), {
|
|
233
236
|
expirationTtl,
|
|
234
237
|
metadata
|
|
235
238
|
});
|
|
@@ -238,7 +241,7 @@ var KVCacheHandler = class {
|
|
|
238
241
|
const tagList = Array.isArray(tags) ? tags : [tags];
|
|
239
242
|
const now = Date.now();
|
|
240
243
|
const validTags = tagList.filter((t) => validateTag(t) !== null);
|
|
241
|
-
await Promise.all(validTags.map((tag) => this.kv.put(this.
|
|
244
|
+
await Promise.all(validTags.map((tag) => this.kv.put(this._tagKey(tag), String(now), { expirationTtl: 720 * 3600 })));
|
|
242
245
|
for (const tag of validTags) this._tagCache.set(tag, {
|
|
243
246
|
timestamp: now,
|
|
244
247
|
fetchedAt: now
|
|
@@ -263,7 +266,7 @@ var KVCacheHandler = class {
|
|
|
263
266
|
async revalidateByPathPrefix(pathPrefix) {
|
|
264
267
|
const tagsToInvalidate = /* @__PURE__ */ new Set();
|
|
265
268
|
let cursor;
|
|
266
|
-
const listPrefix = this.
|
|
269
|
+
const listPrefix = this.keySpace.entryPrefix;
|
|
267
270
|
do {
|
|
268
271
|
const page = await this.kv.list({
|
|
269
272
|
prefix: listPrefix,
|
|
@@ -324,7 +327,7 @@ var KVCacheHandler = class {
|
|
|
324
327
|
return promise;
|
|
325
328
|
}
|
|
326
329
|
};
|
|
327
|
-
const VALID_KINDS = new Set([
|
|
330
|
+
const VALID_KINDS = /* @__PURE__ */ new Set([
|
|
328
331
|
"FETCH",
|
|
329
332
|
"APP_PAGE",
|
|
330
333
|
"PAGES",
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
//#region src/cache/kv-key.d.ts
|
|
2
|
+
/** Key prefix for cache entries. */
|
|
3
|
+
declare const ENTRY_PREFIX = "cache:";
|
|
4
|
+
type KvKeySpace = {
|
|
5
|
+
/** Prefix shared by every cache entry, including entries with hashed logical keys. */entryPrefix: string;
|
|
6
|
+
entryKey(logicalKey: string): string;
|
|
7
|
+
tagKey(tag: string): string;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Create the deterministic key namespace shared by runtime cache operations
|
|
11
|
+
* and deploy-time prerender population.
|
|
12
|
+
*/
|
|
13
|
+
declare function createKvKeySpace(appPrefix: string | undefined): KvKeySpace;
|
|
14
|
+
//#endregion
|
|
15
|
+
export { ENTRY_PREFIX, KvKeySpace, createKvKeySpace };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { fnv1a64 } from "vinext/internal/utils/hash";
|
|
2
|
+
//#region src/cache/kv-key.ts
|
|
3
|
+
/** Key prefix for tag invalidation timestamps. */
|
|
4
|
+
const TAG_PREFIX = "__tag:";
|
|
5
|
+
/** Key prefix for cache entries. */
|
|
6
|
+
const ENTRY_PREFIX = "cache:";
|
|
7
|
+
/** Cloudflare KV's maximum UTF-8 encoded key length. */
|
|
8
|
+
const KV_KEY_MAX_BYTES = 512;
|
|
9
|
+
/** Marker for logical keys that must be hashed to fit in KV. */
|
|
10
|
+
const HASHED_KEY_PREFIX = "__hash:";
|
|
11
|
+
const KV_KEY_ENCODER = new TextEncoder();
|
|
12
|
+
function kvKeyByteLength(key) {
|
|
13
|
+
return KV_KEY_ENCODER.encode(key).length;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Keep short app prefixes readable, but bound the namespace portion so a
|
|
17
|
+
* hashed entry or tag key is always able to fit within Cloudflare KV's limit.
|
|
18
|
+
*/
|
|
19
|
+
function normalizeAppPrefix(appPrefix) {
|
|
20
|
+
if (!appPrefix) return "";
|
|
21
|
+
const prefix = `${appPrefix}:`;
|
|
22
|
+
if (kvKeyByteLength(`${prefix}cache:${HASHED_KEY_PREFIX}${fnv1a64("")}`) <= KV_KEY_MAX_BYTES) return prefix;
|
|
23
|
+
return `__app:${fnv1a64(appPrefix)}:`;
|
|
24
|
+
}
|
|
25
|
+
function buildStorageKey(prefix, categoryPrefix, logicalKey) {
|
|
26
|
+
const key = `${prefix}${categoryPrefix}${logicalKey}`;
|
|
27
|
+
if (kvKeyByteLength(key) <= KV_KEY_MAX_BYTES) return key;
|
|
28
|
+
return `${prefix}${categoryPrefix}${HASHED_KEY_PREFIX}${fnv1a64(logicalKey)}`;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Create the deterministic key namespace shared by runtime cache operations
|
|
32
|
+
* and deploy-time prerender population.
|
|
33
|
+
*/
|
|
34
|
+
function createKvKeySpace(appPrefix) {
|
|
35
|
+
const prefix = normalizeAppPrefix(appPrefix);
|
|
36
|
+
return {
|
|
37
|
+
entryPrefix: `${prefix}${ENTRY_PREFIX}`,
|
|
38
|
+
entryKey: (logicalKey) => buildStorageKey(prefix, ENTRY_PREFIX, logicalKey),
|
|
39
|
+
tagKey: (tag) => buildStorageKey(prefix, TAG_PREFIX, tag)
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
//#endregion
|
|
43
|
+
export { ENTRY_PREFIX, createKvKeySpace };
|
package/dist/deploy.js
CHANGED
|
@@ -14,8 +14,8 @@ import { parseArgs } from "node:util";
|
|
|
14
14
|
import { pathToFileURL } from "node:url";
|
|
15
15
|
import { runPrerender } from "vinext/internal/build/run-prerender";
|
|
16
16
|
import { loadDotenv } from "vinext/internal/config/dotenv";
|
|
17
|
-
import { loadNextConfig, resolveNextConfig } from "vinext/internal/config/next-config";
|
|
18
|
-
import {
|
|
17
|
+
import { findVinextNextConfigInPlugins, loadNextConfig, resolveNextConfig, resolveNextConfigInput } from "vinext/internal/config/next-config";
|
|
18
|
+
import { findVinextCacheConfigInPlugins, findVinextPrerenderConfigInPlugins, findVinextRouteRootConfigInPlugins, formatVinextPrerenderLabel, resolveVinextPrerenderDecision } from "vinext/internal/config/prerender";
|
|
19
19
|
import { detectProject, findInNodeModules, formatMissingCloudflarePluginError, getMissingDeps } from "vinext/internal/utils/project";
|
|
20
20
|
import { PHASE_PRODUCTION_BUILD } from "vinext/shims/constants";
|
|
21
21
|
//#region src/deploy.ts
|
|
@@ -164,6 +164,18 @@ async function loadProjectViteApi(root) {
|
|
|
164
164
|
}
|
|
165
165
|
return await (vitePath === "vite" ? import(vitePath) : import(pathToFileURL(vitePath).href));
|
|
166
166
|
}
|
|
167
|
+
async function loadDeployViteConfigMetadata(root) {
|
|
168
|
+
const plugins = (await (await loadProjectViteApi(root)).loadConfigFromFile({
|
|
169
|
+
command: "build",
|
|
170
|
+
mode: "production"
|
|
171
|
+
}, void 0, root))?.config.plugins;
|
|
172
|
+
return {
|
|
173
|
+
cacheConfig: viteConfigHasCacheAdapter(root) ? await findVinextCacheConfigInPlugins(plugins) : null,
|
|
174
|
+
nextConfig: await findVinextNextConfigInPlugins(plugins),
|
|
175
|
+
prerenderConfig: await findVinextPrerenderConfigInPlugins(plugins),
|
|
176
|
+
routeRootConfig: await findVinextRouteRootConfigInPlugins(plugins)
|
|
177
|
+
};
|
|
178
|
+
}
|
|
167
179
|
async function runBuild(info, env) {
|
|
168
180
|
console.log("\n Building for Cloudflare Workers...\n");
|
|
169
181
|
const { createBuilder } = await loadProjectViteApi(info.root);
|
|
@@ -171,10 +183,8 @@ async function runBuild(info, env) {
|
|
|
171
183
|
await (await createBuilder({ root: info.root })).buildApp();
|
|
172
184
|
});
|
|
173
185
|
}
|
|
174
|
-
async function populateKVCacheFromPrerenderedArtifacts(root,
|
|
175
|
-
|
|
176
|
-
const vite = await loadProjectViteApi(root);
|
|
177
|
-
const kvConfig = resolveKvDataAdapterConfig(await withCloudflareEnv(buildEnv, () => loadVinextCacheConfigFromViteConfig(vite, root)));
|
|
186
|
+
async function populateKVCacheFromPrerenderedArtifacts(root, wranglerEnv, cacheConfig) {
|
|
187
|
+
const kvConfig = resolveKvDataAdapterConfig(cacheConfig);
|
|
178
188
|
if (!kvConfig) return;
|
|
179
189
|
const { routeCount, pairs } = buildPrerenderKVPairs(path.join(root, "dist", "server"), {
|
|
180
190
|
appPrefix: kvConfig.appPrefix,
|
|
@@ -483,11 +493,13 @@ async function deploy(options) {
|
|
|
483
493
|
console.log("\n Dry run complete. No build or deploy performed.\n");
|
|
484
494
|
return;
|
|
485
495
|
}
|
|
486
|
-
const nextConfig = await resolveNextConfig(await loadNextConfig(info.root, PHASE_PRODUCTION_BUILD), info.root);
|
|
487
496
|
const buildEnv = deployEnv === "production" && !options.env ? void 0 : deployEnv;
|
|
488
|
-
const
|
|
489
|
-
|
|
490
|
-
|
|
497
|
+
const viteConfigMetadata = await withCloudflareEnv(buildEnv, () => loadDeployViteConfigMetadata(info.root));
|
|
498
|
+
const nextConfig = await withCloudflareEnv(buildEnv, async () => {
|
|
499
|
+
const inlineNextConfig = viteConfigMetadata.nextConfig;
|
|
500
|
+
return resolveNextConfig(inlineNextConfig ? await resolveNextConfigInput(inlineNextConfig, PHASE_PRODUCTION_BUILD) : await loadNextConfig(info.root, PHASE_PRODUCTION_BUILD), info.root);
|
|
501
|
+
});
|
|
502
|
+
const vinextPrerenderConfig = !options.prerenderAll && nextConfig.output !== "export" ? viteConfigMetadata.prerenderConfig : null;
|
|
491
503
|
const prerenderDecision = resolveVinextPrerenderDecision({
|
|
492
504
|
prerenderAllFlag: options.prerenderAll,
|
|
493
505
|
vinextPrerenderConfig,
|
|
@@ -496,16 +508,11 @@ async function deploy(options) {
|
|
|
496
508
|
const shouldEmitPrerenderPathManifest = options.warmCdnCache || !options.skipBuild && prerenderDecision;
|
|
497
509
|
if (!options.skipBuild) await runBuild(info, buildEnv);
|
|
498
510
|
else console.log("\n Skipping build (--skip-build)");
|
|
499
|
-
if (shouldEmitPrerenderPathManifest) {
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
root: info.root,
|
|
505
|
-
nextConfigOverride: nextConfig,
|
|
506
|
-
routeRootConfig
|
|
507
|
-
});
|
|
508
|
-
}
|
|
511
|
+
if (shouldEmitPrerenderPathManifest) await emitPrerenderPathManifest({
|
|
512
|
+
root: info.root,
|
|
513
|
+
nextConfig,
|
|
514
|
+
routeRootConfig: viteConfigMetadata.routeRootConfig
|
|
515
|
+
});
|
|
509
516
|
let ranPrerender = false;
|
|
510
517
|
if (prerenderDecision) {
|
|
511
518
|
console.log(`\n ${formatVinextPrerenderLabel(prerenderDecision)}`);
|
|
@@ -515,12 +522,13 @@ async function deploy(options) {
|
|
|
515
522
|
}
|
|
516
523
|
await runPrerender({
|
|
517
524
|
root: info.root,
|
|
518
|
-
concurrency: options.prerenderConcurrency
|
|
525
|
+
concurrency: options.prerenderConcurrency,
|
|
526
|
+
nextConfig
|
|
519
527
|
});
|
|
520
528
|
ranPrerender = true;
|
|
521
529
|
}
|
|
522
530
|
if (ranPrerender) try {
|
|
523
|
-
await populateKVCacheFromPrerenderedArtifacts(root,
|
|
531
|
+
await populateKVCacheFromPrerenderedArtifacts(root, deployEnv === "production" && !options.env ? void 0 : deployEnv, viteConfigMetadata.cacheConfig);
|
|
524
532
|
} catch (error) {
|
|
525
533
|
console.log(` KV cache: Skipping prerender upload (${formatUnknownError(error)}). Continuing with deploy.`);
|
|
526
534
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createKvKeySpace } from "./cache/kv-key.js";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import fs from "node:fs";
|
|
4
4
|
import { getRenderedAppRoutes, readPrerenderManifest } from "vinext/internal/server/prerender-manifest";
|
|
@@ -28,9 +28,6 @@ function formatUnknownError(error) {
|
|
|
28
28
|
if (error instanceof Error && error.message) return error.message;
|
|
29
29
|
return String(error);
|
|
30
30
|
}
|
|
31
|
-
function buildKVKey(appPrefix, cacheKey) {
|
|
32
|
-
return `${appPrefix ? `${appPrefix}:` : ""}${ENTRY_PREFIX}${cacheKey}`;
|
|
33
|
-
}
|
|
34
31
|
function buildCacheEntry(value, tags, now, revalidateSeconds, expireSeconds) {
|
|
35
32
|
const cacheControl = revalidateSeconds === void 0 ? void 0 : expireSeconds === void 0 ? { revalidate: revalidateSeconds } : {
|
|
36
33
|
revalidate: revalidateSeconds,
|
|
@@ -64,6 +61,7 @@ function buildPrerenderKVPairs(serverDir, options) {
|
|
|
64
61
|
const now = options?.now ?? Date.now();
|
|
65
62
|
const ttlSeconds = options?.ttlSeconds ?? DEFAULT_KV_TTL_SECONDS;
|
|
66
63
|
const trailingSlash = manifest.trailingSlash ?? false;
|
|
64
|
+
const keySpace = createKvKeySpace(options?.appPrefix);
|
|
67
65
|
let routeCount = 0;
|
|
68
66
|
for (const route of getRenderedAppRoutes(manifest.routes)) {
|
|
69
67
|
const artifactPathname = route.path ?? route.route;
|
|
@@ -87,7 +85,7 @@ function buildPrerenderKVPairs(serverDir, options) {
|
|
|
87
85
|
const htmlKey = appIsrCacheKey(cachePathname, "html", manifest.buildId);
|
|
88
86
|
const rscKey = appIsrCacheKey(cachePathname, "rsc", manifest.buildId);
|
|
89
87
|
pairs.push({
|
|
90
|
-
key:
|
|
88
|
+
key: keySpace.entryKey(htmlKey),
|
|
91
89
|
value: buildCacheEntry({
|
|
92
90
|
kind: "APP_PAGE",
|
|
93
91
|
html: fs.readFileSync(htmlPath, "utf-8"),
|
|
@@ -99,7 +97,7 @@ function buildPrerenderKVPairs(serverDir, options) {
|
|
|
99
97
|
if (fs.existsSync(rscPath)) {
|
|
100
98
|
const rscData = fs.readFileSync(rscPath).toString("base64");
|
|
101
99
|
pairs.push({
|
|
102
|
-
key:
|
|
100
|
+
key: keySpace.entryKey(rscKey),
|
|
103
101
|
value: buildCacheEntry({
|
|
104
102
|
kind: "APP_PAGE",
|
|
105
103
|
html: "",
|
package/dist/tpr.d.ts
CHANGED
|
@@ -71,7 +71,7 @@ declare function resolveVinextProdServerPath(root: string): string;
|
|
|
71
71
|
* Build KV bulk API pairs from pre-rendered entries.
|
|
72
72
|
*
|
|
73
73
|
* Key format matches the runtime KVCacheHandler exactly:
|
|
74
|
-
*
|
|
74
|
+
* createKvKeySpace().entryKey(isrCacheKey("app", pathname, buildId) + ":html")
|
|
75
75
|
* → "cache:app:<buildId>:<pathname>:html"
|
|
76
76
|
*/
|
|
77
77
|
declare function buildTprKVPairs(entries: Map<string, PrerenderResult>, buildId: string | undefined, defaultRevalidateSeconds: number): Array<{
|
package/dist/tpr.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createKvKeySpace } from "./cache/kv-key.js";
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import fs from "node:fs";
|
|
@@ -578,12 +578,13 @@ const MAX_KV_TTL_SECONDS = 720 * 3600;
|
|
|
578
578
|
* Build KV bulk API pairs from pre-rendered entries.
|
|
579
579
|
*
|
|
580
580
|
* Key format matches the runtime KVCacheHandler exactly:
|
|
581
|
-
*
|
|
581
|
+
* createKvKeySpace().entryKey(isrCacheKey("app", pathname, buildId) + ":html")
|
|
582
582
|
* → "cache:app:<buildId>:<pathname>:html"
|
|
583
583
|
*/
|
|
584
584
|
function buildTprKVPairs(entries, buildId, defaultRevalidateSeconds) {
|
|
585
585
|
const now = Date.now();
|
|
586
586
|
const pairs = [];
|
|
587
|
+
const keySpace = createKvKeySpace(void 0);
|
|
587
588
|
for (const [routePath, result] of entries) {
|
|
588
589
|
if (!isTprCacheable(result.headers)) continue;
|
|
589
590
|
const revalidateSeconds = readTprRevalidateHeader(result.headers) ?? defaultRevalidateSeconds;
|
|
@@ -602,7 +603,7 @@ function buildTprKVPairs(entries, buildId, defaultRevalidateSeconds) {
|
|
|
602
603
|
lastModified: now,
|
|
603
604
|
revalidateAt
|
|
604
605
|
};
|
|
605
|
-
const cacheKey =
|
|
606
|
+
const cacheKey = keySpace.entryKey(isrCacheKey("app", routePath, buildId) + ":html");
|
|
606
607
|
pairs.push({
|
|
607
608
|
key: cacheKey,
|
|
608
609
|
value: JSON.stringify(entry),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vinext/cloudflare",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.2",
|
|
4
4
|
"description": "Cloudflare adapters for vinext (KV data cache and Images-backed image optimization).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -52,11 +52,12 @@
|
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"@types/node": "^25.9.2",
|
|
55
|
-
"vite
|
|
56
|
-
"
|
|
55
|
+
"vite": "npm:@voidzero-dev/vite-plus-core@0.2.2",
|
|
56
|
+
"vite-plus": "0.2.2",
|
|
57
|
+
"vinext": "1.0.0-beta.2"
|
|
57
58
|
},
|
|
58
59
|
"peerDependencies": {
|
|
59
|
-
"vinext": "
|
|
60
|
+
"vinext": "^1.0.0-beta.2"
|
|
60
61
|
},
|
|
61
62
|
"engines": {
|
|
62
63
|
"node": ">=22"
|