vinext 0.1.3 → 0.1.5

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 (185) hide show
  1. package/dist/build/client-build-config.d.ts +11 -2
  2. package/dist/build/client-build-config.js +17 -6
  3. package/dist/build/css-url-assets.d.ts +1 -1
  4. package/dist/build/css-url-assets.js +9 -7
  5. package/dist/build/prerender.js +3 -1
  6. package/dist/cache/cache-adapters-virtual.js +1 -1
  7. package/dist/client/pages-router-link-navigation.d.ts +33 -7
  8. package/dist/client/pages-router-link-navigation.js +32 -2
  9. package/dist/client/vinext-next-data.js +2 -0
  10. package/dist/cloudflare/src/cache/kv-data-adapter.runtime.d.ts +1 -1
  11. package/dist/config/config-matchers.d.ts +11 -1
  12. package/dist/config/config-matchers.js +14 -2
  13. package/dist/config/tsconfig-paths.js +14 -1
  14. package/dist/deploy.js +20 -13
  15. package/dist/entries/app-rsc-entry.js +27 -22
  16. package/dist/entries/pages-client-entry.js +14 -13
  17. package/dist/entries/pages-server-entry.js +8 -27
  18. package/dist/index.js +365 -147
  19. package/dist/plugins/css-data-url.js +30 -26
  20. package/dist/plugins/dynamic-preload-metadata.js +2 -4
  21. package/dist/plugins/extensionless-dynamic-import.js +27 -24
  22. package/dist/plugins/fonts.js +5 -4
  23. package/dist/plugins/import-meta-url.js +21 -15
  24. package/dist/plugins/instrumentation-client.js +1 -1
  25. package/dist/plugins/middleware-server-only.js +7 -6
  26. package/dist/plugins/og-assets.js +48 -46
  27. package/dist/plugins/optimize-imports.js +9 -3
  28. package/dist/plugins/remove-console.d.ts +7 -1
  29. package/dist/plugins/remove-console.js +4 -1
  30. package/dist/plugins/require-context.js +21 -20
  31. package/dist/plugins/strip-server-exports.d.ts +16 -8
  32. package/dist/plugins/strip-server-exports.js +496 -46
  33. package/dist/routing/app-route-graph.js +2 -2
  34. package/dist/server/app-bfcache-identity.d.ts +26 -0
  35. package/dist/server/app-bfcache-identity.js +127 -0
  36. package/dist/server/app-browser-action-result.js +1 -1
  37. package/dist/server/app-browser-entry.js +22 -12
  38. package/dist/server/app-browser-navigation-controller.d.ts +1 -1
  39. package/dist/server/app-browser-navigation-controller.js +1 -1
  40. package/dist/server/app-browser-state.d.ts +3 -22
  41. package/dist/server/app-browser-state.js +23 -139
  42. package/dist/server/app-browser-stream.js +1 -1
  43. package/dist/server/app-browser-visible-commit.d.ts +1 -1
  44. package/dist/server/app-browser-visible-commit.js +3 -2
  45. package/dist/server/app-fallback-renderer.d.ts +1 -1
  46. package/dist/server/app-layout-param-observation.d.ts +1 -1
  47. package/dist/server/app-layout-param-observation.js +1 -1
  48. package/dist/server/app-middleware.js +2 -1
  49. package/dist/server/app-page-boundary-render.d.ts +1 -1
  50. package/dist/server/app-page-boundary.js +1 -1
  51. package/dist/server/app-page-cache-finalizer.d.ts +62 -0
  52. package/dist/server/app-page-cache-finalizer.js +122 -0
  53. package/dist/server/app-page-cache-render.d.ts +2 -2
  54. package/dist/server/app-page-cache-render.js +1 -1
  55. package/dist/server/app-page-cache.d.ts +2 -53
  56. package/dist/server/app-page-cache.js +5 -131
  57. package/dist/server/app-page-dispatch.d.ts +2 -2
  58. package/dist/server/app-page-dispatch.js +10 -8
  59. package/dist/server/app-page-probe.js +3 -2
  60. package/dist/server/app-page-render-observation.js +2 -2
  61. package/dist/server/app-page-render.d.ts +3 -3
  62. package/dist/server/app-page-render.js +3 -2
  63. package/dist/server/app-page-stream.d.ts +2 -9
  64. package/dist/server/app-page-stream.js +1 -35
  65. package/dist/server/app-pages-bridge.d.ts +5 -1
  66. package/dist/server/app-pages-bridge.js +5 -13
  67. package/dist/server/app-request-context.d.ts +1 -2
  68. package/dist/server/app-request-context.js +2 -1
  69. package/dist/server/app-route-handler-dispatch.js +3 -2
  70. package/dist/server/app-route-handler-execution.d.ts +1 -1
  71. package/dist/server/app-route-handler-execution.js +1 -1
  72. package/dist/server/app-route-handler-response.d.ts +1 -1
  73. package/dist/server/app-router-entry.js +2 -1
  74. package/dist/server/app-rsc-handler.d.ts +3 -0
  75. package/dist/server/app-rsc-handler.js +73 -31
  76. package/dist/server/app-rsc-response-finalizer.js +1 -1
  77. package/dist/server/app-rsc-route-matching.js +6 -2
  78. package/dist/server/app-server-action-execution.d.ts +1 -1
  79. package/dist/server/app-server-action-execution.js +10 -6
  80. package/dist/server/app-ssr-entry.d.ts +1 -1
  81. package/dist/server/app-ssr-entry.js +12 -38
  82. package/dist/server/app-ssr-router-instance.d.ts +6 -0
  83. package/dist/server/app-ssr-router-instance.js +24 -0
  84. package/dist/server/app-ssr-stream.js +1 -1
  85. package/dist/server/artifact-compatibility.js +1 -1
  86. package/dist/server/before-interactive-head.d.ts +17 -0
  87. package/dist/server/before-interactive-head.js +35 -0
  88. package/dist/server/client-reuse-manifest.js +1 -1
  89. package/dist/server/csp.js +1 -4
  90. package/dist/server/defer-until-stream-consumed.d.ts +7 -0
  91. package/dist/server/defer-until-stream-consumed.js +34 -0
  92. package/dist/server/dev-server.js +82 -37
  93. package/dist/server/instrumentation.js +1 -1
  94. package/dist/server/isr-cache.d.ts +1 -1
  95. package/dist/server/isr-cache.js +1 -1
  96. package/dist/server/isr-decision.d.ts +1 -1
  97. package/dist/server/middleware-matcher.js +20 -9
  98. package/dist/server/middleware-runtime.d.ts +3 -4
  99. package/dist/server/middleware-runtime.js +4 -2
  100. package/dist/server/navigation-planner.d.ts +3 -12
  101. package/dist/server/navigation-planner.js +24 -0
  102. package/dist/server/navigation-trace.d.ts +2 -1
  103. package/dist/server/navigation-trace.js +1 -0
  104. package/dist/server/open-redirect.d.ts +12 -0
  105. package/dist/server/open-redirect.js +21 -0
  106. package/dist/server/operation-token.d.ts +40 -0
  107. package/dist/server/operation-token.js +85 -0
  108. package/dist/server/pages-data-route.d.ts +1 -1
  109. package/dist/server/pages-data-route.js +7 -4
  110. package/dist/server/pages-dev-module-url.d.ts +4 -0
  111. package/dist/server/pages-dev-module-url.js +15 -0
  112. package/dist/server/pages-document-initial-props.d.ts +4 -15
  113. package/dist/server/pages-document-initial-props.js +27 -56
  114. package/dist/server/pages-i18n.js +2 -2
  115. package/dist/server/pages-page-data.d.ts +1 -1
  116. package/dist/server/pages-page-data.js +3 -1
  117. package/dist/server/pages-page-handler.js +3 -1
  118. package/dist/server/pages-page-response.d.ts +3 -1
  119. package/dist/server/pages-page-response.js +6 -6
  120. package/dist/server/pages-readiness.js +1 -1
  121. package/dist/server/pages-request-pipeline.d.ts +7 -7
  122. package/dist/server/pages-request-pipeline.js +63 -21
  123. package/dist/server/prod-server.d.ts +3 -1
  124. package/dist/server/prod-server.js +43 -11
  125. package/dist/server/request-pipeline.d.ts +1 -24
  126. package/dist/server/request-pipeline.js +1 -33
  127. package/dist/server/seed-cache.d.ts +1 -1
  128. package/dist/server/static-file-cache.js +16 -4
  129. package/dist/shims/before-interactive-context.d.ts +14 -3
  130. package/dist/shims/cache-handler.d.ts +106 -0
  131. package/dist/shims/cache-handler.js +176 -0
  132. package/dist/shims/cache-request-state.d.ts +47 -0
  133. package/dist/shims/cache-request-state.js +126 -0
  134. package/dist/shims/cache-runtime.d.ts +2 -2
  135. package/dist/shims/cache-runtime.js +3 -14
  136. package/dist/shims/cache.d.ts +3 -231
  137. package/dist/shims/cache.js +17 -383
  138. package/dist/shims/cdn-cache.d.ts +1 -1
  139. package/dist/shims/cdn-cache.js +1 -1
  140. package/dist/shims/document.d.ts +15 -20
  141. package/dist/shims/document.js +5 -8
  142. package/dist/shims/error-boundary-navigation.d.ts +7 -0
  143. package/dist/shims/error-boundary-navigation.js +44 -0
  144. package/dist/shims/error-boundary.js +10 -8
  145. package/dist/shims/error.js +2 -1
  146. package/dist/shims/fetch-cache.js +1 -1
  147. package/dist/shims/form.js +1 -1
  148. package/dist/shims/image.js +74 -9
  149. package/dist/shims/internal/app-page-props-cache-key.d.ts +5 -0
  150. package/dist/shims/internal/app-page-props-cache-key.js +16 -0
  151. package/dist/shims/internal/navigation-untracked.js +2 -1
  152. package/dist/shims/internal/pages-data-fetch-dedup.d.ts +6 -7
  153. package/dist/shims/internal/pages-data-fetch-dedup.js +67 -14
  154. package/dist/shims/internal/pages-data-target.js +1 -1
  155. package/dist/shims/layout-segment-context.d.ts +1 -1
  156. package/dist/shims/layout-segment-context.js +2 -1
  157. package/dist/shims/link.js +38 -17
  158. package/dist/shims/metadata.js +4 -4
  159. package/dist/shims/navigation-context-state.d.ts +40 -0
  160. package/dist/shims/navigation-context-state.js +116 -0
  161. package/dist/shims/navigation-errors.d.ts +55 -0
  162. package/dist/shims/navigation-errors.js +110 -0
  163. package/dist/shims/navigation-server.d.ts +3 -0
  164. package/dist/shims/navigation-server.js +3 -0
  165. package/dist/shims/navigation-state.d.ts +1 -2
  166. package/dist/shims/navigation-state.js +2 -1
  167. package/dist/shims/navigation.d.ts +3 -291
  168. package/dist/shims/navigation.js +16 -445
  169. package/dist/shims/navigation.react-server.d.ts +2 -2
  170. package/dist/shims/navigation.react-server.js +3 -1
  171. package/dist/shims/request-state-types.d.ts +3 -3
  172. package/dist/shims/router.d.ts +6 -2
  173. package/dist/shims/router.js +99 -20
  174. package/dist/shims/script.js +9 -5
  175. package/dist/shims/slot.js +3 -1
  176. package/dist/shims/unified-request-context.d.ts +2 -2
  177. package/dist/utils/has-trailing-comma.d.ts +24 -0
  178. package/dist/utils/has-trailing-comma.js +62 -0
  179. package/dist/utils/text-stream.d.ts +1 -1
  180. package/dist/utils/text-stream.js +2 -2
  181. package/dist/utils/virtual-module.d.ts +5 -0
  182. package/dist/utils/virtual-module.js +0 -0
  183. package/dist/utils/vite-version.d.ts +12 -1
  184. package/dist/utils/vite-version.js +9 -1
  185. package/package.json +5 -1
