vinext 1.0.0-beta.1 → 1.0.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (175) hide show
  1. package/README.md +4 -1
  2. package/dist/build/client-build-config.js +1 -0
  3. package/dist/build/report.d.ts +8 -1
  4. package/dist/build/report.js +12 -2
  5. package/dist/check.js +15 -2
  6. package/dist/cli.js +3 -2
  7. package/dist/config/config-matchers.d.ts +13 -37
  8. package/dist/config/config-matchers.js +31 -121
  9. package/dist/config/next-config.d.ts +3 -2
  10. package/dist/config/next-config.js +3 -1
  11. package/dist/config/request-context.d.ts +14 -0
  12. package/dist/config/request-context.js +26 -0
  13. package/dist/entries/app-rsc-entry.js +27 -9
  14. package/dist/entries/app-rsc-manifest.js +17 -0
  15. package/dist/entries/pages-server-entry.js +3 -2
  16. package/dist/index.js +82 -58
  17. package/dist/init.d.ts +6 -4
  18. package/dist/init.js +20 -22
  19. package/dist/plugins/og-assets.js +1 -1
  20. package/dist/routing/app-route-graph.d.ts +13 -5
  21. package/dist/routing/app-route-graph.js +59 -13
  22. package/dist/routing/app-router.js +12 -6
  23. package/dist/routing/file-matcher.d.ts +11 -22
  24. package/dist/routing/file-matcher.js +21 -33
  25. package/dist/routing/pages-router.js +23 -29
  26. package/dist/routing/route-matching.d.ts +14 -1
  27. package/dist/routing/route-matching.js +13 -1
  28. package/dist/routing/route-pattern.d.ts +2 -1
  29. package/dist/routing/route-pattern.js +7 -4
  30. package/dist/routing/route-trie.d.ts +5 -1
  31. package/dist/routing/route-trie.js +5 -2
  32. package/dist/server/app-browser-entry.js +7 -6
  33. package/dist/server/app-browser-history-controller.d.ts +1 -1
  34. package/dist/server/app-browser-history-controller.js +3 -3
  35. package/dist/server/app-browser-navigation-controller.js +1 -1
  36. package/dist/server/app-browser-state.js +1 -1
  37. package/dist/server/app-browser-visible-commit.js +1 -1
  38. package/dist/server/app-fallback-renderer.d.ts +3 -0
  39. package/dist/server/app-fallback-renderer.js +4 -2
  40. package/dist/server/app-middleware.js +2 -1
  41. package/dist/server/app-page-boundary-render.d.ts +12 -1
  42. package/dist/server/app-page-boundary-render.js +84 -2
  43. package/dist/server/app-page-cache-finalizer.d.ts +1 -1
  44. package/dist/server/app-page-cache.d.ts +1 -1
  45. package/dist/server/app-page-dispatch.d.ts +11 -2
  46. package/dist/server/app-page-dispatch.js +14 -17
  47. package/dist/server/app-page-element-builder.d.ts +7 -2
  48. package/dist/server/app-page-element-builder.js +112 -27
  49. package/dist/server/app-page-head.d.ts +54 -2
  50. package/dist/server/app-page-head.js +164 -78
  51. package/dist/server/app-page-http-access-fallback-metadata.d.ts +29 -0
  52. package/dist/server/app-page-http-access-fallback-metadata.js +106 -0
  53. package/dist/server/app-page-render.d.ts +2 -2
  54. package/dist/server/app-page-render.js +1 -1
  55. package/dist/server/app-page-request.d.ts +12 -0
  56. package/dist/server/app-page-request.js +133 -13
  57. package/dist/server/app-page-route-wiring.d.ts +9 -0
  58. package/dist/server/app-page-route-wiring.js +43 -3
  59. package/dist/server/app-post-middleware-context.d.ts +1 -1
  60. package/dist/server/app-post-middleware-context.js +1 -1
  61. package/dist/server/app-route-handler-dispatch.js +31 -17
  62. package/dist/server/app-route-handler-execution.d.ts +6 -1
  63. package/dist/server/app-route-handler-execution.js +42 -16
  64. package/dist/server/app-route-handler-policy.d.ts +2 -0
  65. package/dist/server/app-route-handler-policy.js +3 -3
  66. package/dist/server/app-route-module-loader.d.ts +3 -1
  67. package/dist/server/app-route-module-loader.js +1 -0
  68. package/dist/server/app-rsc-cache-busting.d.ts +1 -1
  69. package/dist/server/app-rsc-errors.d.ts +1 -1
  70. package/dist/server/app-rsc-errors.js +12 -2
  71. package/dist/server/app-rsc-handler.d.ts +10 -5
  72. package/dist/server/app-rsc-handler.js +52 -24
  73. package/dist/server/app-rsc-request-normalization.d.ts +3 -2
  74. package/dist/server/app-rsc-request-normalization.js +8 -2
  75. package/dist/server/app-rsc-response-finalizer.d.ts +2 -2
  76. package/dist/server/app-rsc-response-finalizer.js +5 -11
  77. package/dist/server/app-rsc-route-matching.d.ts +20 -0
  78. package/dist/server/app-rsc-route-matching.js +87 -11
  79. package/dist/server/app-segment-config.js +13 -3
  80. package/dist/server/app-server-action-execution.d.ts +3 -1
  81. package/dist/server/app-server-action-execution.js +9 -7
  82. package/dist/server/app-ssr-entry.js +2 -2
  83. package/dist/server/app-ssr-stream.d.ts +1 -7
  84. package/dist/server/app-ssr-stream.js +2 -10
  85. package/dist/server/config-headers.d.ts +24 -0
  86. package/dist/server/config-headers.js +52 -0
  87. package/dist/server/dev-initial-server-error.d.ts +1 -1
  88. package/dist/server/dev-server.js +29 -13
  89. package/dist/server/isr-cache.d.ts +1 -1
  90. package/dist/server/middleware-matcher-pattern.d.ts +22 -0
  91. package/dist/server/middleware-matcher-pattern.js +219 -0
  92. package/dist/server/middleware-matcher.d.ts +2 -7
  93. package/dist/server/middleware-matcher.js +13 -60
  94. package/dist/server/middleware-path-to-regexp.d.ts +14 -0
  95. package/dist/server/middleware-path-to-regexp.js +228 -0
  96. package/dist/server/middleware-runtime.js +4 -3
  97. package/dist/server/middleware.d.ts +1 -1
  98. package/dist/server/middleware.js +2 -1
  99. package/dist/server/pages-data-route.d.ts +11 -1
  100. package/dist/server/pages-data-route.js +16 -1
  101. package/dist/server/pages-get-initial-props.d.ts +15 -2
  102. package/dist/server/pages-get-initial-props.js +16 -6
  103. package/dist/server/pages-page-data.d.ts +3 -1
  104. package/dist/server/pages-page-data.js +16 -7
  105. package/dist/server/pages-page-handler.d.ts +4 -2
  106. package/dist/server/pages-page-handler.js +16 -17
  107. package/dist/server/pages-page-response.js +1 -1
  108. package/dist/server/pages-readiness.d.ts +3 -3
  109. package/dist/server/pages-request-pipeline.d.ts +1 -0
  110. package/dist/server/pages-request-pipeline.js +25 -11
  111. package/dist/server/pages-router-entry.js +6 -0
  112. package/dist/server/prerender-route-params.js +2 -2
  113. package/dist/server/prod-server.d.ts +1 -4
  114. package/dist/server/prod-server.js +36 -23
  115. package/dist/server/request-pipeline.d.ts +15 -29
  116. package/dist/server/request-pipeline.js +24 -59
  117. package/dist/server/rsc-stream-hints.js +122 -18
  118. package/dist/shims/app.d.ts +1 -1
  119. package/dist/shims/cache-request-state.d.ts +27 -1
  120. package/dist/shims/cache-request-state.js +60 -1
  121. package/dist/shims/cache-runtime.d.ts +12 -1
  122. package/dist/shims/cache-runtime.js +22 -7
  123. package/dist/shims/cache.d.ts +5 -5
  124. package/dist/shims/cache.js +26 -10
  125. package/dist/shims/document.d.ts +42 -83
  126. package/dist/shims/document.js +62 -53
  127. package/dist/shims/dynamic.d.ts +5 -25
  128. package/dist/shims/dynamic.js +29 -8
  129. package/dist/shims/error.d.ts +1 -1
  130. package/dist/shims/error.js +1 -1
  131. package/dist/shims/fetch-cache.js +12 -3
  132. package/dist/shims/font-google-base.d.ts +11 -4
  133. package/dist/shims/font-local.d.ts +10 -3
  134. package/dist/shims/head.d.ts +13 -2
  135. package/dist/shims/head.js +3 -3
  136. package/dist/shims/headers.d.ts +28 -31
  137. package/dist/shims/headers.js +109 -49
  138. package/dist/shims/image.d.ts +27 -37
  139. package/dist/shims/image.js +21 -14
  140. package/dist/shims/internal/cookie-serialize.d.ts +3 -1
  141. package/dist/shims/internal/cookie-serialize.js +3 -1
  142. package/dist/shims/internal/hybrid-client-route-owner.js +3 -1
  143. package/dist/shims/internal/utils.d.ts +3 -3
  144. package/dist/shims/legacy-image.d.ts +3 -37
  145. package/dist/shims/legacy-image.js +6 -16
  146. package/dist/shims/link.d.ts +15 -22
  147. package/dist/shims/link.js +20 -11
  148. package/dist/shims/navigation-context-state.d.ts +1 -1
  149. package/dist/shims/navigation.d.ts +7 -3
  150. package/dist/shims/navigation.js +24 -13
  151. package/dist/shims/navigation.react-server.js +1 -1
  152. package/dist/shims/next-shims-augmentations.d.ts +1 -0
  153. package/dist/shims/next-shims-public.d.ts +1 -0
  154. package/dist/shims/public-shim-map.json.js +103 -0
  155. package/dist/shims/readonly-url-search-params.d.ts +3 -3
  156. package/dist/shims/readonly-url-search-params.js +3 -3
  157. package/dist/shims/request-state-types.d.ts +1 -1
  158. package/dist/shims/router.d.ts +55 -21
  159. package/dist/shims/router.js +162 -37
  160. package/dist/shims/script.d.ts +6 -10
  161. package/dist/shims/script.js +6 -3
  162. package/dist/shims/server.d.ts +45 -22
  163. package/dist/shims/server.js +44 -5
  164. package/dist/shims/unified-request-context.d.ts +1 -1
  165. package/dist/shims/unified-request-context.js +2 -0
  166. package/dist/shims/url-safety.d.ts +1 -1
  167. package/dist/shims/url-safety.js +2 -2
  168. package/dist/typegen.d.ts +8 -2
  169. package/dist/typegen.js +76 -15
  170. package/dist/utils/domain-locale.d.ts +2 -2
  171. package/dist/utils/external-url.d.ts +5 -0
  172. package/dist/utils/external-url.js +7 -0
  173. package/dist/utils/regex-safety.d.ts +8 -0
  174. package/dist/utils/regex-safety.js +737 -0
  175. package/package.json +13 -2
