@vinext/cloudflare 1.3.0 → 1.3.1
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/app-page-parts.d.ts +0 -6
- package/dist/cache/app-page-parts.js +1 -9
- package/dist/cache/cdn-adapter.worker.js +1 -2
- package/dist/cache/kv-data-adapter.runtime.js +22 -8
- package/dist/cache/response-store-adapter.worker.js +7 -4
- package/dist/cache/response-store-data.runtime.d.ts +2 -0
- package/dist/cache/response-store-data.runtime.js +6 -3
- package/dist/tpr.js +0 -1
- package/package.json +3 -3
|
@@ -4,10 +4,4 @@
|
|
|
4
4
|
* payload, the two parts Next.js keeps in one entry, rather than a variant.
|
|
5
5
|
*/
|
|
6
6
|
export declare function isCanonicalAppPage(responseStageProps: unknown, isRscRequest: boolean): boolean;
|
|
7
|
-
/**
|
|
8
|
-
* Whether a canonical RSC request has a document part. A `.rsc` path reaches
|
|
9
|
-
* its page's HTML path only through the app's trailingSlash policy, and
|
|
10
|
-
* vinext's client never sends one, so it stores its payload alone.
|
|
11
|
-
*/
|
|
12
|
-
export declare function hasDocumentPart(rscRequestUrl: string): boolean;
|
|
13
7
|
//#endregion
|
|
@@ -6,13 +6,5 @@
|
|
|
6
6
|
function isCanonicalAppPage(responseStageProps, isRscRequest) {
|
|
7
7
|
return responseStageProps !== null && typeof responseStageProps === "object" && Reflect.get(responseStageProps, "kind") === "app-page" && Reflect.get(responseStageProps, "isRscRequest") === isRscRequest && (Reflect.get(responseStageProps, "matchKind") === "request" || Reflect.get(responseStageProps, "matchKind") === "resolved") && (!isRscRequest || Reflect.get(responseStageProps, "renderMode") === "navigation") && Reflect.get(responseStageProps, "interceptionContext") === null && Reflect.get(responseStageProps, "interceptionId") === null && Reflect.get(responseStageProps, "mountedSlotsHeader") === null;
|
|
8
8
|
}
|
|
9
|
-
/**
|
|
10
|
-
* Whether a canonical RSC request has a document part. A `.rsc` path reaches
|
|
11
|
-
* its page's HTML path only through the app's trailingSlash policy, and
|
|
12
|
-
* vinext's client never sends one, so it stores its payload alone.
|
|
13
|
-
*/
|
|
14
|
-
function hasDocumentPart(rscRequestUrl) {
|
|
15
|
-
return !new URL(rscRequestUrl).pathname.endsWith(".rsc");
|
|
16
|
-
}
|
|
17
9
|
//#endregion
|
|
18
|
-
export {
|
|
10
|
+
export { isCanonicalAppPage };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { VINEXT_CDN_BUILD_ID_HEADER, getVinextCdnBuildIdentity } from "./cdn-build-id.js";
|
|
2
|
-
import {
|
|
2
|
+
import { isCanonicalAppPage } from "./app-page-parts.js";
|
|
3
3
|
import { SHARED_RESPONSE_STAGE_HEADER, finalizeGatewayResponse } from "./browser-cache-policy.js";
|
|
4
4
|
import { hasCacheMethod, invalidateOrPurge } from "./workers-cache-invalidation.js";
|
|
5
5
|
import { VINEXT_PRERENDER_READINESS_PATH, VINEXT_RSC_VARY_HEADER } from "vinext/internal/server/headers";
|
|
@@ -383,7 +383,6 @@ function getResponseStageInvocation(value, expectedCache) {
|
|
|
383
383
|
function otherPagePartDispatch(request, props) {
|
|
384
384
|
const isRscRequest = isCanonicalAppPage(props, true);
|
|
385
385
|
if (!isRscRequest && !isCanonicalAppPage(props, false)) return null;
|
|
386
|
-
if (isRscRequest && !hasDocumentPart(request.url)) return null;
|
|
387
386
|
const headers = new Headers(request.headers);
|
|
388
387
|
for (const name of FRAMEWORK_RESPONSE_VARY_FIELDS) headers.delete(name);
|
|
389
388
|
for (const name of [
|
|
@@ -25,6 +25,14 @@ import { getRequestExecutionContext } from "vinext/shims/request-context";
|
|
|
25
25
|
*/
|
|
26
26
|
/** Default KV namespace binding name read from the Worker `env`. */
|
|
27
27
|
const DEFAULT_BINDING = "VINEXT_KV_CACHE";
|
|
28
|
+
function toStoredLifetime(seconds) {
|
|
29
|
+
if (seconds === Infinity) return "Infinity";
|
|
30
|
+
if (seconds === -Infinity) return "-Infinity";
|
|
31
|
+
return seconds;
|
|
32
|
+
}
|
|
33
|
+
function isStoredLifetime(value) {
|
|
34
|
+
return typeof value === "number" || value === "Infinity" || value === "-Infinity";
|
|
35
|
+
}
|
|
28
36
|
function parseTagMarker(raw) {
|
|
29
37
|
if (raw === null || raw === void 0) return {};
|
|
30
38
|
if (!raw.startsWith("{")) return { expired: /^\d+$/.test(raw) ? Number(raw) : NaN };
|
|
@@ -313,8 +321,8 @@ var KVCacheHandler = class {
|
|
|
313
321
|
const expireAt = typeof effectiveExpire === "number" && effectiveExpire > 0 ? now + effectiveExpire * 1e3 : null;
|
|
314
322
|
const cacheControl = typeof effectiveRevalidate === "number" ? {
|
|
315
323
|
revalidate: Number.isFinite(effectiveRevalidate) ? effectiveRevalidate : false,
|
|
316
|
-
...effectiveExpire === void 0 ? {} : { expire: effectiveExpire },
|
|
317
|
-
...effectiveStale === void 0 ? {} : { stale: effectiveStale }
|
|
324
|
+
...effectiveExpire === void 0 ? {} : { expire: toStoredLifetime(effectiveExpire) },
|
|
325
|
+
...effectiveStale === void 0 ? {} : { stale: toStoredLifetime(effectiveStale) }
|
|
318
326
|
} : void 0;
|
|
319
327
|
const entry = {
|
|
320
328
|
value: data ? serializeForJSON(data) : null,
|
|
@@ -469,18 +477,24 @@ function validateCacheEntry(raw) {
|
|
|
469
477
|
if (obj.cacheControl !== void 0) {
|
|
470
478
|
if (!isUnknownRecord(obj.cacheControl)) return null;
|
|
471
479
|
if (typeof obj.cacheControl.revalidate !== "number" && obj.cacheControl.revalidate !== false) return null;
|
|
472
|
-
|
|
473
|
-
|
|
480
|
+
for (const field of ["expire", "stale"]) {
|
|
481
|
+
const seconds = obj.cacheControl[field];
|
|
482
|
+
if (seconds !== void 0 && !isStoredLifetime(seconds)) return null;
|
|
483
|
+
}
|
|
474
484
|
}
|
|
475
485
|
if (obj.value !== null) {
|
|
476
486
|
if (!obj.value || typeof obj.value !== "object") return null;
|
|
477
487
|
const value = obj.value;
|
|
478
488
|
if (typeof value.kind !== "string" || !VALID_KINDS.has(value.kind)) return null;
|
|
479
489
|
}
|
|
480
|
-
if (obj.cacheControl
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
490
|
+
if (obj.cacheControl !== void 0) {
|
|
491
|
+
const { revalidate, expire, stale } = obj.cacheControl;
|
|
492
|
+
obj.cacheControl = {
|
|
493
|
+
revalidate: revalidate === false ? Infinity : revalidate,
|
|
494
|
+
...expire === void 0 ? {} : { expire: Number(expire) },
|
|
495
|
+
...stale === void 0 ? {} : { stale: Number(stale) }
|
|
496
|
+
};
|
|
497
|
+
}
|
|
484
498
|
return raw;
|
|
485
499
|
}
|
|
486
500
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isCanonicalAppPage } from "./app-page-parts.js";
|
|
2
2
|
import { SHARED_RESPONSE_STAGE_HEADER, finalizeGatewayResponse } from "./browser-cache-policy.js";
|
|
3
|
-
import { captureResponseStoreDataRegeneration, runWithResponseStoreInvocation, setResponseStore } from "./response-store-data.runtime.js";
|
|
3
|
+
import { captureResponseStoreDataRegeneration, runWithResponseStoreInvocation, setResponseStore, trackResponseStoreRegenerationWork } from "./response-store-data.runtime.js";
|
|
4
4
|
import { NEXTJS_DEPLOYMENT_ID_HEADER, VINEXT_PARAMS_HEADER, VINEXT_RENDERED_PATH_AND_SEARCH_HEADER, VINEXT_RSC_COMPLETION_METADATA_HEADER, VINEXT_SPECIAL_ERROR_STATUS_HEADER, VINEXT_STALE_TIME_PENDING_HEADER } from "vinext/internal/server/headers";
|
|
5
5
|
import { VINEXT_RSC_BUILD_ID_HEADER, VINEXT_RSC_COMPATIBILITY_ID_HEADER, VINEXT_RSC_CONTENT_TYPE, VINEXT_RSC_VARY_HEADER as VINEXT_RSC_VARY_HEADER$1, applyRscCompatibilityIdHeader, applyRscDeploymentIdHeader, createCanonicalRscRequestHeaders, createCanonicalRscRequestUrl, stripRscCacheBustingSearchParam } from "vinext/internal/server/app-rsc-cache-busting";
|
|
6
6
|
import { hasSharedCacheCredentials, isNonCacheableCacheControl } from "vinext/shims/cdn-cache";
|
|
@@ -25,7 +25,10 @@ function stageContext(ctx, env) {
|
|
|
25
25
|
hostRuntime: "worker",
|
|
26
26
|
passThroughOnException: () => ctx.passThroughOnException(),
|
|
27
27
|
...ctx.props === void 0 ? {} : { props: ctx.props },
|
|
28
|
-
waitUntil: (promise) =>
|
|
28
|
+
waitUntil: (promise) => {
|
|
29
|
+
trackResponseStoreRegenerationWork(promise);
|
|
30
|
+
ctx.waitUntil(promise);
|
|
31
|
+
}
|
|
29
32
|
});
|
|
30
33
|
}
|
|
31
34
|
function safeProps(props) {
|
|
@@ -263,7 +266,7 @@ function otherPagePart(identityRequest, identityProps) {
|
|
|
263
266
|
invocation: rscPartInvocation(identityRequest, identityProps),
|
|
264
267
|
kind: "rsc"
|
|
265
268
|
};
|
|
266
|
-
if (isCanonicalAppPage(identityProps, true)
|
|
269
|
+
if (isCanonicalAppPage(identityProps, true)) return {
|
|
267
270
|
invocation: documentPartInvocation(identityRequest, identityProps),
|
|
268
271
|
kind: "document"
|
|
269
272
|
};
|
|
@@ -31,6 +31,8 @@ export declare function captureResponseStoreAppPageDocument(): ((document: CdnAp
|
|
|
31
31
|
export declare function deferResponseStoreNotModified(): boolean;
|
|
32
32
|
/** Stream the foreground body while retaining an independent admission branch. */
|
|
33
33
|
export declare function deferResponseStoreAdmission(response: Response, complete: (response: Response) => Promise<Response>): Response | null;
|
|
34
|
+
/** Keeps work a regeneration hands to waitUntil inside the regeneration. */
|
|
35
|
+
export declare function trackResponseStoreRegenerationWork(work: Promise<unknown>): void;
|
|
34
36
|
/** Re-render an invocation and return the exact rewritten data-cache entry. */
|
|
35
37
|
export declare function captureResponseStoreDataRegeneration(key: string, callback: () => Promise<void>): Promise<Response>;
|
|
36
38
|
export declare class WorkersResponseStoreCacheHandler implements CacheHandler {
|
|
@@ -157,6 +157,10 @@ function deferResponseStoreAdmission(response, complete) {
|
|
|
157
157
|
writer.closed.catch((error) => finishAdmission({ reason: error }));
|
|
158
158
|
return new Response(foreground, response);
|
|
159
159
|
}
|
|
160
|
+
/** Keeps work a regeneration hands to waitUntil inside the regeneration. */
|
|
161
|
+
function trackResponseStoreRegenerationWork(work) {
|
|
162
|
+
regenerationStorage.getStore()?.sideWrites.push(work.then(() => void 0, () => void 0));
|
|
163
|
+
}
|
|
160
164
|
/** Re-render an invocation and return the exact rewritten data-cache entry. */
|
|
161
165
|
async function captureResponseStoreDataRegeneration(key, callback) {
|
|
162
166
|
const scope = {
|
|
@@ -295,8 +299,7 @@ var WorkersResponseStoreCacheHandler = class {
|
|
|
295
299
|
}
|
|
296
300
|
set(key, value, context) {
|
|
297
301
|
const write = this.write(key, value, context);
|
|
298
|
-
|
|
299
|
-
if (regeneration && regeneration.targetKey !== key) regeneration.sideWrites.push(write);
|
|
302
|
+
regenerationStorage.getStore()?.sideWrites.push(write);
|
|
300
303
|
return write;
|
|
301
304
|
}
|
|
302
305
|
async write(key, value, context) {
|
|
@@ -374,4 +377,4 @@ function createResponseStoreDataCacheAdapter() {
|
|
|
374
377
|
return new WorkersResponseStoreCacheHandler();
|
|
375
378
|
}
|
|
376
379
|
//#endregion
|
|
377
|
-
export { CACHE_FUNCTION_REVALIDATOR_ID, DATA_REVALIDATOR_ID, WorkersResponseStoreCacheHandler, captureResponseStoreAppPageDocument, captureResponseStoreDataRegeneration, captureResponseStoreRscData, createResponseStoreDataCacheAdapter as default, deferResponseStoreAdmission, deferResponseStoreNotModified, runWithResponseStoreInvocation, setResponseStore };
|
|
380
|
+
export { CACHE_FUNCTION_REVALIDATOR_ID, DATA_REVALIDATOR_ID, WorkersResponseStoreCacheHandler, captureResponseStoreAppPageDocument, captureResponseStoreDataRegeneration, captureResponseStoreRscData, createResponseStoreDataCacheAdapter as default, deferResponseStoreAdmission, deferResponseStoreNotModified, runWithResponseStoreInvocation, setResponseStore, trackResponseStoreRegenerationWork };
|
package/dist/tpr.js
CHANGED
|
@@ -102,7 +102,6 @@ function filterTrafficPaths(entries) {
|
|
|
102
102
|
if (/\.(js|css|png|jpg|jpeg|gif|svg|ico|woff2?|ttf|eot|map|webp|avif)$/i.test(e.path)) return false;
|
|
103
103
|
if (e.path.startsWith("/api/")) return false;
|
|
104
104
|
if (e.path.startsWith("/_next/") || e.path.startsWith("/__vinext/")) return false;
|
|
105
|
-
if (e.path.endsWith(".rsc")) return false;
|
|
106
105
|
return true;
|
|
107
106
|
});
|
|
108
107
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vinext/cloudflare",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"description": "Cloudflare cache and image adapters for vinext.",
|
|
5
5
|
"homepage": "https://vinext.dev/",
|
|
6
6
|
"license": "MIT",
|
|
@@ -56,12 +56,12 @@
|
|
|
56
56
|
"miniflare": "5.20260730.0-alpha",
|
|
57
57
|
"vite": "npm:@voidzero-dev/vite-plus-core@1.3.0",
|
|
58
58
|
"vite-plus": "1.3.0",
|
|
59
|
-
"vinext": "1.4.
|
|
59
|
+
"vinext": "1.4.1"
|
|
60
60
|
},
|
|
61
61
|
"peerDependencies": {
|
|
62
62
|
"@cloudflare/vite-plugin": "*",
|
|
63
63
|
"cf": "*",
|
|
64
|
-
"vinext": "^1.4.
|
|
64
|
+
"vinext": "^1.4.1"
|
|
65
65
|
},
|
|
66
66
|
"peerDependenciesMeta": {
|
|
67
67
|
"@cloudflare/vite-plugin": {
|