@@ -1,13 +1,14 @@
1
1
  import { getOrCreateAls } from "./internal/als-registry.js";
2
- import { getRequestContext, isInsideUnifiedScope, runWithUnifiedStateMutation } from "./unified-request-context.js";
2
+ import { getRequestContext, isInsideUnifiedScope } from "./unified-request-context.js";
3
3
  import { getRequestExecutionContext, runWithExecutionContext } from "./request-context.js";
4
+ import { MemoryCacheHandler, NoOpCacheHandler, configureMemoryCacheHandler, getCacheHandler, getDataCacheHandler, setCacheHandler, setDataCacheHandler } from "./cache-handler.js";
5
+ import { getCdnCacheAdapter } from "./cdn-cache.js";
6
+ import { fnv1a64 } from "../utils/hash.js";
4
7
  import { makeHangingPromise } from "./internal/make-hanging-promise.js";
5
8
  import { getHeadersAccessPhase, markDynamicUsage } from "./headers.js";
6
- import { fnv1a64 } from "../utils/hash.js";
7
- import { workUnitAsyncStorage } from "./internal/work-unit-async-storage.js";
8
- import { readCacheControlNumberField } from "../utils/cache-control-metadata.js";
9
+ import { ACTION_DID_REVALIDATE_DYNAMIC_ONLY, ACTION_DID_REVALIDATE_STATIC_AND_DYNAMIC, _consumeRequestScopedCacheLife, _initRequestScopedCacheState, _peekRequestScopedCacheLife, _peekUnstableCacheObservations, _registerCacheContextAccessor, _runWithCacheState, _setRequestScopedCacheLife, cacheLifeProfiles, getAndClearActionRevalidationKind, getRegisteredCacheContext, markActionRevalidation, recordUnstableCacheObservation, shouldServeStaleUnstableCacheEntry } from "./cache-request-state.js";
9
10
  import { encodeCacheTag, encodeCacheTags } from "../utils/encode-cache-tag.js";