@@ -36,7 +36,7 @@ declare function appGetInitialProps({
36
36
  declare class App<P = any, CP = any, S = any> extends React.Component<P & AppProps<CP>, S> {
37
37
  static origGetInitialProps: typeof appGetInitialProps;
38
38
  static getInitialProps: typeof appGetInitialProps;
39
- render(): React.ReactNode;
39
+ render(): React.ReactElement;
40
40
  }
41
41
  //#endregion
42
42
  export { AppContext, AppInitialProps, AppProps, App as default };
@@ -26,6 +26,8 @@ type UnstableCacheObservation = Readonly<{
26
26
  }>;
27
27
  type CacheState = {
28
28
  actionRevalidationKind: ActionRevalidationKind;
29
+ pendingRevalidatedTags: Set<string>;
30
+ pendingRevalidations: Set<Promise<void>>;
29
31
  requestScopedCacheLife: CacheLifeConfig | null;
30
32
  unstableCacheObservations: Map<string, UnstableCacheObservation>;
31
33
  unstableCacheRevalidation: UnstableCacheRevalidationMode;
@@ -37,6 +39,30 @@ declare function _runWithCacheState<T>(fn: () => T | Promise<T>): T | Promise<T>
37
39
  declare function _initRequestScopedCacheState(): void;
38
40
  declare function markActionRevalidation(kind: ActionRevalidationKind): void;
39
41
  declare function getAndClearActionRevalidationKind(): ActionRevalidationKind;
42
+ /** @internal */
43
+ declare function _markPendingRevalidatedTag(tag: string): void;
44
+ /** @internal */
45
+ declare function _hasPendingRevalidatedTag(tags: readonly string[]): boolean;
46
+ /**
47
+ * Record a cache invalidation that must finish before the current action or
48
+ * route-handler request is finalized. The public revalidation APIs remain
49
+ * synchronous, matching Next.js, while the request boundary owns the await.
50
+ *
51
+ * Returns false outside a request-like phase so standalone calls can retain
52
+ * their historical background-work behavior without accumulating promises in
53
+ * the process-global fallback state.
54
+ *
55
+ * @internal
56
+ */
57
+ declare function _queuePendingRevalidation(promise: Promise<void>): boolean;
58
+ /**
59
+ * Await and clear every cache invalidation queued in the current request.
60
+ * Clearing before awaiting also lets a later drain observe work enqueued by
61
+ * an async continuation while this batch is settling.
62
+ *
63
+ * @internal
64
+ */
65
+ declare function _drainPendingRevalidations(): Promise<void>;
40
66
  declare function _setRequestScopedCacheLife(config: CacheLifeConfig): void;
41
67
  declare function _peekRequestScopedCacheLife(): CacheLifeConfig | null;
42
68
  declare function _consumeRequestScopedCacheLife(): CacheLifeConfig | null;
@@ -44,4 +70,4 @@ declare function recordUnstableCacheObservation(observation: UnstableCacheObserv
44
70
  declare function _peekUnstableCacheObservations(): UnstableCacheObservation[];
45
71
  declare function shouldServeStaleUnstableCacheEntry(): boolean;
46
72
  //#endregion
47
- export { ACTION_DID_REVALIDATE_DYNAMIC_ONLY, ACTION_DID_REVALIDATE_STATIC_AND_DYNAMIC, ActionRevalidationKind, CacheLifeConfig, CacheState, UnstableCacheObservation, UnstableCacheRevalidationMode, _consumeRequestScopedCacheLife, _initRequestScopedCacheState, _peekRequestScopedCacheLife, _peekUnstableCacheObservations, _registerCacheContextAccessor, _runWithCacheState, _setRequestScopedCacheLife, cacheLifeProfiles, getAndClearActionRevalidationKind, getRegisteredCacheContext, markActionRevalidation, recordUnstableCacheObservation, shouldServeStaleUnstableCacheEntry };
73
+ export { ACTION_DID_REVALIDATE_DYNAMIC_ONLY, ACTION_DID_REVALIDATE_STATIC_AND_DYNAMIC, ActionRevalidationKind, CacheLifeConfig, CacheState, UnstableCacheObservation, UnstableCacheRevalidationMode, _consumeRequestScopedCacheLife, _drainPendingRevalidations, _hasPendingRevalidatedTag, _initRequestScopedCacheState, _markPendingRevalidatedTag, _peekRequestScopedCacheLife, _peekUnstableCacheObservations, _queuePendingRevalidation, _registerCacheContextAccessor, _runWithCacheState, _setRequestScopedCacheLife, cacheLifeProfiles, getAndClearActionRevalidationKind, getRegisteredCacheContext, markActionRevalidation, recordUnstableCacheObservation, shouldServeStaleUnstableCacheEntry };
@@ -53,6 +53,8 @@ const ACTION_DID_REVALIDATE_STATIC_AND_DYNAMIC = 1;
53
53
  const ACTION_DID_REVALIDATE_DYNAMIC_ONLY = 2;
54
54
  const fallbackState = globalState[FALLBACK_KEY] ??= {
55
55
  actionRevalidationKind: ACTION_DID_NOT_REVALIDATE,
56
+ pendingRevalidatedTags: /* @__PURE__ */ new Set(),
57
+ pendingRevalidations: /* @__PURE__ */ new Set(),
56
58
  requestScopedCacheLife: null,
57
59
  unstableCacheObservations: /* @__PURE__ */ new Map(),
58
60
  unstableCacheRevalidation: "foreground"
@@ -70,6 +72,8 @@ function _runWithCacheState(fn) {
70
72
  }, fn);
71
73
  const state = {
72
74
  actionRevalidationKind: ACTION_DID_NOT_REVALIDATE,
75
+ pendingRevalidatedTags: /* @__PURE__ */ new Set(),
76
+ pendingRevalidations: /* @__PURE__ */ new Set(),
73
77
  requestScopedCacheLife: null,
74
78
  unstableCacheObservations: /* @__PURE__ */ new Map(),
75
79
  unstableCacheRevalidation: "foreground"
@@ -93,6 +97,61 @@ function getAndClearActionRevalidationKind() {
93
97
  state.actionRevalidationKind = ACTION_DID_NOT_REVALIDATE;
94
98
  return kind;
95
99
  }
100
+ function hasRequestScopedCacheState() {
101
+ if (isInsideUnifiedScope() || cacheAls.getStore() !== void 0) return true;
102
+ const phase = getHeadersAccessPhase();
103
+ return phase === "action" || phase === "route-handler";
104
+ }
105
+ /** @internal */
106
+ function _markPendingRevalidatedTag(tag) {
107
+ if (!hasRequestScopedCacheState()) return;
108
+ getCacheState().pendingRevalidatedTags.add(tag);
109
+ }
110
+ /** @internal */
111
+ function _hasPendingRevalidatedTag(tags) {
112
+ if (!hasRequestScopedCacheState()) return false;
113
+ const pendingTags = getCacheState().pendingRevalidatedTags;
114
+ return tags.some((tag) => pendingTags.has(tag));
115
+ }
116
+ /**
117
+ * Record a cache invalidation that must finish before the current action or
118
+ * route-handler request is finalized. The public revalidation APIs remain
119
+ * synchronous, matching Next.js, while the request boundary owns the await.
120
+ *
121
+ * Returns false outside a request-like phase so standalone calls can retain
122
+ * their historical background-work behavior without accumulating promises in
123
+ * the process-global fallback state.
124
+ *
125
+ * @internal
126
+ */
127
+ function _queuePendingRevalidation(promise) {
128
+ if (!hasRequestScopedCacheState()) return false;
129
+ getCacheState().pendingRevalidations.add(promise);
130
+ promise.catch(() => {});
131
+ return true;
132
+ }
133
+ /**
134
+ * Await and clear every cache invalidation queued in the current request.
135
+ * Clearing before awaiting also lets a later drain observe work enqueued by
136
+ * an async continuation while this batch is settling.
137
+ *
138
+ * @internal
139
+ */
140
+ async function _drainPendingRevalidations() {
141
+ const state = getCacheState();
142
+ let didReject = false;
143
+ let firstRejection;
144
+ while (state.pendingRevalidations.size > 0) {
145
+ const pending = [...state.pendingRevalidations];
146
+ state.pendingRevalidations.clear();
147
+ const results = await Promise.allSettled(pending);
148
+ for (const result of results) if (result.status === "rejected" && !didReject) {
149
+ didReject = true;
150
+ firstRejection = result.reason;
151
+ }
152
+ }
153
+ if (didReject) throw firstRejection;
154
+ }
96
155
  function _setRequestScopedCacheLife(config) {
97
156
  const state = getCacheState();
98
157
  if (state.requestScopedCacheLife === null) {
@@ -123,4 +182,4 @@ function shouldServeStaleUnstableCacheEntry() {
123
182
  return getCacheState().unstableCacheRevalidation === "background";
124
183
  }
125
184
  //#endregion
126
- export { ACTION_DID_REVALIDATE_DYNAMIC_ONLY, ACTION_DID_REVALIDATE_STATIC_AND_DYNAMIC, _consumeRequestScopedCacheLife, _initRequestScopedCacheState, _peekRequestScopedCacheLife, _peekUnstableCacheObservations, _registerCacheContextAccessor, _runWithCacheState, _setRequestScopedCacheLife, cacheLifeProfiles, getAndClearActionRevalidationKind, getRegisteredCacheContext, markActionRevalidation, recordUnstableCacheObservation, shouldServeStaleUnstableCacheEntry };
185
+ export { ACTION_DID_REVALIDATE_DYNAMIC_ONLY, ACTION_DID_REVALIDATE_STATIC_AND_DYNAMIC, _consumeRequestScopedCacheLife, _drainPendingRevalidations, _hasPendingRevalidatedTag, _initRequestScopedCacheState, _markPendingRevalidatedTag, _peekRequestScopedCacheLife, _peekUnstableCacheObservations, _queuePendingRevalidation, _registerCacheContextAccessor, _runWithCacheState, _setRequestScopedCacheLife, cacheLifeProfiles, getAndClearActionRevalidationKind, getRegisteredCacheContext, markActionRevalidation, recordUnstableCacheObservation, shouldServeStaleUnstableCacheEntry };
@@ -35,6 +35,17 @@ declare const cacheContextStorage: import("node:async_hooks").AsyncLocalStorage<
35
35
  * Get the current cache context. Returns null if not inside a "use cache" function.
36
36
  */
37
37
  declare function getCacheContext(): CacheContext | null;
38
+ /**
39
+ * Build the shared-cache key for a "use cache" function from its build-scoped
40
+ * identity and serialized arguments.
41
+ *
42
+ * This is a logical handler key, not a storage key. Backend-specific adapters
43
+ * are responsible for mapping it to their physical key constraints after
44
+ * applying any storage prefixes.
45
+ *
46
+ * Exported for testing.
47
+ */
48
+ declare function buildUseCacheKey(id: string, keySeed: string | undefined, argsKey?: string): string;
38
49
  /**
39
50
  * Convert an encodeReply result (string | FormData) to a cache key string.
40
51
  * For FormData (binary args), produces a deterministic SHA-256 hash over
@@ -80,4 +91,4 @@ type RegisterCachedFunctionOptions = {
80
91
  */
81
92
  declare function registerCachedFunction<TArgs extends unknown[], TResult>(fn: (...args: TArgs) => Promise<TResult>, id: string, variant?: string, options?: RegisterCachedFunctionOptions): (...args: TArgs) => Promise<TResult>;
82
93
  //#endregion
83
- export { CacheContext, NestedDynamicUseCacheError, PrivateCacheState, cacheContextStorage, clearPrivateCache, getCacheContext, markAppPagePropsForUseCache, registerCachedFunction, replyToCacheKey, runWithPrivateCache };
94
+ export { CacheContext, NestedDynamicUseCacheError, PrivateCacheState, buildUseCacheKey, cacheContextStorage, clearPrivateCache, getCacheContext, markAppPagePropsForUseCache, registerCachedFunction, replyToCacheKey, runWithPrivateCache };
@@ -4,7 +4,7 @@ import { VINEXT_RSC_MARKER_HEADER } from "../server/headers.js";
4
4
  import { getDataCacheHandler } from "./cache-handler.js";
5
5
  import { trackPprFallbackShellCacheTask } from "./ppr-fallback-shell.js";
6
6
  import { markDynamicUsage } from "./headers.js";
7
- import { _registerCacheContextAccessor, _setRequestScopedCacheLife, cacheLifeProfiles } from "./cache-request-state.js";
7
+ import { _hasPendingRevalidatedTag, _registerCacheContextAccessor, _setRequestScopedCacheLife, cacheLifeProfiles } from "./cache-request-state.js";
8
8
  import { addCollectedRequestTags, getCurrentFetchSoftTags } from "./fetch-cache.js";
9
9
  import { isMarkedAppPagePropsObject, markAppPagePropsForUseCache } from "./internal/app-page-props-cache-key.js";
10
10
  //#region src/shims/cache-runtime.ts
@@ -102,6 +102,16 @@ function getUseCacheBuildIdDefine() {
102
102
  function getUseCacheKeySeed() {
103
103
  return getUseCacheDeploymentIdDefine() || getUseCacheBuildIdDefine();
104
104
  }
105
+ /**
106
+ * Build the shared-cache key for a "use cache" function from its build-scoped
107
+ * identity and serialized arguments.
108
+ *
109
+ * This is a logical handler key, not a storage key. Backend-specific adapters
110
+ * are responsible for mapping it to their physical key constraints after
111
+ * applying any storage prefixes.
112
+ *
113
+ * Exported for testing.
114
+ */
105
115
  function buildUseCacheKey(id, keySeed, argsKey) {
106
116
  const scopedId = keySeed ? `build:${encodeURIComponent(keySeed)}:${id}` : id;
107
117
  return argsKey === void 0 ? `use-cache:${scopedId}` : `use-cache:${scopedId}:${argsKey}`;
@@ -263,11 +273,16 @@ function registerCachedFunction(fn, id, variant, options = {}) {
263
273
  if (isDev) return executeWithContext(fn, args, cacheVariant);
264
274
  const handler = getDataCacheHandler();
265
275
  const softTags = getCurrentFetchSoftTags();
266
- const existing = await handler.get(cacheKey, {
267
- kind: "FETCH",
268
- softTags
269
- });
270
- if (existing?.value && existing.value.kind === "FETCH" && existing.cacheState !== "stale") try {
276
+ let existing = null;
277
+ if (!_hasPendingRevalidatedTag(softTags)) try {
278
+ existing = await handler.get(cacheKey, {
279
+ kind: "FETCH",
280
+ softTags
281
+ });
282
+ } catch (error) {
283
+ console.error("[vinext] use cache: handler.get failed; treating as a cache miss:", error);
284
+ }
285
+ if (existing?.value && existing.value.kind === "FETCH" && existing.cacheState !== "stale" && !_hasPendingRevalidatedTag([...existing.value.tags ?? [], ...softTags])) try {
271
286
  propagateCacheTagsToRequest(existing.value.tags);
272
287
  if (rsc && existing.value.data.headers["x-vinext-rsc"] === "1") {
273
288
  const stream = uint8ToStream(base64ToUint8(existing.value.data.body));
@@ -449,4 +464,4 @@ function stableStringify(value, seen) {
449
464
  return JSON.stringify(value);
450
465
  }
451
466
  //#endregion
452
- export { NestedDynamicUseCacheError, cacheContextStorage, clearPrivateCache, getCacheContext, markAppPagePropsForUseCache, registerCachedFunction, replyToCacheKey, runWithPrivateCache };
467
+ export { NestedDynamicUseCacheError, buildUseCacheKey, cacheContextStorage, clearPrivateCache, getCacheContext, markAppPagePropsForUseCache, registerCachedFunction, replyToCacheKey, runWithPrivateCache };
@@ -1,4 +1,4 @@
1
- import { ACTION_DID_REVALIDATE_DYNAMIC_ONLY, ACTION_DID_REVALIDATE_STATIC_AND_DYNAMIC, ActionRevalidationKind, CacheLifeConfig, CacheState, UnstableCacheObservation, UnstableCacheRevalidationMode, _consumeRequestScopedCacheLife, _initRequestScopedCacheState, _peekRequestScopedCacheLife, _peekUnstableCacheObservations, _registerCacheContextAccessor, _runWithCacheState, _setRequestScopedCacheLife, cacheLifeProfiles, getAndClearActionRevalidationKind, getRegisteredCacheContext, markActionRevalidation, recordUnstableCacheObservation, shouldServeStaleUnstableCacheEntry } from "./cache-request-state.js";
1
+ import { ACTION_DID_REVALIDATE_DYNAMIC_ONLY, ACTION_DID_REVALIDATE_STATIC_AND_DYNAMIC, ActionRevalidationKind, CacheLifeConfig, CacheState, UnstableCacheObservation, UnstableCacheRevalidationMode, _consumeRequestScopedCacheLife, _drainPendingRevalidations, _hasPendingRevalidatedTag, _initRequestScopedCacheState, _markPendingRevalidatedTag, _peekRequestScopedCacheLife, _peekUnstableCacheObservations, _queuePendingRevalidation, _registerCacheContextAccessor, _runWithCacheState, _setRequestScopedCacheLife, cacheLifeProfiles, getAndClearActionRevalidationKind, getRegisteredCacheContext, markActionRevalidation, recordUnstableCacheObservation, shouldServeStaleUnstableCacheEntry } from "./cache-request-state.js";
2
2
  import { ExecutionContextLike, getRequestExecutionContext, runWithExecutionContext } from "./request-context.js";
3
3
  import { CacheControlMetadata, CacheHandler, CacheHandlerContext, CacheHandlerValue, CachedAppPageValue, CachedFetchValue, CachedImageValue, CachedPagesValue, CachedRedirectValue, CachedRouteValue, IncrementalCacheValue, MemoryCacheHandler, NoOpCacheHandler, configureMemoryCacheHandler, getCacheHandler, getDataCacheHandler, setCacheHandler, setDataCacheHandler } from "./cache-handler.js";
4
4
 
@@ -18,7 +18,7 @@ import { CacheControlMetadata, CacheHandler, CacheHandlerContext, CacheHandlerVa
18
18
  */
19
19
  declare function revalidateTag(tag: string, profile?: string | {
20
20
  expire?: number;
21
- }): Promise<void>;
21
+ }): undefined;
22
22
  /**
23
23
  * Revalidate cached data associated with a specific path.
24
24
  *
@@ -34,7 +34,7 @@ declare function revalidateTag(tag: string, profile?: string | {
34
34
  * The `type` parameter is App Router only — Pages Router does not generate
35
35
  * layout/page hierarchy tags, so only no-type invalidation applies there.
36
36
  */
37
- declare function revalidatePath(path: string, type?: "page" | "layout"): Promise<void>;
37
+ declare function revalidatePath(path: string, type?: "page" | "layout"): undefined;
38
38
  /**
39
39
  * No-op shim for API compatibility.
40
40
  *
@@ -57,7 +57,7 @@ declare function refresh(): void;
57
57
  *
58
58
  * @see https://nextjs.org/docs/app/api-reference/functions/updateTag
59
59
  */
60
- declare function updateTag(tag: string): Promise<void>;
60
+ declare function updateTag(tag: string): undefined;
61
61
  /**
62
62
  * Opt out of static rendering and indicate a particular component should not be cached.
63
63
  *
@@ -142,4 +142,4 @@ type UnstableCacheOptions = {
142
142
  */
143
143
  declare function unstable_cache<T extends (...args: any[]) => Promise<any>>(fn: T, keyParts?: string[], options?: UnstableCacheOptions): T;
144
144
  //#endregion
145
- export { ACTION_DID_REVALIDATE_DYNAMIC_ONLY, ACTION_DID_REVALIDATE_STATIC_AND_DYNAMIC, ActionRevalidationKind, CacheControlMetadata, CacheHandler, CacheHandlerContext, CacheHandlerValue, CacheLifeConfig, CacheState, CachedAppPageValue, CachedFetchValue, CachedImageValue, CachedPagesValue, CachedRedirectValue, CachedRouteValue, type ExecutionContextLike, IncrementalCacheValue, MemoryCacheHandler, NoOpCacheHandler, UnstableCacheObservation, UnstableCacheRevalidationMode, _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 };
145
+ export { ACTION_DID_REVALIDATE_DYNAMIC_ONLY, ACTION_DID_REVALIDATE_STATIC_AND_DYNAMIC, ActionRevalidationKind, CacheControlMetadata, CacheHandler, CacheHandlerContext, CacheHandlerValue, CacheLifeConfig, CacheState, CachedAppPageValue, CachedFetchValue, CachedImageValue, CachedPagesValue, CachedRedirectValue, CachedRouteValue, type ExecutionContextLike, IncrementalCacheValue, MemoryCacheHandler, NoOpCacheHandler, UnstableCacheObservation, UnstableCacheRevalidationMode, _consumeRequestScopedCacheLife, _drainPendingRevalidations, _hasPendingRevalidatedTag, _initRequestScopedCacheState, _markPendingRevalidatedTag, _peekRequestScopedCacheLife, _peekUnstableCacheObservations, _queuePendingRevalidation, _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 };
@@ -6,9 +6,9 @@ import { getCdnCacheAdapter } from "./cdn-cache.js";
6
6
  import { fnv1a64 } from "../utils/hash.js";
7
7
  import { makeHangingPromise } from "./internal/make-hanging-promise.js";
8
8
  import { getHeadersAccessPhase, isDraftModeEnabled, markDynamicUsage } from "./headers.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
+ import { ACTION_DID_REVALIDATE_DYNAMIC_ONLY, ACTION_DID_REVALIDATE_STATIC_AND_DYNAMIC, _consumeRequestScopedCacheLife, _drainPendingRevalidations, _hasPendingRevalidatedTag, _initRequestScopedCacheState, _markPendingRevalidatedTag, _peekRequestScopedCacheLife, _peekUnstableCacheObservations, _queuePendingRevalidation, _registerCacheContextAccessor, _runWithCacheState, _setRequestScopedCacheLife, cacheLifeProfiles, getAndClearActionRevalidationKind, getRegisteredCacheContext, markActionRevalidation, recordUnstableCacheObservation, shouldServeStaleUnstableCacheEntry } from "./cache-request-state.js";
10
10
  import { encodeCacheTag, encodeCacheTags } from "../utils/encode-cache-tag.js";
11
- import { addCollectedRequestTags } from "./fetch-cache.js";
11
+ import { addCollectedRequestTags, getCurrentFetchSoftTags } from "./fetch-cache.js";
12
12
  import { workUnitAsyncStorage } from "./internal/work-unit-async-storage.js";
13
13
  //#region src/shims/cache.ts
14
14
  /**
@@ -32,6 +32,14 @@ import { workUnitAsyncStorage } from "./internal/work-unit-async-storage.js";
32
32
  * target used by the generated cache-adapter module.
33
33
  */
34
34
  const _g = globalThis;
35
+ function scheduleRevalidation(promise) {
36
+ const executionContext = getRequestExecutionContext();
37
+ const queued = _queuePendingRevalidation(promise);
38
+ if (executionContext) executionContext.waitUntil(promise);
39
+ else if (!queued) promise.catch((error) => {
40
+ console.error("[vinext] cache revalidation failed:", error);
41
+ });
42
+ }
35
43
  /**
36
44
  * Revalidate cached data associated with a specific cache tag.
37
45
  *
@@ -45,14 +53,16 @@ const _g = globalThis;
45
53
  * @param tag - Cache tag to revalidate
46
54
  * @param profile - cacheLife profile name (e.g. 'max', 'hours') or inline { expire: number }
47
55
  */
48
- async function revalidateTag(tag, profile) {
56
+ function revalidateTag(tag, profile) {
49
57
  let durations;
50
58
  if (typeof profile === "string") {
51
59
  const resolved = cacheLifeProfiles[profile];
52
60
  if (resolved) durations = { expire: resolved.expire };
53
61
  } else if (profile && typeof profile === "object") durations = profile;
54
62
  if (!profile || !durations || durations.expire === 0) markActionRevalidation(1);
55
- await _invalidateEncodedTag(encodeCacheTag(tag), durations);
63
+ const encodedTag = encodeCacheTag(tag);
64
+ _markPendingRevalidatedTag(encodedTag);
65
+ return scheduleRevalidation(_invalidateEncodedTag(encodedTag, durations));
56
66
  }
57
67
  /**
58
68
  * Invalidate one already-encoded tag across both cache layers.
@@ -82,10 +92,12 @@ async function _invalidateEncodedTag(encoded, durations) {
82
92
  * The `type` parameter is App Router only — Pages Router does not generate
83
93
  * layout/page hierarchy tags, so only no-type invalidation applies there.
84
94
  */
85
- async function revalidatePath(path, type) {
95
+ function revalidatePath(path, type) {
86
96
  markActionRevalidation(1);
87
97
  const stem = path.endsWith("/") ? path.slice(0, -1) : path;
88
- await _invalidateEncodedTag(encodeCacheTag(type ? `_N_T_${stem}/${type}` : `_N_T_${stem || "/"}`));
98
+ const encodedTag = encodeCacheTag(type ? `_N_T_${stem}/${type}` : `_N_T_${stem || "/"}`);
99
+ _markPendingRevalidatedTag(encodedTag);
100
+ return scheduleRevalidation(_invalidateEncodedTag(encodedTag));
89
101
  }
90
102
  /**
91
103
  * No-op shim for API compatibility.
@@ -114,7 +126,9 @@ function refresh() {
114
126
  function updateTag(tag) {
115
127
  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");
116
128
  markActionRevalidation(1);
117
- return _invalidateEncodedTag(encodeCacheTag(tag));
129
+ const encodedTag = encodeCacheTag(tag);
130
+ _markPendingRevalidatedTag(encodedTag);
131
+ return scheduleRevalidation(_invalidateEncodedTag(encodedTag));
118
132
  }
119
133
  /**
120
134
  * Opt out of static rendering and indicate a particular component should not be cached.
@@ -386,9 +400,11 @@ function unstable_cache(fn, keyParts, options) {
386
400
  });
387
401
  const isDraftMode = isDraftModeEnabled();
388
402
  if (!isDraftMode) {
389
- const existing = await getDataCacheHandler().get(cacheKey, {
403
+ const softTags = getCurrentFetchSoftTags();
404
+ const existing = _hasPendingRevalidatedTag([...tags, ...softTags]) ? null : await getDataCacheHandler().get(cacheKey, {
390
405
  kind: "FETCH",
391
- tags
406
+ tags,
407
+ softTags
392
408
  });
393
409
  if (existing?.value && existing.value.kind === "FETCH") {
394
410
  const cached = tryDeserializeUnstableCacheResult(existing.value.data.body);
@@ -406,4 +422,4 @@ function unstable_cache(fn, keyParts, options) {
406
422
  return cachedFn;
407
423
  }
408
424
  //#endregion
409
- 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 };
425
+ export { ACTION_DID_REVALIDATE_DYNAMIC_ONLY, ACTION_DID_REVALIDATE_STATIC_AND_DYNAMIC, MemoryCacheHandler, NoOpCacheHandler, _consumeRequestScopedCacheLife, _drainPendingRevalidations, _hasPendingRevalidatedTag, _initRequestScopedCacheState, _markPendingRevalidatedTag, _peekRequestScopedCacheLife, _peekUnstableCacheObservations, _queuePendingRevalidation, _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,92 +1,51 @@
1
1
  import React from "react";
2
+ import { DocumentContext, DocumentInitialProps, DocumentProps } from "@vinext/types/next/upstream/dist/shared/lib/utils";
3
+ import { HtmlProps } from "@vinext/types/next/upstream/dist/shared/lib/html-context.shared-runtime";
2
4
 
3
5
  //#region src/shims/document.d.ts
4
- declare function Html({
5
- children,
6
- lang,
7
- ...props
8
- }: React.HTMLAttributes<HTMLHtmlElement> & {
6
+ type OriginProps = {
7
+ nonce?: string;
8
+ crossOrigin?: "anonymous" | "use-credentials" | "" | undefined;
9
9
  children?: React.ReactNode;
10
- }): React.JSX.Element;
11
- /**
12
- * Document Head - renders <head> with children.
13
- * The dev server injects meta tags, styles, etc.
14
- *
15
- * Note: charset and viewport are intentionally NOT hardcoded here. Those
16
- * defaults are seeded by `next/head`'s `defaultHead()` and emitted alongside
17
- * user `<Head>` tags via `getSSRHeadHTML()`, matching Next.js's canonical
18
- * ordering (`<meta charset>` first, then `<meta viewport>`, then user tags,
19
- * all with `data-next-head=""`). See `test/e2e/next-head/index.test.ts`.
20
- */
21
- declare function Head({
22
- children
23
- }: {
24
- children?: React.ReactNode;
25
- }): React.JSX.Element;
26
- /**
27
- * Main - renders the page content container.
28
- */
29
- declare function Main(): React.JSX.Element;
30
- /**
31
- * NextScript - renders a placeholder that the dev-server replaces with
32
- * actual hydration scripts (__NEXT_DATA__ + entry module).
33
- * Uses dangerouslySetInnerHTML so the HTML comment survives renderToString.
34
- */
35
- declare function NextScript(): React.JSX.Element;
36
- /**
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.
41
- *
42
- * @see https://github.com/vercel/next.js/blob/canary/packages/next/src/shared/lib/utils.ts
43
- */
44
- type DocumentContext = {
45
- renderPage: (options?: {
46
- enhanceApp?: (App: React.ComponentType<{
47
- children?: React.ReactNode;
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?: {
54
- nonce?: string;
55
- }) => Promise<DocumentInitialProps>;
56
- pathname?: string;
57
- query?: Record<string, string | string[] | undefined>;
58
- asPath?: string;
59
- err?: any;
60
10
  };
61
- type DocumentInitialProps = {
62
- html: string;
63
- head?: ReadonlyArray<React.ReactElement>;
64
- styles?: React.ReactElement[] | Iterable<React.ReactNode> | React.ReactElement;
11
+ type DocumentFiles = {
12
+ sharedFiles: readonly string[];
13
+ pageFiles: readonly string[];
14
+ allFiles: readonly string[];
65
15
  };
66
- /**
67
- * Default Document component — also the base class user `_document.tsx` files
68
- * `extend`. Must be a class (not a function) to match Next.js's `next/document`
69
- * default export so `class MyDocument extends Document` produces a constructible
70
- * class that React can instantiate during SSR. Returning a function here breaks
71
- * any user `_document.tsx` that uses the class-based form because `extends`
72
- * against a non-constructor produces a class that can only be called without
73
- * `new`, which React refuses to do.
74
- *
75
- * @see https://github.com/vercel/next.js/blob/canary/packages/next/src/pages/_document.tsx
76
- * Ported behavior: Next.js's default `Document` is a `class Document extends
77
- * React.Component`. Custom documents extend it and override `getInitialProps`
78
- * and `render`. Generic default matches Next.js (`P = {}`).
79
- */
80
- declare class Document<P = {}> extends React.Component<P & {
81
- children?: React.ReactNode;
82
- }> {
83
- /**
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.
87
- */
16
+ type HeadProps = OriginProps & React.ComponentPropsWithoutRef<"head">;
17
+ declare function Html(props: React.DetailedHTMLProps<React.HtmlHTMLAttributes<HTMLHtmlElement>, HTMLHtmlElement>): React.ReactElement;
18
+ interface Head {
19
+ context: HtmlProps;
20
+ }
21
+ declare class Head extends React.Component<HeadProps> {
22
+ static contextType: React.Context<HtmlProps | undefined>;
23
+ getCssLinks(_files: DocumentFiles): React.ReactElement[] | null;
24
+ getPreloadDynamicChunks(): Array<React.ReactElement | null>;
25
+ getPreloadMainLinks(_files: DocumentFiles): React.ReactElement[] | null;
26
+ getBeforeInteractiveInlineScripts(): React.ReactElement[];
27
+ getDynamicChunks(_files: DocumentFiles): Array<React.ReactElement | null>;
28
+ getPreNextScripts(): React.ReactElement;
29
+ getScripts(_files: DocumentFiles): React.ReactElement[];
30
+ getPolyfillScripts(): React.ReactElement[];
31
+ render(): React.ReactElement;
32
+ }
33
+ declare function Main(): React.ReactElement;
34
+ interface NextScript {
35
+ context: HtmlProps;
36
+ }
37
+ declare class NextScript extends React.Component<OriginProps> {
38
+ static contextType: React.Context<HtmlProps | undefined>;
39
+ getDynamicChunks(_files: DocumentFiles): Array<React.ReactElement | null>;
40
+ getPreNextScripts(): React.ReactElement;
41
+ getScripts(_files: DocumentFiles): React.ReactElement[];
42
+ getPolyfillScripts(): React.ReactElement[];
43
+ static getInlineScriptSource(context: Readonly<HtmlProps>): string;
44
+ render(): React.ReactElement;
45
+ }
46
+ declare class Document<P = {}> extends React.Component<DocumentProps & P> {
88
47
  static getInitialProps(ctx: DocumentContext): Promise<DocumentInitialProps>;
89
- render(): React.ReactNode;
48
+ render(): React.ReactElement;
90
49
  }
91
50
  //#endregion
92
- export { DocumentContext, DocumentInitialProps, Head, Html, Main, NextScript, Document as default };
51
+ export { type DocumentContext, type DocumentInitialProps, type DocumentProps, Head, Html, Main, NextScript, OriginProps, Document as default };
@@ -1,70 +1,79 @@
1
1
  import React from "react";
2
- import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
3
3
  //#region src/shims/document.tsx
4
4
  /**
5
5
  * next/document shim
6
6
  *
7
- * Provides Html, Head, Main, NextScript components for custom _document.tsx.
8
- * During SSR these render placeholder markers that the dev server replaces
9
- * with actual content.
7
+ * Provides Html, Head, Main, NextScript, and the class-based Document API for
8
+ * custom Pages Router documents. Vinext's renderer replaces the Main and
9
+ * NextScript placeholders with the rendered page and hydration scripts.
10
10
  */
11
- function Html({ children, lang, ...props }) {
12
- return /* @__PURE__ */ jsx("html", {
13
- lang,
14
- ...props,
15
- children
16
- });
17
- }
18
- /**
19
- * Document Head - renders <head> with children.
20
- * The dev server injects meta tags, styles, etc.
21
- *
22
- * Note: charset and viewport are intentionally NOT hardcoded here. Those
23
- * defaults are seeded by `next/head`'s `defaultHead()` and emitted alongside
24
- * user `<Head>` tags via `getSSRHeadHTML()`, matching Next.js's canonical
25
- * ordering (`<meta charset>` first, then `<meta viewport>`, then user tags,
26
- * all with `data-next-head=""`). See `test/e2e/next-head/index.test.ts`.
27
- */
28
- function Head({ children }) {
29
- return /* @__PURE__ */ jsx("head", { children });
11
+ const HtmlContext = React.createContext(void 0);
12
+ function Html(props) {
13
+ return /* @__PURE__ */ jsx("html", { ...props });
30
14
  }
31
- /**
32
- * Main - renders the page content container.
33
- */
15
+ var Head = class extends React.Component {
16
+ static contextType = HtmlContext;
17
+ getCssLinks(_files) {
18
+ return null;
19
+ }
20
+ getPreloadDynamicChunks() {
21
+ return [];
22
+ }
23
+ getPreloadMainLinks(_files) {
24
+ return null;
25
+ }
26
+ getBeforeInteractiveInlineScripts() {
27
+ return [];
28
+ }
29
+ getDynamicChunks(_files) {
30
+ return [];
31
+ }
32
+ getPreNextScripts() {
33
+ return /* @__PURE__ */ jsx(Fragment$1, {});
34
+ }
35
+ getScripts(_files) {
36
+ return [];
37
+ }
38
+ getPolyfillScripts() {
39
+ return [];
40
+ }
41
+ render() {
42
+ const { children, ...props } = this.props;
43
+ return /* @__PURE__ */ jsx("head", {
44
+ ...props,
45
+ children
46
+ });
47
+ }
48
+ };
34
49
  function Main() {
35
50
  return /* @__PURE__ */ jsx("div", {
36
51
  id: "__next",
37
52
  dangerouslySetInnerHTML: { __html: "__NEXT_MAIN__" }
38
53
  });
39
54
  }
40
- /**
41
- * NextScript - renders a placeholder that the dev-server replaces with
42
- * actual hydration scripts (__NEXT_DATA__ + entry module).
43
- * Uses dangerouslySetInnerHTML so the HTML comment survives renderToString.
44
- */
45
- function NextScript() {
46
- return /* @__PURE__ */ jsx("span", { dangerouslySetInnerHTML: { __html: "<!-- __NEXT_SCRIPTS__ -->" } });
47
- }
48
- /**
49
- * Default Document component — also the base class user `_document.tsx` files
50
- * `extend`. Must be a class (not a function) to match Next.js's `next/document`
51
- * default export so `class MyDocument extends Document` produces a constructible
52
- * class that React can instantiate during SSR. Returning a function here breaks
53
- * any user `_document.tsx` that uses the class-based form because `extends`
54
- * against a non-constructor produces a class that can only be called without
55
- * `new`, which React refuses to do.
56
- *
57
- * @see https://github.com/vercel/next.js/blob/canary/packages/next/src/pages/_document.tsx
58
- * Ported behavior: Next.js's default `Document` is a `class Document extends
59
- * React.Component`. Custom documents extend it and override `getInitialProps`
60
- * and `render`. Generic default matches Next.js (`P = {}`).
61
- */
55
+ var NextScript = class extends React.Component {
56
+ static contextType = HtmlContext;
57
+ getDynamicChunks(_files) {
58
+ return [];
59
+ }
60
+ getPreNextScripts() {
61
+ return /* @__PURE__ */ jsx(Fragment$1, {});
62
+ }
63
+ getScripts(_files) {
64
+ return [];
65
+ }
66
+ getPolyfillScripts() {
67
+ return [];
68
+ }
69
+ static getInlineScriptSource(context) {
70
+ return JSON.stringify(context.__NEXT_DATA__);
71
+ }
72
+ render() {
73
+ return /* @__PURE__ */ jsx("span", { dangerouslySetInnerHTML: { __html: "<!-- __NEXT_SCRIPTS__ -->" } });
74
+ }
75
+ };
62
76
  var Document = class extends React.Component {
63
- /**
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.
67
- */
68
77
  static getInitialProps(ctx) {
69
78
  return ctx.defaultGetInitialProps(ctx);
70
79
  }