vinext 0.0.23 → 0.0.25

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 (105) hide show
  1. package/README.md +24 -0
  2. package/dist/check.d.ts.map +1 -1
  3. package/dist/check.js +3 -2
  4. package/dist/check.js.map +1 -1
  5. package/dist/client/entry.js +1 -1
  6. package/dist/client/entry.js.map +1 -1
  7. package/dist/config/config-matchers.d.ts +21 -0
  8. package/dist/config/config-matchers.d.ts.map +1 -1
  9. package/dist/config/config-matchers.js +59 -9
  10. package/dist/config/config-matchers.js.map +1 -1
  11. package/dist/config/next-config.d.ts +8 -2
  12. package/dist/config/next-config.d.ts.map +1 -1
  13. package/dist/config/next-config.js +90 -35
  14. package/dist/config/next-config.js.map +1 -1
  15. package/dist/deploy.d.ts +10 -0
  16. package/dist/deploy.d.ts.map +1 -1
  17. package/dist/deploy.js +140 -56
  18. package/dist/deploy.js.map +1 -1
  19. package/dist/index.d.ts +14 -2
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +195 -25
  22. package/dist/index.js.map +1 -1
  23. package/dist/plugins/async-hooks-stub.d.ts +16 -0
  24. package/dist/plugins/async-hooks-stub.d.ts.map +1 -0
  25. package/dist/plugins/async-hooks-stub.js +45 -0
  26. package/dist/plugins/async-hooks-stub.js.map +1 -0
  27. package/dist/routing/app-router.d.ts +12 -6
  28. package/dist/routing/app-router.d.ts.map +1 -1
  29. package/dist/routing/app-router.js +19 -40
  30. package/dist/routing/app-router.js.map +1 -1
  31. package/dist/routing/pages-router.d.ts.map +1 -1
  32. package/dist/routing/pages-router.js +3 -9
  33. package/dist/routing/pages-router.js.map +1 -1
  34. package/dist/routing/utils.d.ts +9 -0
  35. package/dist/routing/utils.d.ts.map +1 -1
  36. package/dist/routing/utils.js +10 -0
  37. package/dist/routing/utils.js.map +1 -1
  38. package/dist/server/api-handler.d.ts.map +1 -1
  39. package/dist/server/api-handler.js +6 -0
  40. package/dist/server/api-handler.js.map +1 -1
  41. package/dist/server/app-dev-server.d.ts +2 -2
  42. package/dist/server/app-dev-server.d.ts.map +1 -1
  43. package/dist/server/app-dev-server.js +294 -133
  44. package/dist/server/app-dev-server.js.map +1 -1
  45. package/dist/server/dev-module-runner.d.ts +84 -0
  46. package/dist/server/dev-module-runner.d.ts.map +1 -0
  47. package/dist/server/dev-module-runner.js +105 -0
  48. package/dist/server/dev-module-runner.js.map +1 -0
  49. package/dist/server/dev-server.js.map +1 -1
  50. package/dist/server/instrumentation.d.ts +52 -9
  51. package/dist/server/instrumentation.d.ts.map +1 -1
  52. package/dist/server/instrumentation.js +52 -15
  53. package/dist/server/instrumentation.js.map +1 -1
  54. package/dist/server/middleware.d.ts +7 -3
  55. package/dist/server/middleware.d.ts.map +1 -1
  56. package/dist/server/middleware.js +16 -6
  57. package/dist/server/middleware.js.map +1 -1
  58. package/dist/server/prod-server.d.ts +8 -2
  59. package/dist/server/prod-server.d.ts.map +1 -1
  60. package/dist/server/prod-server.js +56 -35
  61. package/dist/server/prod-server.js.map +1 -1
  62. package/dist/server/worker-utils.d.ts +15 -0
  63. package/dist/server/worker-utils.d.ts.map +1 -0
  64. package/dist/server/worker-utils.js +41 -0
  65. package/dist/server/worker-utils.js.map +1 -0
  66. package/dist/shims/cache.d.ts.map +1 -1
  67. package/dist/shims/cache.js +14 -2
  68. package/dist/shims/cache.js.map +1 -1
  69. package/dist/shims/fetch-cache.d.ts.map +1 -1
  70. package/dist/shims/fetch-cache.js +139 -29
  71. package/dist/shims/fetch-cache.js.map +1 -1
  72. package/dist/shims/form.d.ts.map +1 -1
  73. package/dist/shims/form.js +2 -3
  74. package/dist/shims/form.js.map +1 -1
  75. package/dist/shims/headers.d.ts +6 -0
  76. package/dist/shims/headers.d.ts.map +1 -1
  77. package/dist/shims/headers.js +8 -0
  78. package/dist/shims/headers.js.map +1 -1
  79. package/dist/shims/layout-segment-context.d.ts +5 -4
  80. package/dist/shims/layout-segment-context.d.ts.map +1 -1
  81. package/dist/shims/layout-segment-context.js +6 -5
  82. package/dist/shims/layout-segment-context.js.map +1 -1
  83. package/dist/shims/link.d.ts.map +1 -1
  84. package/dist/shims/link.js +32 -17
  85. package/dist/shims/link.js.map +1 -1
  86. package/dist/shims/navigation.d.ts +14 -11
  87. package/dist/shims/navigation.d.ts.map +1 -1
  88. package/dist/shims/navigation.js +122 -102
  89. package/dist/shims/navigation.js.map +1 -1
  90. package/dist/shims/router.d.ts.map +1 -1
  91. package/dist/shims/router.js +37 -21
  92. package/dist/shims/router.js.map +1 -1
  93. package/dist/shims/server.d.ts +2 -0
  94. package/dist/shims/server.d.ts.map +1 -1
  95. package/dist/shims/server.js +4 -0
  96. package/dist/shims/server.js.map +1 -1
  97. package/dist/shims/url-utils.d.ts +13 -0
  98. package/dist/shims/url-utils.d.ts.map +1 -0
  99. package/dist/shims/url-utils.js +28 -0
  100. package/dist/shims/url-utils.js.map +1 -0
  101. package/dist/utils/project.d.ts +13 -1
  102. package/dist/utils/project.d.ts.map +1 -1
  103. package/dist/utils/project.js +63 -13
  104. package/dist/utils/project.js.map +1 -1
  105. package/package.json +6 -1
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Shared utilities for Cloudflare Worker entries.
3
+ *
4
+ * Used by hand-written example worker entries and can be imported as
5
+ * "vinext/server/worker-utils". The generated worker entry (deploy.ts)
6
+ * inlines these functions in its template string.
7
+ */
8
+ /**
9
+ * Merge middleware/config headers into a response.
10
+ * Response headers take precedence over middleware headers for all headers
11
+ * except Set-Cookie, which is additive (both middleware and response cookies
12
+ * are preserved). Uses getSetCookie() to preserve multiple Set-Cookie values.
13
+ */
14
+ export function mergeHeaders(response, extraHeaders, statusOverride) {
15
+ if (!Object.keys(extraHeaders).length && !statusOverride)
16
+ return response;
17
+ const merged = new Headers();
18
+ for (const [k, v] of Object.entries(extraHeaders)) {
19
+ if (Array.isArray(v)) {
20
+ for (const item of v)
21
+ merged.append(k, item);
22
+ }
23
+ else {
24
+ merged.set(k, v);
25
+ }
26
+ }
27
+ response.headers.forEach((v, k) => {
28
+ if (k === "set-cookie")
29
+ return;
30
+ merged.set(k, v);
31
+ });
32
+ const responseCookies = response.headers.getSetCookie?.() ?? [];
33
+ for (const cookie of responseCookies)
34
+ merged.append("set-cookie", cookie);
35
+ return new Response(response.body, {
36
+ status: statusOverride ?? response.status,
37
+ statusText: response.statusText,
38
+ headers: merged,
39
+ });
40
+ }
41
+ //# sourceMappingURL=worker-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-utils.js","sourceRoot":"","sources":["../../src/server/worker-utils.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAC1B,QAAkB,EAClB,YAA+C,EAC/C,cAAuB;IAEvB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,IAAI,CAAC,cAAc;QAAE,OAAO,QAAQ,CAAC;IAC1E,MAAM,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;IAC7B,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;QAClD,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;YACrB,KAAK,MAAM,IAAI,IAAI,CAAC;gBAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QAC/C,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACnB,CAAC;IACH,CAAC;IACD,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QAChC,IAAI,CAAC,KAAK,YAAY;YAAE,OAAO;QAC/B,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACnB,CAAC,CAAC,CAAC;IACH,MAAM,eAAe,GAAG,QAAQ,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,IAAI,EAAE,CAAC;IAChE,KAAK,MAAM,MAAM,IAAI,eAAe;QAAE,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IAC1E,OAAO,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE;QACjC,MAAM,EAAE,cAAc,IAAI,QAAQ,CAAC,MAAM;QACzC,UAAU,EAAE,QAAQ,CAAC,UAAU;QAC/B,OAAO,EAAE,MAAM;KAChB,CAAC,CAAC;AACL,CAAC","sourcesContent":["/**\n * Shared utilities for Cloudflare Worker entries.\n *\n * Used by hand-written example worker entries and can be imported as\n * \"vinext/server/worker-utils\". The generated worker entry (deploy.ts)\n * inlines these functions in its template string.\n */\n\n/**\n * Merge middleware/config headers into a response.\n * Response headers take precedence over middleware headers for all headers\n * except Set-Cookie, which is additive (both middleware and response cookies\n * are preserved). Uses getSetCookie() to preserve multiple Set-Cookie values.\n */\nexport function mergeHeaders(\n response: Response,\n extraHeaders: Record<string, string | string[]>,\n statusOverride?: number,\n): Response {\n if (!Object.keys(extraHeaders).length && !statusOverride) return response;\n const merged = new Headers();\n for (const [k, v] of Object.entries(extraHeaders)) {\n if (Array.isArray(v)) {\n for (const item of v) merged.append(k, item);\n } else {\n merged.set(k, v);\n }\n }\n response.headers.forEach((v, k) => {\n if (k === \"set-cookie\") return;\n merged.set(k, v);\n });\n const responseCookies = response.headers.getSetCookie?.() ?? [];\n for (const cookie of responseCookies) merged.append(\"set-cookie\", cookie);\n return new Response(response.body, {\n status: statusOverride ?? response.status,\n statusText: response.statusText,\n headers: merged,\n });\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/shims/cache.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/shims/cache.ts"],"names":[],"mappings":"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"}
@@ -377,6 +377,18 @@ export function cacheTag(...tags) {
377
377
  */
378
378
  const _UNSTABLE_CACHE_ALS_KEY = Symbol.for("vinext.unstableCache.als");
379
379
  const _unstableCacheAls = (_g[_UNSTABLE_CACHE_ALS_KEY] ??= new AsyncLocalStorage());
380
+ const UNSTABLE_CACHE_UNDEFINED_SENTINEL = "__vinext_unstable_cache_undefined__";
381
+ function serializeUnstableCacheResult(value) {
382
+ return value === undefined
383
+ ? UNSTABLE_CACHE_UNDEFINED_SENTINEL
384
+ : JSON.stringify(value);
385
+ }
386
+ function deserializeUnstableCacheResult(body) {
387
+ if (body === UNSTABLE_CACHE_UNDEFINED_SENTINEL) {
388
+ return undefined;
389
+ }
390
+ return JSON.parse(body);
391
+ }
380
392
  /**
381
393
  * Check if the current execution context is inside an unstable_cache() callback.
382
394
  * Used by headers(), cookies(), and connection() to throw errors when
@@ -408,7 +420,7 @@ export function unstable_cache(fn, keyParts, options) {
408
420
  });
409
421
  if (existing?.value && existing.value.kind === "FETCH" && existing.cacheState !== "stale") {
410
422
  try {
411
- return JSON.parse(existing.value.data.body);
423
+ return deserializeUnstableCacheResult(existing.value.data.body);
412
424
  }
413
425
  catch {
414
426
  // Corrupted entry, fall through to re-fetch
@@ -423,7 +435,7 @@ export function unstable_cache(fn, keyParts, options) {
423
435
  kind: "FETCH",
424
436
  data: {
425
437
  headers: {},
426
- body: JSON.stringify(result),
438
+ body: serializeUnstableCacheResult(result),
427
439
  url: cacheKey,
428
440
  },
429
441
  tags,
@@ -1 +1 @@
1
- {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/shims/cache.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * next/cache shim\n *\n * Provides the Next.js caching API surface: revalidateTag, revalidatePath,\n * unstable_cache. Backed by a pluggable CacheHandler that defaults to\n * in-memory but can be swapped for Cloudflare KV, Redis, DynamoDB, etc.\n *\n * The CacheHandler interface matches Next.js 16's CacheHandler class, so\n * existing community adapters (@neshca/cache-handler, @opennextjs/aws, etc.)\n * can be used directly.\n *\n * Configuration (in vite.config.ts or next.config.js):\n * vinext({ cacheHandler: './my-cache-handler.ts' })\n *\n * Or set at runtime:\n * import { setCacheHandler } from 'next/cache';\n * setCacheHandler(new MyCacheHandler());\n */\n\nimport { markDynamicUsage as _markDynamic } from \"./headers.js\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport { fnv1a64 } from \"../utils/hash.js\";\n\n// ---------------------------------------------------------------------------\n// Lazy accessor for cache context — avoids circular imports with cache-runtime.\n// The cache-runtime module sets this on load.\n// ---------------------------------------------------------------------------\n\ninterface CacheContextLike {\n tags: string[];\n lifeConfigs: import(\"./cache-runtime.js\").CacheContext[\"lifeConfigs\"];\n variant: string;\n}\n\n/** @internal Set by cache-runtime.ts on import to avoid circular dependency */\nlet _getCacheContextFn: (() => CacheContextLike | null) | null = null;\n\n/**\n * Register the cache context accessor. Called by cache-runtime.ts on load.\n * @internal\n */\nexport function _registerCacheContextAccessor(fn: () => CacheContextLike | null): void {\n _getCacheContextFn = fn;\n}\n\n// ---------------------------------------------------------------------------\n// CacheHandler interface — matches Next.js 16's CacheHandler class shape.\n// Implement this to provide a custom cache backend.\n// ---------------------------------------------------------------------------\n\nexport interface CacheHandlerValue {\n lastModified: number;\n age?: number;\n cacheState?: string;\n value: IncrementalCacheValue | null;\n}\n\n/** Discriminated union of cache value types. */\nexport type IncrementalCacheValue =\n | CachedFetchValue\n | CachedAppPageValue\n | CachedPagesValue\n | CachedRouteValue\n | CachedRedirectValue\n | CachedImageValue;\n\nexport interface CachedFetchValue {\n kind: \"FETCH\";\n data: {\n headers: Record<string, string>;\n body: string;\n url: string;\n status?: number;\n };\n tags?: string[];\n revalidate: number | false;\n}\n\nexport interface CachedAppPageValue {\n kind: \"APP_PAGE\";\n html: string;\n rscData: ArrayBuffer | undefined;\n headers: Record<string, string | string[]> | undefined;\n postponed: string | undefined;\n status: number | undefined;\n}\n\nexport interface CachedPagesValue {\n kind: \"PAGES\";\n html: string;\n pageData: object;\n headers: Record<string, string | string[]> | undefined;\n status: number | undefined;\n}\n\nexport interface CachedRouteValue {\n kind: \"APP_ROUTE\";\n body: ArrayBuffer;\n status: number;\n headers: Record<string, string | string[]>;\n}\n\nexport interface CachedRedirectValue {\n kind: \"REDIRECT\";\n props: object;\n}\n\nexport interface CachedImageValue {\n kind: \"IMAGE\";\n etag: string;\n buffer: ArrayBuffer;\n extension: string;\n revalidate?: number;\n}\n\nexport interface CacheHandlerContext {\n dev?: boolean;\n maxMemoryCacheSize?: number;\n revalidatedTags?: string[];\n [key: string]: unknown;\n}\n\nexport interface CacheHandler {\n get(\n key: string,\n ctx?: Record<string, unknown>,\n ): Promise<CacheHandlerValue | null>;\n\n set(\n key: string,\n data: IncrementalCacheValue | null,\n ctx?: Record<string, unknown>,\n ): Promise<void>;\n\n revalidateTag(\n tags: string | string[],\n durations?: { expire?: number },\n ): Promise<void>;\n\n resetRequestCache?(): void;\n}\n\n// ---------------------------------------------------------------------------\n// Default in-memory adapter — works everywhere, suitable for dev and\n// single-process production. Not shared across workers/instances.\n// ---------------------------------------------------------------------------\n\ninterface MemoryEntry {\n value: IncrementalCacheValue | null;\n tags: string[];\n lastModified: number;\n revalidateAt: number | null;\n}\n\nexport class MemoryCacheHandler implements CacheHandler {\n private store = new Map<string, MemoryEntry>();\n private tagRevalidatedAt = new Map<string, number>();\n\n async get(\n key: string,\n _ctx?: Record<string, unknown>,\n ): Promise<CacheHandlerValue | null> {\n const entry = this.store.get(key);\n if (!entry) return null;\n\n // Check tag-based invalidation first — if tag was invalidated, treat as hard miss\n for (const tag of entry.tags) {\n const revalidatedAt = this.tagRevalidatedAt.get(tag);\n if (revalidatedAt && revalidatedAt >= entry.lastModified) {\n this.store.delete(key);\n return null;\n }\n }\n\n // Check time-based expiry — return stale entry with cacheState=\"stale\"\n // instead of deleting, so ISR can serve stale-while-revalidate\n if (entry.revalidateAt !== null && Date.now() > entry.revalidateAt) {\n return {\n lastModified: entry.lastModified,\n value: entry.value,\n cacheState: \"stale\",\n };\n }\n\n return {\n lastModified: entry.lastModified,\n value: entry.value,\n };\n }\n\n async set(\n key: string,\n data: IncrementalCacheValue | null,\n ctx?: Record<string, unknown>,\n ): Promise<void> {\n const tags: string[] = [];\n if (data && \"tags\" in data && Array.isArray(data.tags)) {\n tags.push(...data.tags);\n }\n if (ctx && \"tags\" in ctx && Array.isArray(ctx.tags)) {\n tags.push(...(ctx.tags as string[]));\n }\n\n let revalidateAt: number | null = null;\n if (ctx) {\n // Handle both old-style { revalidate } and new-style { cacheControl: { revalidate } }\n const revalidate =\n (ctx as any).cacheControl?.revalidate ?? (ctx as any).revalidate;\n if (typeof revalidate === \"number\" && revalidate > 0) {\n revalidateAt = Date.now() + revalidate * 1000;\n }\n }\n if (data && \"revalidate\" in data && typeof data.revalidate === \"number\") {\n revalidateAt = Date.now() + data.revalidate * 1000;\n }\n\n this.store.set(key, {\n value: data,\n tags,\n lastModified: Date.now(),\n revalidateAt,\n });\n }\n\n async revalidateTag(\n tags: string | string[],\n _durations?: { expire?: number },\n ): Promise<void> {\n const tagList = Array.isArray(tags) ? tags : [tags];\n const now = Date.now();\n for (const tag of tagList) {\n this.tagRevalidatedAt.set(tag, now);\n }\n }\n\n resetRequestCache(): void {\n // No-op for the simple memory cache. In a production adapter,\n // this would clear per-request caches (e.g., dedup fetch calls).\n }\n}\n\n// ---------------------------------------------------------------------------\n// Active cache handler — the singleton used by next/cache API functions.\n// Defaults to MemoryCacheHandler, can be swapped at runtime.\n// ---------------------------------------------------------------------------\n\nlet activeHandler: CacheHandler = new MemoryCacheHandler();\n\n/**\n * Set a custom CacheHandler. Call this during server startup to\n * plug in Cloudflare KV, Redis, DynamoDB, or any other backend.\n *\n * The handler must implement the CacheHandler interface (same shape\n * as Next.js 16's CacheHandler class).\n */\nexport function setCacheHandler(handler: CacheHandler): void {\n activeHandler = handler;\n}\n\n/**\n * Get the active CacheHandler (for internal use or testing).\n */\nexport function getCacheHandler(): CacheHandler {\n return activeHandler;\n}\n\n// ---------------------------------------------------------------------------\n// Public API — what app code imports from 'next/cache'\n// ---------------------------------------------------------------------------\n\n/**\n * Revalidate cached data associated with a specific cache tag.\n *\n * Works with both `fetch(..., { next: { tags: ['myTag'] } })` and\n * `unstable_cache(fn, keys, { tags: ['myTag'] })`.\n */\n/**\n * Revalidate cached data associated with a specific cache tag.\n *\n * Next.js 16 updated signature: requires a cacheLife profile as second argument\n * for stale-while-revalidate (SWR) behavior. The single-argument form is\n * deprecated but still supported for backward compatibility.\n *\n * @param tag - Cache tag to revalidate\n * @param profile - cacheLife profile name (e.g. 'max', 'hours') or inline { expire: number }\n */\nexport async function revalidateTag(\n tag: string,\n profile?: string | { expire?: number },\n): Promise<void> {\n // Resolve the profile to durations for the handler\n let durations: { expire?: number } | undefined;\n if (typeof profile === \"string\") {\n const resolved = cacheLifeProfiles[profile];\n if (resolved) {\n durations = { expire: resolved.expire };\n }\n } else if (profile && typeof profile === \"object\") {\n durations = profile;\n }\n await activeHandler.revalidateTag(tag, durations);\n}\n\n/**\n * Revalidate cached data associated with a specific path.\n *\n * Under the hood, Next.js converts paths to internal tags.\n * We use a `_N_T_/path` prefix convention for path-based tags.\n */\nexport async function revalidatePath(\n path: string,\n _type?: \"page\" | \"layout\",\n): Promise<void> {\n // Next.js internally converts paths to tags with a prefix\n const pathTag = `_N_T_${path}`;\n await activeHandler.revalidateTag([path, pathTag]);\n}\n\n/**\n * Expire and immediately refresh cached data for a tag (Next.js 16).\n *\n * Server Actions-only API that provides read-your-writes semantics:\n * the cache entry is expired and fresh data is read within the same request,\n * so the user immediately sees their changes.\n *\n * Use this for interactive features (forms, user settings) where users\n * expect to see their updates instantly.\n *\n * @param tag - Cache tag to expire and refresh\n */\nexport async function updateTag(tag: string): Promise<void> {\n // Expire the tag immediately (same as revalidateTag without SWR)\n await activeHandler.revalidateTag(tag);\n}\n\n/**\n * Refresh uncached data on the page (Next.js 16).\n *\n * Server Actions-only API that signals the client to re-fetch dynamic\n * (uncached) data without touching the cache. Complementary to the\n * client-side router.refresh().\n *\n * Use this when you need to refresh data like notification counts,\n * live metrics, or status indicators after performing a server action.\n */\nexport function refresh(): void {\n // In our implementation, this is a signal that the client should\n // refresh dynamic data. The actual refresh happens on the client side\n // via the RSC protocol — the server action response triggers a\n // client-side navigation refresh.\n // For now, this is a no-op on the server; the Server Action response\n // mechanism already handles re-rendering the affected RSC tree.\n}\n\n/**\n * Opt out of static rendering and indicate a particular component should not be cached.\n *\n * In Next.js, calling noStore() inside a Server Component ensures the component\n * is dynamically rendered. In our implementation, this is a no-op since we don't\n * have the same static/dynamic rendering split — all server rendering is on-demand.\n * It's provided for API compatibility so apps importing it don't break.\n */\nexport function unstable_noStore(): void {\n // Signal dynamic usage so ISR-configured routes bypass the cache\n _markDynamic();\n}\n\n// Also export as `noStore` (Next.js 15+ naming)\nexport { unstable_noStore as noStore };\n\n// ---------------------------------------------------------------------------\n// Request-scoped cacheLife for page-level \"use cache\" directives.\n// When cacheLife() is called outside a \"use cache\" function context (e.g.,\n// in a page component with file-level \"use cache\"), the resolved config is\n// stored here so the server can read it after rendering and apply ISR caching.\n//\n// Uses AsyncLocalStorage for request isolation on concurrent workers.\n// ---------------------------------------------------------------------------\ninterface CacheState {\n requestScopedCacheLife: CacheLifeConfig | null;\n}\n\nconst _ALS_KEY = Symbol.for(\"vinext.cache.als\");\nconst _FALLBACK_KEY = Symbol.for(\"vinext.cache.fallback\");\nconst _g = globalThis as unknown as Record<PropertyKey, unknown>;\nconst _cacheAls = (_g[_ALS_KEY] ??= new AsyncLocalStorage<CacheState>()) as AsyncLocalStorage<CacheState>;\n\nconst _cacheFallbackState = (_g[_FALLBACK_KEY] ??= {\n requestScopedCacheLife: null,\n} satisfies CacheState) as CacheState;\n\nfunction _getCacheState(): CacheState {\n return _cacheAls.getStore() ?? _cacheFallbackState;\n}\n\n/**\n * Run a function within a cache state ALS scope.\n * Ensures per-request isolation for request-scoped cacheLife config\n * on concurrent runtimes.\n * @internal\n */\nexport function _runWithCacheState<T>(fn: () => T | Promise<T>): T | Promise<T> {\n const state: CacheState = {\n requestScopedCacheLife: null,\n };\n return _cacheAls.run(state, fn);\n}\n\n/**\n * Initialize cache ALS for a new request. Call at request entry.\n * Only needed when not using _runWithCacheState() (legacy path).\n * @internal\n */\nexport function _initRequestScopedCacheState(): void {\n const state = _cacheAls.getStore();\n if (state) {\n state.requestScopedCacheLife = null;\n } else {\n _cacheFallbackState.requestScopedCacheLife = null;\n }\n}\n\n/**\n * Set a request-scoped cache life config. Called by cacheLife() when outside\n * a \"use cache\" function context.\n * @internal\n */\nexport function _setRequestScopedCacheLife(config: CacheLifeConfig): void {\n const state = _getCacheState();\n if (state.requestScopedCacheLife === null) {\n state.requestScopedCacheLife = { ...config };\n } else {\n // Minimum-wins rule\n if (config.stale !== undefined) {\n state.requestScopedCacheLife.stale = state.requestScopedCacheLife.stale !== undefined\n ? Math.min(state.requestScopedCacheLife.stale, config.stale)\n : config.stale;\n }\n if (config.revalidate !== undefined) {\n state.requestScopedCacheLife.revalidate = state.requestScopedCacheLife.revalidate !== undefined\n ? Math.min(state.requestScopedCacheLife.revalidate, config.revalidate)\n : config.revalidate;\n }\n if (config.expire !== undefined) {\n state.requestScopedCacheLife.expire = state.requestScopedCacheLife.expire !== undefined\n ? Math.min(state.requestScopedCacheLife.expire, config.expire)\n : config.expire;\n }\n }\n}\n\n/**\n * Consume and reset the request-scoped cache life. Returns null if none was set.\n * @internal\n */\nexport function _consumeRequestScopedCacheLife(): CacheLifeConfig | null {\n const state = _getCacheState();\n const config = state.requestScopedCacheLife;\n state.requestScopedCacheLife = null;\n return config;\n}\n\n// ---------------------------------------------------------------------------\n// cacheLife / cacheTag — Next.js 15+ \"use cache\" APIs\n// ---------------------------------------------------------------------------\n\n/**\n * Cache life configuration. Controls stale-while-revalidate behavior.\n */\nexport interface CacheLifeConfig {\n /** How long (seconds) the client can cache without checking the server */\n stale?: number;\n /** How frequently (seconds) the server cache refreshes */\n revalidate?: number;\n /** Max staleness (seconds) before deoptimizing to dynamic */\n expire?: number;\n}\n\n/**\n * Built-in cache life profiles matching Next.js 16.\n */\nexport const cacheLifeProfiles: Record<string, CacheLifeConfig> = {\n default: { revalidate: 900, expire: 4294967294 },\n seconds: { stale: 30, revalidate: 1, expire: 60 },\n minutes: { stale: 300, revalidate: 60, expire: 3600 },\n hours: { stale: 300, revalidate: 3600, expire: 86400 },\n days: { stale: 300, revalidate: 86400, expire: 604800 },\n weeks: { stale: 300, revalidate: 604800, expire: 2592000 },\n max: { stale: 300, revalidate: 2592000, expire: 31536000 },\n};\n\n/**\n * Set the cache lifetime for a \"use cache\" function.\n *\n * Accepts either a built-in profile name (e.g., \"hours\", \"days\") or a custom\n * configuration object. In Next.js, this only works inside \"use cache\" functions.\n *\n * When called inside a \"use cache\" function, this sets the cache TTL.\n * The \"minimum-wins\" rule applies: if called multiple times, the shortest\n * duration for each field wins.\n *\n * When called outside a \"use cache\" context, this is a validated no-op.\n */\nexport function cacheLife(profile: string | CacheLifeConfig): void {\n let resolvedConfig: CacheLifeConfig;\n\n if (typeof profile === \"string\") {\n // Validate the profile name exists\n if (!cacheLifeProfiles[profile]) {\n console.warn(\n `[vinext] cacheLife: unknown profile \"${profile}\". ` +\n `Available profiles: ${Object.keys(cacheLifeProfiles).join(\", \")}`,\n );\n return;\n }\n resolvedConfig = { ...cacheLifeProfiles[profile] };\n } else if (typeof profile === \"object\" && profile !== null) {\n // Validate the config shape\n if (\n profile.expire !== undefined &&\n profile.revalidate !== undefined &&\n profile.expire < profile.revalidate\n ) {\n console.warn(\n \"[vinext] cacheLife: expire must be >= revalidate\",\n );\n }\n resolvedConfig = { ...profile };\n } else {\n return;\n }\n\n // If we're inside a \"use cache\" context, push the config\n try {\n const ctx = _getCacheContextFn?.();\n if (ctx) {\n ctx.lifeConfigs.push(resolvedConfig);\n return;\n }\n } catch {\n // Fall through to request-scoped\n }\n\n // Outside a \"use cache\" context (e.g., page component with file-level \"use cache\"):\n // store as request-scoped so the server can read it after rendering.\n _setRequestScopedCacheLife(resolvedConfig);\n}\n\n/**\n * Tag a \"use cache\" function's cached result for on-demand revalidation.\n *\n * Tags set here can be invalidated via revalidateTag(). In Next.js, this only\n * works inside \"use cache\" functions.\n *\n * When called inside a \"use cache\" function, tags are attached to the cached\n * entry. They can later be invalidated via revalidateTag().\n *\n * When called outside a \"use cache\" context, this is a no-op.\n */\nexport function cacheTag(...tags: string[]): void {\n try {\n const ctx = _getCacheContextFn?.();\n if (ctx) {\n ctx.tags.push(...tags);\n }\n } catch {\n // Not in a cache context — no-op\n }\n}\n\n// ---------------------------------------------------------------------------\n// unstable_cache — the older caching API\n// ---------------------------------------------------------------------------\n\n/**\n * AsyncLocalStorage to track whether we're inside an unstable_cache() callback.\n * Stored on globalThis via Symbol so headers.ts can detect the scope without\n * a direct import (avoiding circular dependencies).\n */\nconst _UNSTABLE_CACHE_ALS_KEY = Symbol.for(\"vinext.unstableCache.als\");\nconst _unstableCacheAls = (\n (_g[_UNSTABLE_CACHE_ALS_KEY] ??= new AsyncLocalStorage<boolean>()) as AsyncLocalStorage<boolean>\n);\n\n/**\n * Check if the current execution context is inside an unstable_cache() callback.\n * Used by headers(), cookies(), and connection() to throw errors when\n * dynamic request APIs are called inside a cache scope.\n */\nexport function isInsideUnstableCacheScope(): boolean {\n return _unstableCacheAls.getStore() === true;\n}\n\ninterface UnstableCacheOptions {\n revalidate?: number | false;\n tags?: string[];\n}\n\n/**\n * Wrap an async function with caching.\n *\n * Returns a new function that caches results. The cache key is derived\n * from keyParts + serialized arguments.\n */\nexport function unstable_cache<T extends (...args: any[]) => Promise<any>>(\n fn: T,\n keyParts?: string[],\n options?: UnstableCacheOptions,\n): T {\n const baseKey = keyParts\n ? keyParts.join(\":\")\n : fnv1a64(fn.toString());\n const tags = options?.tags ?? [];\n const revalidateSeconds = options?.revalidate;\n\n const cachedFn = async (...args: any[]): Promise<any> => {\n const argsKey = JSON.stringify(args);\n const cacheKey = `unstable_cache:${baseKey}:${argsKey}`;\n\n // Try to get from cache. Check cacheState so time-expired entries\n // trigger a re-fetch instead of being served indefinitely.\n const existing = await activeHandler.get(cacheKey, {\n kind: \"FETCH\",\n tags,\n });\n if (existing?.value && existing.value.kind === \"FETCH\" && existing.cacheState !== \"stale\") {\n try {\n return JSON.parse(existing.value.data.body);\n } catch {\n // Corrupted entry, fall through to re-fetch\n }\n }\n\n // Cache miss — call the function inside the unstable_cache ALS scope\n // so that headers()/cookies()/connection() can detect they're in a\n // cache scope and throw an appropriate error.\n const result = await _unstableCacheAls.run(true, () => fn(...args));\n\n // Store in cache using the FETCH kind\n const cacheValue: CachedFetchValue = {\n kind: \"FETCH\",\n data: {\n headers: {},\n body: JSON.stringify(result),\n url: cacheKey,\n },\n tags,\n // revalidate: false means \"cache indefinitely\" (no time-based expiry).\n // A positive number means time-based revalidation in seconds.\n // When unset (undefined), default to false (indefinite) matching\n // Next.js behavior for unstable_cache without explicit revalidate.\n revalidate: typeof revalidateSeconds === \"number\" ? revalidateSeconds : false,\n };\n\n await activeHandler.set(cacheKey, cacheValue, {\n fetchCache: true,\n tags,\n revalidate: revalidateSeconds,\n });\n\n return result;\n };\n\n return cachedFn as T;\n}\n"]}
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/shims/cache.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * next/cache shim\n *\n * Provides the Next.js caching API surface: revalidateTag, revalidatePath,\n * unstable_cache. Backed by a pluggable CacheHandler that defaults to\n * in-memory but can be swapped for Cloudflare KV, Redis, DynamoDB, etc.\n *\n * The CacheHandler interface matches Next.js 16's CacheHandler class, so\n * existing community adapters (@neshca/cache-handler, @opennextjs/aws, etc.)\n * can be used directly.\n *\n * Configuration (in vite.config.ts or next.config.js):\n * vinext({ cacheHandler: './my-cache-handler.ts' })\n *\n * Or set at runtime:\n * import { setCacheHandler } from 'next/cache';\n * setCacheHandler(new MyCacheHandler());\n */\n\nimport { markDynamicUsage as _markDynamic } from \"./headers.js\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport { fnv1a64 } from \"../utils/hash.js\";\n\n// ---------------------------------------------------------------------------\n// Lazy accessor for cache context — avoids circular imports with cache-runtime.\n// The cache-runtime module sets this on load.\n// ---------------------------------------------------------------------------\n\ninterface CacheContextLike {\n tags: string[];\n lifeConfigs: import(\"./cache-runtime.js\").CacheContext[\"lifeConfigs\"];\n variant: string;\n}\n\n/** @internal Set by cache-runtime.ts on import to avoid circular dependency */\nlet _getCacheContextFn: (() => CacheContextLike | null) | null = null;\n\n/**\n * Register the cache context accessor. Called by cache-runtime.ts on load.\n * @internal\n */\nexport function _registerCacheContextAccessor(fn: () => CacheContextLike | null): void {\n _getCacheContextFn = fn;\n}\n\n// ---------------------------------------------------------------------------\n// CacheHandler interface — matches Next.js 16's CacheHandler class shape.\n// Implement this to provide a custom cache backend.\n// ---------------------------------------------------------------------------\n\nexport interface CacheHandlerValue {\n lastModified: number;\n age?: number;\n cacheState?: string;\n value: IncrementalCacheValue | null;\n}\n\n/** Discriminated union of cache value types. */\nexport type IncrementalCacheValue =\n | CachedFetchValue\n | CachedAppPageValue\n | CachedPagesValue\n | CachedRouteValue\n | CachedRedirectValue\n | CachedImageValue;\n\nexport interface CachedFetchValue {\n kind: \"FETCH\";\n data: {\n headers: Record<string, string>;\n body: string;\n url: string;\n status?: number;\n };\n tags?: string[];\n revalidate: number | false;\n}\n\nexport interface CachedAppPageValue {\n kind: \"APP_PAGE\";\n html: string;\n rscData: ArrayBuffer | undefined;\n headers: Record<string, string | string[]> | undefined;\n postponed: string | undefined;\n status: number | undefined;\n}\n\nexport interface CachedPagesValue {\n kind: \"PAGES\";\n html: string;\n pageData: object;\n headers: Record<string, string | string[]> | undefined;\n status: number | undefined;\n}\n\nexport interface CachedRouteValue {\n kind: \"APP_ROUTE\";\n body: ArrayBuffer;\n status: number;\n headers: Record<string, string | string[]>;\n}\n\nexport interface CachedRedirectValue {\n kind: \"REDIRECT\";\n props: object;\n}\n\nexport interface CachedImageValue {\n kind: \"IMAGE\";\n etag: string;\n buffer: ArrayBuffer;\n extension: string;\n revalidate?: number;\n}\n\nexport interface CacheHandlerContext {\n dev?: boolean;\n maxMemoryCacheSize?: number;\n revalidatedTags?: string[];\n [key: string]: unknown;\n}\n\nexport interface CacheHandler {\n get(\n key: string,\n ctx?: Record<string, unknown>,\n ): Promise<CacheHandlerValue | null>;\n\n set(\n key: string,\n data: IncrementalCacheValue | null,\n ctx?: Record<string, unknown>,\n ): Promise<void>;\n\n revalidateTag(\n tags: string | string[],\n durations?: { expire?: number },\n ): Promise<void>;\n\n resetRequestCache?(): void;\n}\n\n// ---------------------------------------------------------------------------\n// Default in-memory adapter — works everywhere, suitable for dev and\n// single-process production. Not shared across workers/instances.\n// ---------------------------------------------------------------------------\n\ninterface MemoryEntry {\n value: IncrementalCacheValue | null;\n tags: string[];\n lastModified: number;\n revalidateAt: number | null;\n}\n\nexport class MemoryCacheHandler implements CacheHandler {\n private store = new Map<string, MemoryEntry>();\n private tagRevalidatedAt = new Map<string, number>();\n\n async get(\n key: string,\n _ctx?: Record<string, unknown>,\n ): Promise<CacheHandlerValue | null> {\n const entry = this.store.get(key);\n if (!entry) return null;\n\n // Check tag-based invalidation first — if tag was invalidated, treat as hard miss\n for (const tag of entry.tags) {\n const revalidatedAt = this.tagRevalidatedAt.get(tag);\n if (revalidatedAt && revalidatedAt >= entry.lastModified) {\n this.store.delete(key);\n return null;\n }\n }\n\n // Check time-based expiry — return stale entry with cacheState=\"stale\"\n // instead of deleting, so ISR can serve stale-while-revalidate\n if (entry.revalidateAt !== null && Date.now() > entry.revalidateAt) {\n return {\n lastModified: entry.lastModified,\n value: entry.value,\n cacheState: \"stale\",\n };\n }\n\n return {\n lastModified: entry.lastModified,\n value: entry.value,\n };\n }\n\n async set(\n key: string,\n data: IncrementalCacheValue | null,\n ctx?: Record<string, unknown>,\n ): Promise<void> {\n const tags: string[] = [];\n if (data && \"tags\" in data && Array.isArray(data.tags)) {\n tags.push(...data.tags);\n }\n if (ctx && \"tags\" in ctx && Array.isArray(ctx.tags)) {\n tags.push(...(ctx.tags as string[]));\n }\n\n let revalidateAt: number | null = null;\n if (ctx) {\n // Handle both old-style { revalidate } and new-style { cacheControl: { revalidate } }\n const revalidate =\n (ctx as any).cacheControl?.revalidate ?? (ctx as any).revalidate;\n if (typeof revalidate === \"number\" && revalidate > 0) {\n revalidateAt = Date.now() + revalidate * 1000;\n }\n }\n if (data && \"revalidate\" in data && typeof data.revalidate === \"number\") {\n revalidateAt = Date.now() + data.revalidate * 1000;\n }\n\n this.store.set(key, {\n value: data,\n tags,\n lastModified: Date.now(),\n revalidateAt,\n });\n }\n\n async revalidateTag(\n tags: string | string[],\n _durations?: { expire?: number },\n ): Promise<void> {\n const tagList = Array.isArray(tags) ? tags : [tags];\n const now = Date.now();\n for (const tag of tagList) {\n this.tagRevalidatedAt.set(tag, now);\n }\n }\n\n resetRequestCache(): void {\n // No-op for the simple memory cache. In a production adapter,\n // this would clear per-request caches (e.g., dedup fetch calls).\n }\n}\n\n// ---------------------------------------------------------------------------\n// Active cache handler — the singleton used by next/cache API functions.\n// Defaults to MemoryCacheHandler, can be swapped at runtime.\n// ---------------------------------------------------------------------------\n\nlet activeHandler: CacheHandler = new MemoryCacheHandler();\n\n/**\n * Set a custom CacheHandler. Call this during server startup to\n * plug in Cloudflare KV, Redis, DynamoDB, or any other backend.\n *\n * The handler must implement the CacheHandler interface (same shape\n * as Next.js 16's CacheHandler class).\n */\nexport function setCacheHandler(handler: CacheHandler): void {\n activeHandler = handler;\n}\n\n/**\n * Get the active CacheHandler (for internal use or testing).\n */\nexport function getCacheHandler(): CacheHandler {\n return activeHandler;\n}\n\n// ---------------------------------------------------------------------------\n// Public API — what app code imports from 'next/cache'\n// ---------------------------------------------------------------------------\n\n/**\n * Revalidate cached data associated with a specific cache tag.\n *\n * Works with both `fetch(..., { next: { tags: ['myTag'] } })` and\n * `unstable_cache(fn, keys, { tags: ['myTag'] })`.\n */\n/**\n * Revalidate cached data associated with a specific cache tag.\n *\n * Next.js 16 updated signature: requires a cacheLife profile as second argument\n * for stale-while-revalidate (SWR) behavior. The single-argument form is\n * deprecated but still supported for backward compatibility.\n *\n * @param tag - Cache tag to revalidate\n * @param profile - cacheLife profile name (e.g. 'max', 'hours') or inline { expire: number }\n */\nexport async function revalidateTag(\n tag: string,\n profile?: string | { expire?: number },\n): Promise<void> {\n // Resolve the profile to durations for the handler\n let durations: { expire?: number } | undefined;\n if (typeof profile === \"string\") {\n const resolved = cacheLifeProfiles[profile];\n if (resolved) {\n durations = { expire: resolved.expire };\n }\n } else if (profile && typeof profile === \"object\") {\n durations = profile;\n }\n await activeHandler.revalidateTag(tag, durations);\n}\n\n/**\n * Revalidate cached data associated with a specific path.\n *\n * Under the hood, Next.js converts paths to internal tags.\n * We use a `_N_T_/path` prefix convention for path-based tags.\n */\nexport async function revalidatePath(\n path: string,\n _type?: \"page\" | \"layout\",\n): Promise<void> {\n // Next.js internally converts paths to tags with a prefix\n const pathTag = `_N_T_${path}`;\n await activeHandler.revalidateTag([path, pathTag]);\n}\n\n/**\n * Expire and immediately refresh cached data for a tag (Next.js 16).\n *\n * Server Actions-only API that provides read-your-writes semantics:\n * the cache entry is expired and fresh data is read within the same request,\n * so the user immediately sees their changes.\n *\n * Use this for interactive features (forms, user settings) where users\n * expect to see their updates instantly.\n *\n * @param tag - Cache tag to expire and refresh\n */\nexport async function updateTag(tag: string): Promise<void> {\n // Expire the tag immediately (same as revalidateTag without SWR)\n await activeHandler.revalidateTag(tag);\n}\n\n/**\n * Refresh uncached data on the page (Next.js 16).\n *\n * Server Actions-only API that signals the client to re-fetch dynamic\n * (uncached) data without touching the cache. Complementary to the\n * client-side router.refresh().\n *\n * Use this when you need to refresh data like notification counts,\n * live metrics, or status indicators after performing a server action.\n */\nexport function refresh(): void {\n // In our implementation, this is a signal that the client should\n // refresh dynamic data. The actual refresh happens on the client side\n // via the RSC protocol — the server action response triggers a\n // client-side navigation refresh.\n // For now, this is a no-op on the server; the Server Action response\n // mechanism already handles re-rendering the affected RSC tree.\n}\n\n/**\n * Opt out of static rendering and indicate a particular component should not be cached.\n *\n * In Next.js, calling noStore() inside a Server Component ensures the component\n * is dynamically rendered. In our implementation, this is a no-op since we don't\n * have the same static/dynamic rendering split — all server rendering is on-demand.\n * It's provided for API compatibility so apps importing it don't break.\n */\nexport function unstable_noStore(): void {\n // Signal dynamic usage so ISR-configured routes bypass the cache\n _markDynamic();\n}\n\n// Also export as `noStore` (Next.js 15+ naming)\nexport { unstable_noStore as noStore };\n\n// ---------------------------------------------------------------------------\n// Request-scoped cacheLife for page-level \"use cache\" directives.\n// When cacheLife() is called outside a \"use cache\" function context (e.g.,\n// in a page component with file-level \"use cache\"), the resolved config is\n// stored here so the server can read it after rendering and apply ISR caching.\n//\n// Uses AsyncLocalStorage for request isolation on concurrent workers.\n// ---------------------------------------------------------------------------\ninterface CacheState {\n requestScopedCacheLife: CacheLifeConfig | null;\n}\n\nconst _ALS_KEY = Symbol.for(\"vinext.cache.als\");\nconst _FALLBACK_KEY = Symbol.for(\"vinext.cache.fallback\");\nconst _g = globalThis as unknown as Record<PropertyKey, unknown>;\nconst _cacheAls = (_g[_ALS_KEY] ??= new AsyncLocalStorage<CacheState>()) as AsyncLocalStorage<CacheState>;\n\nconst _cacheFallbackState = (_g[_FALLBACK_KEY] ??= {\n requestScopedCacheLife: null,\n} satisfies CacheState) as CacheState;\n\nfunction _getCacheState(): CacheState {\n return _cacheAls.getStore() ?? _cacheFallbackState;\n}\n\n/**\n * Run a function within a cache state ALS scope.\n * Ensures per-request isolation for request-scoped cacheLife config\n * on concurrent runtimes.\n * @internal\n */\nexport function _runWithCacheState<T>(fn: () => T | Promise<T>): T | Promise<T> {\n const state: CacheState = {\n requestScopedCacheLife: null,\n };\n return _cacheAls.run(state, fn);\n}\n\n/**\n * Initialize cache ALS for a new request. Call at request entry.\n * Only needed when not using _runWithCacheState() (legacy path).\n * @internal\n */\nexport function _initRequestScopedCacheState(): void {\n const state = _cacheAls.getStore();\n if (state) {\n state.requestScopedCacheLife = null;\n } else {\n _cacheFallbackState.requestScopedCacheLife = null;\n }\n}\n\n/**\n * Set a request-scoped cache life config. Called by cacheLife() when outside\n * a \"use cache\" function context.\n * @internal\n */\nexport function _setRequestScopedCacheLife(config: CacheLifeConfig): void {\n const state = _getCacheState();\n if (state.requestScopedCacheLife === null) {\n state.requestScopedCacheLife = { ...config };\n } else {\n // Minimum-wins rule\n if (config.stale !== undefined) {\n state.requestScopedCacheLife.stale = state.requestScopedCacheLife.stale !== undefined\n ? Math.min(state.requestScopedCacheLife.stale, config.stale)\n : config.stale;\n }\n if (config.revalidate !== undefined) {\n state.requestScopedCacheLife.revalidate = state.requestScopedCacheLife.revalidate !== undefined\n ? Math.min(state.requestScopedCacheLife.revalidate, config.revalidate)\n : config.revalidate;\n }\n if (config.expire !== undefined) {\n state.requestScopedCacheLife.expire = state.requestScopedCacheLife.expire !== undefined\n ? Math.min(state.requestScopedCacheLife.expire, config.expire)\n : config.expire;\n }\n }\n}\n\n/**\n * Consume and reset the request-scoped cache life. Returns null if none was set.\n * @internal\n */\nexport function _consumeRequestScopedCacheLife(): CacheLifeConfig | null {\n const state = _getCacheState();\n const config = state.requestScopedCacheLife;\n state.requestScopedCacheLife = null;\n return config;\n}\n\n// ---------------------------------------------------------------------------\n// cacheLife / cacheTag — Next.js 15+ \"use cache\" APIs\n// ---------------------------------------------------------------------------\n\n/**\n * Cache life configuration. Controls stale-while-revalidate behavior.\n */\nexport interface CacheLifeConfig {\n /** How long (seconds) the client can cache without checking the server */\n stale?: number;\n /** How frequently (seconds) the server cache refreshes */\n revalidate?: number;\n /** Max staleness (seconds) before deoptimizing to dynamic */\n expire?: number;\n}\n\n/**\n * Built-in cache life profiles matching Next.js 16.\n */\nexport const cacheLifeProfiles: Record<string, CacheLifeConfig> = {\n default: { revalidate: 900, expire: 4294967294 },\n seconds: { stale: 30, revalidate: 1, expire: 60 },\n minutes: { stale: 300, revalidate: 60, expire: 3600 },\n hours: { stale: 300, revalidate: 3600, expire: 86400 },\n days: { stale: 300, revalidate: 86400, expire: 604800 },\n weeks: { stale: 300, revalidate: 604800, expire: 2592000 },\n max: { stale: 300, revalidate: 2592000, expire: 31536000 },\n};\n\n/**\n * Set the cache lifetime for a \"use cache\" function.\n *\n * Accepts either a built-in profile name (e.g., \"hours\", \"days\") or a custom\n * configuration object. In Next.js, this only works inside \"use cache\" functions.\n *\n * When called inside a \"use cache\" function, this sets the cache TTL.\n * The \"minimum-wins\" rule applies: if called multiple times, the shortest\n * duration for each field wins.\n *\n * When called outside a \"use cache\" context, this is a validated no-op.\n */\nexport function cacheLife(profile: string | CacheLifeConfig): void {\n let resolvedConfig: CacheLifeConfig;\n\n if (typeof profile === \"string\") {\n // Validate the profile name exists\n if (!cacheLifeProfiles[profile]) {\n console.warn(\n `[vinext] cacheLife: unknown profile \"${profile}\". ` +\n `Available profiles: ${Object.keys(cacheLifeProfiles).join(\", \")}`,\n );\n return;\n }\n resolvedConfig = { ...cacheLifeProfiles[profile] };\n } else if (typeof profile === \"object\" && profile !== null) {\n // Validate the config shape\n if (\n profile.expire !== undefined &&\n profile.revalidate !== undefined &&\n profile.expire < profile.revalidate\n ) {\n console.warn(\n \"[vinext] cacheLife: expire must be >= revalidate\",\n );\n }\n resolvedConfig = { ...profile };\n } else {\n return;\n }\n\n // If we're inside a \"use cache\" context, push the config\n try {\n const ctx = _getCacheContextFn?.();\n if (ctx) {\n ctx.lifeConfigs.push(resolvedConfig);\n return;\n }\n } catch {\n // Fall through to request-scoped\n }\n\n // Outside a \"use cache\" context (e.g., page component with file-level \"use cache\"):\n // store as request-scoped so the server can read it after rendering.\n _setRequestScopedCacheLife(resolvedConfig);\n}\n\n/**\n * Tag a \"use cache\" function's cached result for on-demand revalidation.\n *\n * Tags set here can be invalidated via revalidateTag(). In Next.js, this only\n * works inside \"use cache\" functions.\n *\n * When called inside a \"use cache\" function, tags are attached to the cached\n * entry. They can later be invalidated via revalidateTag().\n *\n * When called outside a \"use cache\" context, this is a no-op.\n */\nexport function cacheTag(...tags: string[]): void {\n try {\n const ctx = _getCacheContextFn?.();\n if (ctx) {\n ctx.tags.push(...tags);\n }\n } catch {\n // Not in a cache context — no-op\n }\n}\n\n// ---------------------------------------------------------------------------\n// unstable_cache — the older caching API\n// ---------------------------------------------------------------------------\n\n/**\n * AsyncLocalStorage to track whether we're inside an unstable_cache() callback.\n * Stored on globalThis via Symbol so headers.ts can detect the scope without\n * a direct import (avoiding circular dependencies).\n */\nconst _UNSTABLE_CACHE_ALS_KEY = Symbol.for(\"vinext.unstableCache.als\");\nconst _unstableCacheAls = (\n (_g[_UNSTABLE_CACHE_ALS_KEY] ??= new AsyncLocalStorage<boolean>()) as AsyncLocalStorage<boolean>\n);\nconst UNSTABLE_CACHE_UNDEFINED_SENTINEL = \"__vinext_unstable_cache_undefined__\";\n\nfunction serializeUnstableCacheResult(value: unknown): string {\n return value === undefined\n ? UNSTABLE_CACHE_UNDEFINED_SENTINEL\n : JSON.stringify(value);\n}\n\nfunction deserializeUnstableCacheResult(body: string): unknown {\n if (body === UNSTABLE_CACHE_UNDEFINED_SENTINEL) {\n return undefined;\n }\n\n return JSON.parse(body);\n}\n\n/**\n * Check if the current execution context is inside an unstable_cache() callback.\n * Used by headers(), cookies(), and connection() to throw errors when\n * dynamic request APIs are called inside a cache scope.\n */\nexport function isInsideUnstableCacheScope(): boolean {\n return _unstableCacheAls.getStore() === true;\n}\n\ninterface UnstableCacheOptions {\n revalidate?: number | false;\n tags?: string[];\n}\n\n/**\n * Wrap an async function with caching.\n *\n * Returns a new function that caches results. The cache key is derived\n * from keyParts + serialized arguments.\n */\nexport function unstable_cache<T extends (...args: any[]) => Promise<any>>(\n fn: T,\n keyParts?: string[],\n options?: UnstableCacheOptions,\n): T {\n const baseKey = keyParts\n ? keyParts.join(\":\")\n : fnv1a64(fn.toString());\n const tags = options?.tags ?? [];\n const revalidateSeconds = options?.revalidate;\n\n const cachedFn = async (...args: any[]): Promise<any> => {\n const argsKey = JSON.stringify(args);\n const cacheKey = `unstable_cache:${baseKey}:${argsKey}`;\n\n // Try to get from cache. Check cacheState so time-expired entries\n // trigger a re-fetch instead of being served indefinitely.\n const existing = await activeHandler.get(cacheKey, {\n kind: \"FETCH\",\n tags,\n });\n if (existing?.value && existing.value.kind === \"FETCH\" && existing.cacheState !== \"stale\") {\n try {\n return deserializeUnstableCacheResult(existing.value.data.body);\n } catch {\n // Corrupted entry, fall through to re-fetch\n }\n }\n\n // Cache miss — call the function inside the unstable_cache ALS scope\n // so that headers()/cookies()/connection() can detect they're in a\n // cache scope and throw an appropriate error.\n const result = await _unstableCacheAls.run(true, () => fn(...args));\n\n // Store in cache using the FETCH kind\n const cacheValue: CachedFetchValue = {\n kind: \"FETCH\",\n data: {\n headers: {},\n body: serializeUnstableCacheResult(result),\n url: cacheKey,\n },\n tags,\n // revalidate: false means \"cache indefinitely\" (no time-based expiry).\n // A positive number means time-based revalidation in seconds.\n // When unset (undefined), default to false (indefinite) matching\n // Next.js behavior for unstable_cache without explicit revalidate.\n revalidate: typeof revalidateSeconds === \"number\" ? revalidateSeconds : false,\n };\n\n await activeHandler.set(cacheKey, cacheValue, {\n fetchCache: true,\n tags,\n revalidate: revalidateSeconds,\n });\n\n return result;\n };\n\n return cachedFn as T;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"fetch-cache.d.ts","sourceRoot":"","sources":["../../src/shims/fetch-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAsOH,UAAU,gBAAgB;IACxB,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAGD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,WAAW;QACnB,IAAI,CAAC,EAAE,gBAAgB,CAAC;KACzB;CACF;AA0CD;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,EAAE,CAEhD;AAoOD;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,IAAI,MAAM,IAAI,CAO3C;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAG3E;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,UAAU,CAAC,KAAK,CAE1D"}
1
+ {"version":3,"file":"fetch-cache.d.ts","sourceRoot":"","sources":["../../src/shims/fetch-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AA0WH,UAAU,gBAAgB;IACxB,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAGD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,WAAW;QACnB,IAAI,CAAC,EAAE,gBAAgB,CAAC;KACzB;CACF;AA0CD;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,EAAE,CAEhD;AAoOD;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,IAAI,MAAM,IAAI,CAO3C;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAG3E;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,UAAU,CAAC,KAAK,CAE1D"}
@@ -30,13 +30,18 @@ import { AsyncLocalStorage } from "node:async_hooks";
30
30
  */
31
31
  const HEADER_BLOCKLIST = ["traceparent", "tracestate"];
32
32
  // Cache key version — bump when changing the key format to bust stale entries
33
- const CACHE_KEY_PREFIX = "v2";
33
+ const CACHE_KEY_PREFIX = "v3";
34
34
  const MAX_CACHE_KEY_BODY_BYTES = 1024 * 1024; // 1 MiB
35
35
  class BodyTooLargeForCacheKeyError extends Error {
36
36
  constructor() {
37
37
  super("Fetch body too large for cache key generation");
38
38
  }
39
39
  }
40
+ class SkipCacheKeyGenerationError extends Error {
41
+ constructor() {
42
+ super("Fetch body could not be serialized for cache key generation");
43
+ }
44
+ }
40
45
  /**
41
46
  * Collect all headers from the request, excluding the blocklist.
42
47
  * Merges headers from both the Request object and the init object,
@@ -71,19 +76,91 @@ function hasAuthHeaders(input, init) {
71
76
  const headers = collectHeaders(input, init);
72
77
  return AUTH_HEADERS.some((name) => name in headers);
73
78
  }
79
+ async function serializeFormData(formData, pushBodyChunk, getTotalBodyBytes) {
80
+ for (const [key, val] of formData.entries()) {
81
+ if (typeof val === "string") {
82
+ pushBodyChunk(JSON.stringify([key, { kind: "string", value: val }]));
83
+ continue;
84
+ }
85
+ if (val.size > MAX_CACHE_KEY_BODY_BYTES || getTotalBodyBytes() + val.size > MAX_CACHE_KEY_BODY_BYTES) {
86
+ throw new BodyTooLargeForCacheKeyError();
87
+ }
88
+ pushBodyChunk(JSON.stringify([key, {
89
+ kind: "file",
90
+ name: val.name,
91
+ type: val.type,
92
+ value: await val.text(),
93
+ }]));
94
+ }
95
+ }
96
+ function getParsedFormContentType(contentType) {
97
+ const mediaType = contentType?.split(";")[0]?.trim().toLowerCase();
98
+ if (mediaType === "multipart/form-data" || mediaType === "application/x-www-form-urlencoded") {
99
+ return mediaType;
100
+ }
101
+ return undefined;
102
+ }
103
+ function stripMultipartBoundary(contentType) {
104
+ const [type, ...params] = contentType.split(";");
105
+ const keptParams = params
106
+ .map((param) => param.trim())
107
+ .filter(Boolean)
108
+ .filter((param) => !/^boundary\s*=/i.test(param));
109
+ const normalizedType = type.trim().toLowerCase();
110
+ return keptParams.length > 0
111
+ ? `${normalizedType}; ${keptParams.join("; ")}`
112
+ : normalizedType;
113
+ }
114
+ async function readRequestBodyChunksWithinLimit(request) {
115
+ const contentLengthHeader = request.headers.get("content-length");
116
+ if (contentLengthHeader) {
117
+ const contentLength = Number(contentLengthHeader);
118
+ if (Number.isFinite(contentLength) && contentLength > MAX_CACHE_KEY_BODY_BYTES) {
119
+ throw new BodyTooLargeForCacheKeyError();
120
+ }
121
+ }
122
+ const requestClone = request.clone();
123
+ const contentType = requestClone.headers.get("content-type") ?? undefined;
124
+ const reader = requestClone.body?.getReader();
125
+ if (!reader) {
126
+ return { chunks: [], contentType };
127
+ }
128
+ const chunks = [];
129
+ let totalBodyBytes = 0;
130
+ try {
131
+ while (true) {
132
+ const { done, value } = await reader.read();
133
+ if (done)
134
+ break;
135
+ totalBodyBytes += value.byteLength;
136
+ if (totalBodyBytes > MAX_CACHE_KEY_BODY_BYTES) {
137
+ throw new BodyTooLargeForCacheKeyError();
138
+ }
139
+ chunks.push(value);
140
+ }
141
+ }
142
+ catch (err) {
143
+ void reader.cancel().catch(() => { });
144
+ throw err;
145
+ }
146
+ return { chunks, contentType };
147
+ }
74
148
  /**
75
149
  * Serialize request body into string chunks for cache key inclusion.
76
- * Handles all body types: string, Uint8Array, ReadableStream, FormData, Blob.
150
+ * Handles all body types: string, Uint8Array, ReadableStream, FormData, Blob,
151
+ * and Request object bodies.
77
152
  * Returns the serialized body chunks and optionally stashes the original body
78
153
  * on init as `_ogBody` so it can still be used after stream consumption.
79
154
  */
80
- async function serializeBody(init) {
81
- if (!init?.body)
82
- return [];
155
+ async function serializeBody(input, init) {
156
+ if (!init?.body && !(input instanceof Request && input.body)) {
157
+ return { bodyChunks: [] };
158
+ }
83
159
  const bodyChunks = [];
84
160
  const encoder = new TextEncoder();
85
161
  const decoder = new TextDecoder();
86
162
  let totalBodyBytes = 0;
163
+ let canonicalizedContentType;
87
164
  const pushBodyChunk = (chunk) => {
88
165
  totalBodyBytes += encoder.encode(chunk).byteLength;
89
166
  if (totalBodyBytes > MAX_CACHE_KEY_BODY_BYTES) {
@@ -91,14 +168,15 @@ async function serializeBody(init) {
91
168
  }
92
169
  bodyChunks.push(chunk);
93
170
  };
94
- if (init.body instanceof Uint8Array) {
171
+ const getTotalBodyBytes = () => totalBodyBytes;
172
+ if (init?.body instanceof Uint8Array) {
95
173
  if (init.body.byteLength > MAX_CACHE_KEY_BODY_BYTES) {
96
174
  throw new BodyTooLargeForCacheKeyError();
97
175
  }
98
176
  pushBodyChunk(decoder.decode(init.body));
99
177
  init._ogBody = init.body;
100
178
  }
101
- else if (typeof init.body.getReader === "function") {
179
+ else if (init?.body && typeof init.body.getReader === "function") {
102
180
  // ReadableStream
103
181
  const readableBody = init.body;
104
182
  const [bodyForHashing, bodyForFetch] = readableBody.tee();
@@ -132,34 +210,21 @@ async function serializeBody(init) {
132
210
  if (err instanceof BodyTooLargeForCacheKeyError) {
133
211
  throw err;
134
212
  }
135
- console.error("[vinext] Problem reading body for cache key", err);
213
+ throw new SkipCacheKeyGenerationError();
136
214
  }
137
215
  }
138
- else if (init.body instanceof URLSearchParams) {
216
+ else if (init?.body instanceof URLSearchParams) {
139
217
  // URLSearchParams — .toString() gives a stable serialization
140
218
  init._ogBody = init.body;
141
219
  pushBodyChunk(init.body.toString());
142
220
  }
143
- else if (typeof init.body.keys === "function") {
221
+ else if (init?.body && typeof init.body.keys === "function") {
144
222
  // FormData
145
223
  const formData = init.body;
146
224
  init._ogBody = init.body;
147
- for (const key of new Set(formData.keys())) {
148
- const values = formData.getAll(key);
149
- const serializedValues = await Promise.all(values.map(async (val) => {
150
- if (typeof val === "string")
151
- return val;
152
- if (val.size > MAX_CACHE_KEY_BODY_BYTES || totalBodyBytes + val.size > MAX_CACHE_KEY_BODY_BYTES) {
153
- throw new BodyTooLargeForCacheKeyError();
154
- }
155
- // Note: File name/type/lastModified are not included — only content.
156
- // Two Files with identical content but different names produce the same key.
157
- return await val.text();
158
- }));
159
- pushBodyChunk(`${key}=${serializedValues.join(",")}`);
160
- }
225
+ await serializeFormData(formData, pushBodyChunk, getTotalBodyBytes);
161
226
  }
162
- else if (typeof init.body.arrayBuffer === "function") {
227
+ else if (init?.body && typeof init.body.arrayBuffer === "function") {
163
228
  // Blob
164
229
  const blob = init.body;
165
230
  if (blob.size > MAX_CACHE_KEY_BODY_BYTES) {
@@ -169,7 +234,7 @@ async function serializeBody(init) {
169
234
  const arrayBuffer = await blob.arrayBuffer();
170
235
  init._ogBody = new Blob([arrayBuffer], { type: blob.type });
171
236
  }
172
- else if (typeof init.body === "string") {
237
+ else if (typeof init?.body === "string") {
173
238
  // String length is always <= UTF-8 byte length, so this is a
174
239
  // cheap lower-bound check that avoids encoder.encode() for huge strings.
175
240
  if (init.body.length > MAX_CACHE_KEY_BODY_BYTES) {
@@ -178,7 +243,49 @@ async function serializeBody(init) {
178
243
  pushBodyChunk(init.body);
179
244
  init._ogBody = init.body;
180
245
  }
181
- return bodyChunks;
246
+ else if (input instanceof Request && input.body) {
247
+ let chunks;
248
+ let contentType;
249
+ try {
250
+ ({ chunks, contentType } = await readRequestBodyChunksWithinLimit(input));
251
+ }
252
+ catch (err) {
253
+ if (err instanceof BodyTooLargeForCacheKeyError) {
254
+ throw err;
255
+ }
256
+ throw new SkipCacheKeyGenerationError();
257
+ }
258
+ const formContentType = getParsedFormContentType(contentType);
259
+ if (formContentType) {
260
+ try {
261
+ const boundedRequest = new Request(input.url, {
262
+ method: input.method,
263
+ headers: contentType ? { "content-type": contentType } : undefined,
264
+ body: new Blob(chunks),
265
+ });
266
+ const formData = await boundedRequest.formData();
267
+ await serializeFormData(formData, pushBodyChunk, getTotalBodyBytes);
268
+ canonicalizedContentType = formContentType === "multipart/form-data" && contentType
269
+ ? stripMultipartBoundary(contentType)
270
+ : undefined;
271
+ return { bodyChunks, canonicalizedContentType };
272
+ }
273
+ catch (err) {
274
+ if (err instanceof BodyTooLargeForCacheKeyError) {
275
+ throw err;
276
+ }
277
+ throw new SkipCacheKeyGenerationError();
278
+ }
279
+ }
280
+ for (const chunk of chunks) {
281
+ pushBodyChunk(decoder.decode(chunk, { stream: true }));
282
+ }
283
+ const finalChunk = decoder.decode();
284
+ if (finalChunk) {
285
+ pushBodyChunk(finalChunk);
286
+ }
287
+ }
288
+ return { bodyChunks, canonicalizedContentType };
182
289
  }
183
290
  /**
184
291
  * Generate a deterministic cache key from a fetch request.
@@ -204,7 +311,10 @@ async function buildFetchCacheKey(input, init) {
204
311
  if (init?.method)
205
312
  method = init.method;
206
313
  const headers = collectHeaders(input, init);
207
- const bodyChunks = await serializeBody(init);
314
+ const { bodyChunks, canonicalizedContentType } = await serializeBody(input, init);
315
+ if (canonicalizedContentType) {
316
+ headers["content-type"] = canonicalizedContentType;
317
+ }
208
318
  const cacheString = JSON.stringify([
209
319
  CACHE_KEY_PREFIX,
210
320
  url,
@@ -331,7 +441,7 @@ function createPatchedFetch() {
331
441
  cacheKey = await buildFetchCacheKey(input, init);
332
442
  }
333
443
  catch (err) {
334
- if (err instanceof BodyTooLargeForCacheKeyError) {
444
+ if (err instanceof BodyTooLargeForCacheKeyError || err instanceof SkipCacheKeyGenerationError) {
335
445
  const cleanInit = stripNextFromInit(init);
336
446
  return originalFetch(input, cleanInit);
337
447
  }