10
- import { getCdnCacheAdapter } from "./cdn-cache.js";
11
+ import { workUnitAsyncStorage } from "./internal/work-unit-async-storage.js";
11
12
  //#region src/shims/cache.ts
12
13
  /**
13
14
  * next/cache shim
@@ -29,239 +30,7 @@ import { getCdnCacheAdapter } from "./cdn-cache.js";
29
30
  * deprecated for consumers and retained only as the internal registration
30
31
  * target used by the generated cache-adapter module.
31
32
  */
32
- /** @internal Set by cache-runtime.ts on import to avoid circular dependency */
33
- let _getCacheContextFn = null;
34
- /**
35
- * Register the cache context accessor. Called by cache-runtime.ts on load.
36
- * @internal
37
- */
38
- function _registerCacheContextAccessor(fn) {
39
- _getCacheContextFn = fn;
40
- }
41
- var NoOpCacheHandler = class {
42
- async get(_key, _ctx) {
43
- return null;
44
- }
45
- async set(_key, _data, _ctx) {}
46
- async revalidateTag(_tags, _durations) {}
47
- };
48
- const DEFAULT_MEMORY_CACHE_MAX_SIZE = 50 * 1024 * 1024;
49
- const MAX_REVALIDATED_TAG_ENTRIES = 1e4;
50
- function estimateStringMapSize(map) {
51
- if (!map) return 0;
52
- let size = 0;
53
- for (const [key, value] of Object.entries(map)) {
54
- size += key.length;
55
- if (Array.isArray(value)) for (const item of value) size += item.length;
56
- else size += value.length;
57
- }
58
- return size;
59
- }
60
- function estimateIncrementalCacheValueSize(value) {
61
- if (value === null) return 25;
62
- switch (value.kind) {
63
- case "FETCH": return JSON.stringify(value.data ?? "").length;
64
- case "PAGES": return value.html.length + JSON.stringify(value.pageData ?? {}).length + estimateStringMapSize(value.headers);
65
- case "APP_PAGE": return value.html.length + (value.rscData?.byteLength ?? 0) + (value.postponed?.length ?? 0) + estimateStringMapSize(value.headers);
66
- case "APP_ROUTE": return value.body.byteLength + estimateStringMapSize(value.headers);
67
- case "REDIRECT": return JSON.stringify(value.props ?? {}).length;
68
- case "IMAGE": return value.buffer.byteLength + value.extension.length + value.etag.length;
69
- default: return JSON.stringify(value).length;
70
- }
71
- }
72
- function resolveMemoryCacheMaxSize(options) {
73
- if (typeof options === "number") return options;
74
- if (typeof options?.cacheMaxMemorySize === "number") return options.cacheMaxMemorySize;
75
- if (typeof options?.maxMemoryCacheSize === "number") return options.maxMemoryCacheSize;
76
- return DEFAULT_MEMORY_CACHE_MAX_SIZE;
77
- }
78
- function readStringArrayField(ctx, field) {
79
- const value = ctx?.[field];
80
- if (!Array.isArray(value)) return [];
81
- return value.filter((item) => typeof item === "string");
82
- }
83
- /**
84
- * In-memory data cache handler. This is the built-in default — vinext installs
85
- * it automatically, so consumers should not construct or register it by hand.
86
- *
87
- * @deprecated Consumers should not instantiate cache handlers directly.
88
- * Configure caching declaratively via the `cache` option on the `vinext()`
89
- * plugin (see {@link setDataCacheHandler}); the in-memory handler is the
90
- * default when nothing is configured, and its size is tuned via the
91
- * `cacheMaxMemorySize` plugin option.
92
- */
93
- var MemoryCacheHandler = class {
94
- store = /* @__PURE__ */ new Map();
95
- tagRevalidatedAt = /* @__PURE__ */ new Map();
96
- maxMemoryCacheSize;
97
- currentMemoryCacheSize = 0;
98
- constructor(options) {
99
- this.maxMemoryCacheSize = resolveMemoryCacheMaxSize(options);
100
- }
101
- estimateEntrySize(entry) {
102
- return estimateIncrementalCacheValueSize(entry.value) + entry.tags.reduce((sum, tag) => sum + tag.length, 0) + 64;
103
- }
104
- deleteEntry(key) {
105
- const existing = this.store.get(key);
106
- if (!existing) return;
107
- this.currentMemoryCacheSize -= this.estimateEntrySize(existing);
108
- this.store.delete(key);
109
- }
110
- touchEntry(key, entry) {
111
- this.store.delete(key);
112
- this.store.set(key, entry);
113
- }
114
- evictLeastRecentlyUsed() {
115
- while (this.maxMemoryCacheSize > 0 && this.currentMemoryCacheSize > this.maxMemoryCacheSize) {
116
- const oldestKey = this.store.keys().next().value;
117
- if (oldestKey === void 0) return;
118
- this.deleteEntry(oldestKey);
119
- }
120
- }
121
- async get(key, _ctx) {
122
- const entry = this.store.get(key);
123
- if (!entry) return null;
124
- for (const tag of entry.tags) {
125
- const revalidatedAt = this.tagRevalidatedAt.get(tag);
126
- if (revalidatedAt && revalidatedAt >= entry.lastModified) {
127
- this.deleteEntry(key);
128
- return null;
129
- }
130
- }
131
- for (const tag of readStringArrayField(_ctx, "softTags")) {
132
- const revalidatedAt = this.tagRevalidatedAt.get(tag);
133
- if (revalidatedAt && revalidatedAt >= entry.lastModified) return null;
134
- }
135
- if (entry.expireAt !== null && Date.now() > entry.expireAt) {
136
- this.deleteEntry(key);
137
- return null;
138
- }
139
- this.touchEntry(key, entry);
140
- if (entry.revalidateAt !== null && Date.now() > entry.revalidateAt) return {
141
- lastModified: entry.lastModified,
142
- value: entry.value,
143
- cacheState: "stale",
144
- cacheControl: entry.cacheControl
145
- };
146
- return {
147
- lastModified: entry.lastModified,
148
- value: entry.value,
149
- cacheControl: entry.cacheControl
150
- };
151
- }
152
- async set(key, data, ctx) {
153
- const tagSet = /* @__PURE__ */ new Set();
154
- if (data && "tags" in data && Array.isArray(data.tags)) for (const t of data.tags) tagSet.add(t);
155
- for (const t of readStringArrayField(ctx, "tags")) tagSet.add(t);
156
- const tags = [...tagSet];
157
- let effectiveRevalidate;
158
- let effectiveExpire;
159
- effectiveRevalidate = readCacheControlNumberField(ctx, "revalidate");
160
- effectiveExpire = readCacheControlNumberField(ctx, "expire");
161
- if (data && "revalidate" in data && typeof data.revalidate === "number") effectiveRevalidate = data.revalidate;
162
- if (effectiveRevalidate === 0) return;
163
- const now = Date.now();
164
- const revalidateAt = typeof effectiveRevalidate === "number" && effectiveRevalidate > 0 ? now + effectiveRevalidate * 1e3 : null;
165
- const expireAt = typeof effectiveExpire === "number" && effectiveExpire > 0 ? now + effectiveExpire * 1e3 : null;
166
- const cacheControl = typeof effectiveRevalidate === "number" ? effectiveExpire === void 0 ? { revalidate: effectiveRevalidate } : {
167
- revalidate: effectiveRevalidate,
168
- expire: effectiveExpire
169
- } : void 0;
170
- if (this.maxMemoryCacheSize === 0) return;
171
- const entry = {
172
- value: data,
173
- tags,
174
- lastModified: now,
175
- revalidateAt,
176
- expireAt,
177
- cacheControl
178
- };
179
- const entrySize = this.estimateEntrySize(entry);
180
- if (entrySize > this.maxMemoryCacheSize) {
181
- this.deleteEntry(key);
182
- return;
183
- }
184
- this.deleteEntry(key);
185
- this.store.set(key, entry);
186
- this.currentMemoryCacheSize += entrySize;
187
- this.evictLeastRecentlyUsed();
188
- }
189
- async revalidateTag(tags, _durations) {
190
- const tagList = Array.isArray(tags) ? tags : [tags];
191
- const now = Date.now();
192
- for (const tag of tagList) {
193
- this.tagRevalidatedAt.set(tag, now);
194
- while (this.tagRevalidatedAt.size > MAX_REVALIDATED_TAG_ENTRIES) {
195
- const oldest = this.tagRevalidatedAt.keys().next().value;
196
- if (oldest === void 0) break;
197
- this.tagRevalidatedAt.delete(oldest);
198
- }
199
- }
200
- }
201
- resetRequestCache() {}
202
- };
203
- const _HANDLER_KEY = Symbol.for("vinext.cacheHandler");
204
- const _gHandler = globalThis;
205
- function _getActiveHandler() {
206
- return _gHandler[_HANDLER_KEY] ?? (_gHandler[_HANDLER_KEY] = new MemoryCacheHandler());
207
- }
208
- function configureMemoryCacheHandler(options) {
209
- const current = _gHandler[_HANDLER_KEY];
210
- if (current && !(current instanceof MemoryCacheHandler)) return;
211
- _gHandler[_HANDLER_KEY] = new MemoryCacheHandler(options);
212
- }
213
- /**
214
- * Set the **data cache** handler. This backs all data-cache concerns —
215
- * `fetch` caching, `"use cache"`, `unstable_cache` — and is also the default
216
- * underlying store for page-level ISR (via the default CDN cache adapter).
217
- *
218
- * The handler must implement the CacheHandler interface (same shape as
219
- * Next.js 16's CacheHandler class).
220
- *
221
- * @deprecated Don't wire up the data cache imperatively. Configure it
222
- * declaratively via the `cache.data` option on the `vinext()` plugin in your
223
- * `vite.config.ts`, using a config-time adapter builder. On Cloudflare Workers:
224
- *
225
- * ```ts
226
- * import { vinext } from "vinext";
227
- * import { kvDataAdapter } from "@vinext/cloudflare/cache/kv-data-adapter";
228
- *
229
- * export default defineConfig({
230
- * plugins: [vinext({ cache: { data: kvDataAdapter({ binding: "VINEXT_KV_CACHE" }) } })],
231
- * });
232
- * ```
233
- *
234
- * The plugin defers instantiation to the first request and registers the
235
- * handler across every runtime/router entry, so you don't have to call this
236
- * from a worker entry. This setter remains as the internal registration target
237
- * and for backwards compatibility, but is not the recommended consumer API.
238
- */
239
- function setDataCacheHandler(handler) {
240
- _gHandler[_HANDLER_KEY] = handler;
241
- }
242
- /**
243
- * Get the active data cache handler (for internal use or testing).
244
- */
245
- function getDataCacheHandler() {
246
- return _getActiveHandler();
247
- }
248
- /**
249
- * @deprecated Don't wire up the data cache imperatively. Configure it
250
- * declaratively via the `cache.data` option on the `vinext()` plugin (e.g.
251
- * `kvDataAdapter()` from `@vinext/cloudflare/cache/kv-data-adapter`). See
252
- * {@link setDataCacheHandler} for the migration example. Retained as a
253
- * backwards-compatible alias — `setCacheHandler` has always configured the
254
- * data cache handler.
255
- */
256
- function setCacheHandler(handler) {
257
- setDataCacheHandler(handler);
258
- }
259
- /**
260
- * @deprecated Prefer {@link getDataCacheHandler}.
261
- */
262
- function getCacheHandler() {
263
- return getDataCacheHandler();
264
- }
33
+ const _g = globalThis;
265
34
  /**
266
35
  * Revalidate cached data associated with a specific cache tag.
267
36
  *
@@ -281,7 +50,7 @@ async function revalidateTag(tag, profile) {
281
50
  const resolved = cacheLifeProfiles[profile];
282
51
  if (resolved) durations = { expire: resolved.expire };
283
52
  } else if (profile && typeof profile === "object") durations = profile;
284
- if (!profile || !durations || durations.expire === 0) markActionRevalidation(ACTION_DID_REVALIDATE_STATIC_AND_DYNAMIC);
53
+ if (!profile || !durations || durations.expire === 0) markActionRevalidation(1);
285
54
  await _invalidateEncodedTag(encodeCacheTag(tag), durations);
286
55
  }
287
56
  /**
@@ -294,7 +63,7 @@ async function revalidateTag(tag, profile) {
294
63
  * let the edge re-fetch and re-cache stale data.
295
64
  */
296
65
  async function _invalidateEncodedTag(encoded, durations) {
297
- await _getActiveHandler().revalidateTag(encoded, durations);
66
+ await getDataCacheHandler().revalidateTag(encoded, durations);
298
67
  await getCdnCacheAdapter().revalidateTag(encoded, durations);
299
68
  }
300
69
  /**
@@ -313,7 +82,7 @@ async function _invalidateEncodedTag(encoded, durations) {
313
82
  * layout/page hierarchy tags, so only no-type invalidation applies there.
314
83
  */
315
84
  async function revalidatePath(path, type) {
316
- markActionRevalidation(ACTION_DID_REVALIDATE_STATIC_AND_DYNAMIC);
85
+ markActionRevalidation(1);
317
86
  const stem = path.endsWith("/") ? path.slice(0, -1) : path;
318
87
  await _invalidateEncodedTag(encodeCacheTag(type ? `_N_T_${stem}/${type}` : `_N_T_${stem || "/"}`));
319
88
  }
@@ -326,7 +95,7 @@ async function revalidatePath(path, type) {
326
95
  * response header that the client router already understands.
327
96
  */
328
97
  function refresh() {
329
- markActionRevalidation(ACTION_DID_REVALIDATE_DYNAMIC_ONLY);
98
+ markActionRevalidation(2);
330
99
  }
331
100
  /**
332
101
  * Expire a cache tag immediately (Next.js 16).
@@ -343,7 +112,7 @@ function refresh() {
343
112
  */
344
113
  async function updateTag(tag) {
345
114
  if (getHeadersAccessPhase() !== "action") throw new Error("updateTag can only be called from within a Server Action. To invalidate cache tags in Route Handlers or other contexts, use revalidateTag instead. See more info here: https://nextjs.org/docs/app/api-reference/functions/updateTag");
346
- markActionRevalidation(ACTION_DID_REVALIDATE_STATIC_AND_DYNAMIC);
115
+ markActionRevalidation(1);
347
116
  await _invalidateEncodedTag(encodeCacheTag(tag));
348
117
  }
349
118
  /**
@@ -419,138 +188,6 @@ function unstable_io() {
419
188
  return io();
420
189
  }
421
190
  let _unstableIoWarned = false;
422
- const _FALLBACK_KEY = Symbol.for("vinext.cache.fallback");
423
- const _g = globalThis;
424
- const _cacheAls = getOrCreateAls("vinext.cache.als");
425
- const _cacheFallbackState = _g[_FALLBACK_KEY] ??= {
426
- actionRevalidationKind: 0,
427
- requestScopedCacheLife: null,
428
- unstableCacheObservations: /* @__PURE__ */ new Map(),
429
- unstableCacheRevalidation: "foreground"
430
- };
431
- const ACTION_DID_NOT_REVALIDATE = 0;
432
- const ACTION_DID_REVALIDATE_STATIC_AND_DYNAMIC = 1;
433
- const ACTION_DID_REVALIDATE_DYNAMIC_ONLY = 2;
434
- function _getCacheState() {
435
- if (isInsideUnifiedScope()) return getRequestContext();
436
- return _cacheAls.getStore() ?? _cacheFallbackState;
437
- }
438
- function _runWithCacheState(fn) {
439
- if (isInsideUnifiedScope()) return runWithUnifiedStateMutation((uCtx) => {
440
- uCtx.actionRevalidationKind = ACTION_DID_NOT_REVALIDATE;
441
- uCtx.requestScopedCacheLife = null;
442
- uCtx.unstableCacheObservations = /* @__PURE__ */ new Map();
443
- uCtx.unstableCacheRevalidation = "foreground";
444
- }, fn);
445
- const state = {
446
- actionRevalidationKind: ACTION_DID_NOT_REVALIDATE,
447
- requestScopedCacheLife: null,
448
- unstableCacheObservations: /* @__PURE__ */ new Map(),
449
- unstableCacheRevalidation: "foreground"
450
- };
451
- return _cacheAls.run(state, fn);
452
- }
453
- /**
454
- * Initialize cache ALS for a new request. Call at request entry.
455
- * Only needed when not using _runWithCacheState() (legacy path).
456
- * @internal
457
- */
458
- function _initRequestScopedCacheState() {
459
- const state = _getCacheState();
460
- state.actionRevalidationKind = ACTION_DID_NOT_REVALIDATE;
461
- state.requestScopedCacheLife = null;
462
- state.unstableCacheObservations = /* @__PURE__ */ new Map();
463
- }
464
- function markActionRevalidation(kind) {
465
- if (getHeadersAccessPhase() !== "action") return;
466
- const state = _getCacheState();
467
- state.actionRevalidationKind = state.actionRevalidationKind === ACTION_DID_REVALIDATE_STATIC_AND_DYNAMIC ? ACTION_DID_REVALIDATE_STATIC_AND_DYNAMIC : kind;
468
- }
469
- function getAndClearActionRevalidationKind() {
470
- const state = _getCacheState();
471
- const kind = state.actionRevalidationKind;
472
- state.actionRevalidationKind = ACTION_DID_NOT_REVALIDATE;
473
- return kind;
474
- }
475
- /**
476
- * Set a request-scoped cache life config. Called by cacheLife() so the route
477
- * render can inherit cache policy from file-level and nested "use cache" work.
478
- * @internal
479
- */
480
- function _setRequestScopedCacheLife(config) {
481
- const state = _getCacheState();
482
- if (state.requestScopedCacheLife === null) state.requestScopedCacheLife = { ...config };
483
- else {
484
- if (config.stale !== void 0) state.requestScopedCacheLife.stale = state.requestScopedCacheLife.stale !== void 0 ? Math.min(state.requestScopedCacheLife.stale, config.stale) : config.stale;
485
- if (config.revalidate !== void 0) state.requestScopedCacheLife.revalidate = state.requestScopedCacheLife.revalidate !== void 0 ? Math.min(state.requestScopedCacheLife.revalidate, config.revalidate) : config.revalidate;
486
- if (config.expire !== void 0) state.requestScopedCacheLife.expire = state.requestScopedCacheLife.expire !== void 0 ? Math.min(state.requestScopedCacheLife.expire, config.expire) : config.expire;
487
- }
488
- }
489
- /**
490
- * Read the request-scoped cache life without clearing it. Prerender response
491
- * shaping needs the metadata before the manifest writer consumes it after the
492
- * body has been fully rendered.
493
- * @internal
494
- */
495
- function _peekRequestScopedCacheLife() {
496
- const config = _getCacheState().requestScopedCacheLife;
497
- return config === null ? null : { ...config };
498
- }
499
- /**
500
- * Consume and reset the request-scoped cache life. Returns null if none was set.
501
- * @internal
502
- */
503
- function _consumeRequestScopedCacheLife() {
504
- const state = _getCacheState();
505
- const config = state.requestScopedCacheLife;
506
- state.requestScopedCacheLife = null;
507
- return config;
508
- }
509
- function recordUnstableCacheObservation(observation) {
510
- _getCacheState().unstableCacheObservations.set(observation.keyHash, observation);
511
- }
512
- function _peekUnstableCacheObservations() {
513
- return [..._getCacheState().unstableCacheObservations.values()].sort((a, b) => a.keyHash.localeCompare(b.keyHash));
514
- }
515
- /**
516
- * Built-in cache life profiles matching Next.js 16.
517
- */
518
- const cacheLifeProfiles = {
519
- default: {
520
- revalidate: 900,
521
- expire: 4294967294
522
- },
523
- seconds: {
524
- stale: 30,
525
- revalidate: 1,
526
- expire: 60
527
- },
528
- minutes: {
529
- stale: 300,
530
- revalidate: 60,
531
- expire: 3600
532
- },
533
- hours: {
534
- stale: 300,
535
- revalidate: 3600,
536
- expire: 86400
537
- },
538
- days: {
539
- stale: 300,
540
- revalidate: 86400,
541
- expire: 604800
542
- },
543
- weeks: {
544
- stale: 300,
545
- revalidate: 604800,
546
- expire: 2592e3
547
- },
548
- max: {
549
- stale: 300,
550
- revalidate: 2592e3,
551
- expire: 31536e3
552
- }
553
- };
554
191
  /**
555
192
  * Set the cache lifetime for a "use cache" function.
556
193
  *
@@ -579,7 +216,7 @@ function cacheLife(profile) {
579
216
  };
580
217
  } else return;
581
218
  try {
582
- const ctx = _getCacheContextFn?.();
219
+ const ctx = getRegisteredCacheContext();
583
220
  if (ctx) {
584
221
  ctx.lifeConfigs.push(resolvedConfig);
585
222
  if (resolvedConfig.revalidate !== void 0) ctx.hasExplicitRevalidate = true;
@@ -603,7 +240,7 @@ function cacheLife(profile) {
603
240
  */
604
241
  function cacheTag(...tags) {
605
242
  try {
606
- const ctx = _getCacheContextFn?.();
243
+ const ctx = getRegisteredCacheContext();
607
244
  if (ctx) ctx.tags.push(...encodeCacheTags(tags));
608
245
  } catch {}
609
246
  }
@@ -690,9 +327,6 @@ function getPendingUnstableCacheRevalidations() {
690
327
  _g[_UNSTABLE_CACHE_PENDING_REVALIDATIONS_KEY] = pending;
691
328
  return pending;
692
329
  }
693
- function shouldServeStaleUnstableCacheEntry() {
694
- return _getCacheState().unstableCacheRevalidation === "background";
695
- }
696
330
  function waitUntilUnstableCacheRevalidation(promise) {
697
331
  if (!isInsideUnifiedScope()) return;
698
332
  getRequestContext().executionContext?.waitUntil(promise);
@@ -720,7 +354,7 @@ async function refreshUnstableCacheResult(fn, args, cacheKey, tags, revalidateSe
720
354
  tags,
721
355
  revalidate: typeof revalidateSeconds === "number" ? revalidateSeconds : false
722
356
  };
723
- await _getActiveHandler().set(cacheKey, cacheValue, {
357
+ await getDataCacheHandler().set(cacheKey, cacheValue, {
724
358
  fetchCache: true,
725
359
  tags,
726
360
  revalidate: revalidateSeconds
@@ -746,7 +380,7 @@ function unstable_cache(fn, keyParts, options) {
746
380
  tagCount: tags.length,
747
381
  tagHash: tags.length > 0 ? fnv1a64(JSON.stringify(tags)) : null
748
382
  });
749
- const existing = await _getActiveHandler().get(cacheKey, {
383
+ const existing = await getDataCacheHandler().get(cacheKey, {
750
384
  kind: "FETCH",
751
385
  tags
752
386
  });
@@ -764,4 +398,4 @@ function unstable_cache(fn, keyParts, options) {
764
398
  return cachedFn;
765
399
  }
766
400
  //#endregion
767
- export { MemoryCacheHandler, NoOpCacheHandler, _consumeRequestScopedCacheLife, _initRequestScopedCacheState, _peekRequestScopedCacheLife, _peekUnstableCacheObservations, _registerCacheContextAccessor, _runWithCacheState, _setRequestScopedCacheLife, cacheLife, cacheLifeProfiles, cacheTag, configureMemoryCacheHandler, getAndClearActionRevalidationKind, getCacheHandler, getDataCacheHandler, getRequestExecutionContext, io, isInsideUnstableCacheScope, unstable_noStore as noStore, unstable_noStore, refresh, revalidatePath, revalidateTag, runWithExecutionContext, setCacheHandler, setDataCacheHandler, unstable_cache, unstable_cacheLife, unstable_cacheTag, unstable_io, updateTag };
401
+ export { ACTION_DID_REVALIDATE_DYNAMIC_ONLY, ACTION_DID_REVALIDATE_STATIC_AND_DYNAMIC, MemoryCacheHandler, NoOpCacheHandler, _consumeRequestScopedCacheLife, _initRequestScopedCacheState, _peekRequestScopedCacheLife, _peekUnstableCacheObservations, _registerCacheContextAccessor, _runWithCacheState, _setRequestScopedCacheLife, cacheLife, cacheLifeProfiles, cacheTag, configureMemoryCacheHandler, getAndClearActionRevalidationKind, getCacheHandler, getDataCacheHandler, getRegisteredCacheContext, getRequestExecutionContext, io, isInsideUnstableCacheScope, markActionRevalidation, unstable_noStore as noStore, unstable_noStore, recordUnstableCacheObservation, refresh, revalidatePath, revalidateTag, runWithExecutionContext, setCacheHandler, setDataCacheHandler, shouldServeStaleUnstableCacheEntry, unstable_cache, unstable_cacheLife, unstable_cacheTag, unstable_io, updateTag };
@@ -1,4 +1,4 @@
1
- import { CacheHandlerValue, IncrementalCacheValue } from "./cache.js";
1
+ import { CacheHandlerValue, IncrementalCacheValue } from "./cache-handler.js";
2
2
 
3
3
  //#region src/shims/cdn-cache.d.ts
4
4
  /** A map of response header name -> value the adapter wants applied or removed. */
@@ -1,5 +1,5 @@
1
1
  import { getRequestExecutionContext } from "./request-context.js";
2
- import { getDataCacheHandler } from "./cache.js";
2
+ import { getDataCacheHandler } from "./cache-handler.js";
3
3
  import { CloudflareCdnCacheAdapter } from "../cloudflare/src/cache/cdn-adapter.runtime.js";
4
4
  //#region src/shims/cdn-cache.ts
5
5
  /**
@@ -34,25 +34,23 @@ declare function Main(): React.JSX.Element;
34
34
  */
35
35
  declare function NextScript(): React.JSX.Element;
36
36
  /**
37
- * Loose stand-ins for Next.js's `DocumentContext` / `DocumentInitialProps`.
38
- * The shim doesn't currently invoke `getInitialProps` on user `_document.tsx`
39
- * files (separate gap), but the signatures here match Next.js's so subclasses
40
- * that delegate via `await Document.getInitialProps(ctx)` typecheck against
41
- * the same shape they'd see under real Next.js.
37
+ * Stand-ins for Next.js's `DocumentContext` / `DocumentInitialProps`.
38
+ * The signatures match Next.js so custom `_document.tsx` subclasses can use
39
+ * `ctx.renderPage()` enhancers and delegate through
40
+ * `await Document.getInitialProps(ctx)` with the expected public types.
42
41
  *
43
42
  * @see https://github.com/vercel/next.js/blob/canary/packages/next/src/shared/lib/utils.ts
44
43
  */
45
44
  type DocumentContext = {
46
- renderPage?: (options?: {
45
+ renderPage: (options?: {
47
46
  enhanceApp?: (App: React.ComponentType<{
48
47
  children?: React.ReactNode;
49
- }>) => unknown;
50
- enhanceComponent?: (Comp: React.ComponentType<unknown>) => unknown;
51
- }) => {
52
- html: string;
53
- head?: ReadonlyArray<React.ReactElement>;
54
- };
55
- defaultGetInitialProps?: (ctx: DocumentContext, options?: {
48
+ }>) => React.ComponentType<{
49
+ children?: React.ReactNode;
50
+ }>;
51
+ enhanceComponent?: (Comp: React.ComponentType<unknown>) => React.ComponentType<unknown>;
52
+ } | ((Comp: React.ComponentType<unknown>) => React.ComponentType<unknown>)) => DocumentInitialProps | Promise<DocumentInitialProps>;
53
+ defaultGetInitialProps: (ctx: DocumentContext, options?: {
56
54
  nonce?: string;
57
55
  }) => Promise<DocumentInitialProps>;
58
56
  pathname?: string;
@@ -83,14 +81,11 @@ declare class Document<P = {}> extends React.Component<P & {
83
81
  children?: React.ReactNode;
84
82
  }> {
85
83
  /**
86
- * `getInitialProps` is invoked by the SSR pipeline. The default implementation
87
- * is a stub: vinext does not yet plumb the Pages Router `renderPage` /
88
- * `defaultGetInitialProps` chain into the SSR entry, so subclasses that
89
- * delegate via `await Document.getInitialProps(ctx)` receive an empty shell
90
- * (`html: ""`). This matches the runtime contract user code expects without
91
- * pretending the chain is wired up.
84
+ * `getInitialProps` is invoked by the SSR pipeline. The runtime-provided
85
+ * `ctx.defaultGetInitialProps()` owns the page render and style collection,
86
+ * matching Next.js's canonical CSS-in-JS integration path.
92
87
  */
93
- static getInitialProps(_ctx: DocumentContext): Promise<DocumentInitialProps>;
88
+ static getInitialProps(ctx: DocumentContext): Promise<DocumentInitialProps>;
94
89
  render(): React.ReactNode;
95
90
  }
96
91
  //#endregion
@@ -61,15 +61,12 @@ function NextScript() {
61
61
  */
62
62
  var Document = class extends React.Component {
63
63
  /**
64
- * `getInitialProps` is invoked by the SSR pipeline. The default implementation
65
- * is a stub: vinext does not yet plumb the Pages Router `renderPage` /
66
- * `defaultGetInitialProps` chain into the SSR entry, so subclasses that
67
- * delegate via `await Document.getInitialProps(ctx)` receive an empty shell
68
- * (`html: ""`). This matches the runtime contract user code expects without
69
- * pretending the chain is wired up.
64
+ * `getInitialProps` is invoked by the SSR pipeline. The runtime-provided
65
+ * `ctx.defaultGetInitialProps()` owns the page render and style collection,
66
+ * matching Next.js's canonical CSS-in-JS integration path.
70
67
  */
71
- static async getInitialProps(_ctx) {
72
- return { html: "" };
68
+ static getInitialProps(ctx) {
69
+ return ctx.defaultGetInitialProps(ctx);
73
70
  }
74
71
  render() {
75
72
  return /* @__PURE__ */ jsxs(Html, { children: [/* @__PURE__ */ jsx(Head, {}), /* @__PURE__ */ jsxs("body", { children: [/* @__PURE__ */ jsx(Main, {}), /* @__PURE__ */ jsx(NextScript, {})] })] });
@@ -0,0 +1,7 @@
1
+ import { AppRouterInstance } from "./internal/app-router-context.js";
2
+
3
+ //#region src/shims/error-boundary-navigation.d.ts
4
+ declare function useErrorBoundaryPathname(): string;
5
+ declare function useErrorBoundaryRouter(): AppRouterInstance;
6
+ //#endregion
7
+ export { useErrorBoundaryPathname, useErrorBoundaryRouter };
@@ -0,0 +1,44 @@
1
+ import { stripBasePath } from "../utils/base-path.js";
2
+ import { markPprFallbackShellDynamicBoundary } from "./ppr-fallback-shell.js";
3
+ import { AppRouterContext } from "./internal/app-router-context.js";
4
+ import { getNavigationContext } from "./navigation-context-state.js";
5
+ import "./navigation-server.js";
6
+ import * as React$1 from "react";
7
+ //#region src/shims/error-boundary-navigation.ts
8
+ const CLIENT_NAVIGATION_STATE_KEY = Symbol.for("vinext.clientNavigationState");
9
+ const CLIENT_NAVIGATION_RENDER_CONTEXT_KEY = Symbol.for("vinext.clientNavigationRenderContext");
10
+ const BASE_PATH = process.env.__NEXT_ROUTER_BASEPATH ?? "";
11
+ function getClientNavigationState() {
12
+ return globalThis[CLIENT_NAVIGATION_STATE_KEY];
13
+ }
14
+ function getClientPathnameSnapshot() {
15
+ return getClientNavigationState()?.cachedPathname ?? stripBasePath(window.location.pathname, BASE_PATH);
16
+ }
17
+ function getServerPathnameSnapshot() {
18
+ return getNavigationContext()?.pathname ?? "/";
19
+ }
20
+ function subscribeToCommittedPathname(listener) {
21
+ const state = getClientNavigationState();
22
+ if (!state) return () => {};
23
+ state.listeners.add(listener);
24
+ return () => state.listeners.delete(listener);
25
+ }
26
+ function getClientNavigationRenderContext() {
27
+ const globalState = globalThis;
28
+ return globalState[CLIENT_NAVIGATION_RENDER_CONTEXT_KEY] ??= React$1.createContext(null);
29
+ }
30
+ function useErrorBoundaryPathname() {
31
+ if (typeof window === "undefined") markPprFallbackShellDynamicBoundary();
32
+ const renderSnapshot = React$1.useContext(getClientNavigationRenderContext());
33
+ const committedPathname = React$1.useSyncExternalStore(subscribeToCommittedPathname, getClientPathnameSnapshot, getServerPathnameSnapshot);
34
+ if (renderSnapshot && (getClientNavigationState()?.navigationSnapshotActiveCount ?? 0) > 0) return renderSnapshot.pathname;
35
+ return committedPathname;
36
+ }
37
+ function useErrorBoundaryRouter() {
38
+ if (!AppRouterContext || typeof React$1.useContext !== "function") throw new Error("invariant expected app router to be mounted");
39
+ const router = React$1.useContext(AppRouterContext);
40
+ if (router === null) throw new Error("invariant expected app router to be mounted");
41
+ return router;
42
+ }
43
+ //#endregion
44
+ export { useErrorBoundaryPathname, useErrorBoundaryRouter };