vinext 0.0.47 → 0.0.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/build/layout-classification.js +3 -1
- package/dist/build/layout-classification.js.map +1 -1
- package/dist/build/prerender.js +10 -10
- package/dist/build/prerender.js.map +1 -1
- package/dist/build/report.d.ts +8 -4
- package/dist/build/report.js +17 -7
- package/dist/build/report.js.map +1 -1
- package/dist/build/run-prerender.d.ts +5 -0
- package/dist/build/run-prerender.js +4 -1
- package/dist/build/run-prerender.js.map +1 -1
- package/dist/build/server-manifest.js +2 -7
- package/dist/build/server-manifest.js.map +1 -1
- package/dist/build/standalone.js +3 -5
- package/dist/build/standalone.js.map +1 -1
- package/dist/check.js +45 -29
- package/dist/check.js.map +1 -1
- package/dist/cli-args.d.ts +3 -1
- package/dist/cli-args.js +18 -1
- package/dist/cli-args.js.map +1 -1
- package/dist/cli.js +9 -1
- package/dist/cli.js.map +1 -1
- package/dist/config/config-matchers.js +46 -37
- package/dist/config/config-matchers.js.map +1 -1
- package/dist/deploy.d.ts +18 -2
- package/dist/deploy.js +47 -4
- package/dist/deploy.js.map +1 -1
- package/dist/entries/app-rsc-entry.js +11 -9
- package/dist/entries/app-rsc-entry.js.map +1 -1
- package/dist/entries/app-rsc-manifest.js +4 -1
- package/dist/entries/app-rsc-manifest.js.map +1 -1
- package/dist/entries/pages-client-entry.js +3 -2
- package/dist/entries/pages-client-entry.js.map +1 -1
- package/dist/entries/pages-server-entry.js +21 -62
- package/dist/entries/pages-server-entry.js.map +1 -1
- package/dist/entries/runtime-entry-module.d.ts +12 -3
- package/dist/entries/runtime-entry-module.js +15 -4
- package/dist/entries/runtime-entry-module.js.map +1 -1
- package/dist/index.js +12 -7
- package/dist/index.js.map +1 -1
- package/dist/init.d.ts +1 -1
- package/dist/init.js +2 -2
- package/dist/init.js.map +1 -1
- package/dist/plugins/og-assets.js +15 -16
- package/dist/plugins/og-assets.js.map +1 -1
- package/dist/plugins/rsc-client-shim-excludes.d.ts +2 -1
- package/dist/plugins/rsc-client-shim-excludes.js +10 -1
- package/dist/plugins/rsc-client-shim-excludes.js.map +1 -1
- package/dist/routing/app-route-graph.d.ts +90 -4
- package/dist/routing/app-route-graph.js +210 -7
- package/dist/routing/app-route-graph.js.map +1 -1
- package/dist/routing/app-router.d.ts +15 -3
- package/dist/routing/app-router.js +20 -23
- package/dist/routing/app-router.js.map +1 -1
- package/dist/routing/file-matcher.d.ts +3 -1
- package/dist/routing/file-matcher.js +6 -1
- package/dist/routing/file-matcher.js.map +1 -1
- package/dist/routing/pages-router.js +10 -19
- package/dist/routing/pages-router.js.map +1 -1
- package/dist/routing/route-matching.d.ts +28 -0
- package/dist/routing/route-matching.js +44 -0
- package/dist/routing/route-matching.js.map +1 -0
- package/dist/routing/route-pattern.js +4 -1
- package/dist/routing/route-pattern.js.map +1 -1
- package/dist/routing/route-trie.d.ts +8 -0
- package/dist/routing/route-trie.js +12 -1
- package/dist/routing/route-trie.js.map +1 -1
- package/dist/routing/route-validation.js +3 -4
- package/dist/routing/route-validation.js.map +1 -1
- package/dist/routing/utils.d.ts +8 -1
- package/dist/routing/utils.js +25 -2
- package/dist/routing/utils.js.map +1 -1
- package/dist/server/api-handler.js +2 -8
- package/dist/server/api-handler.js.map +1 -1
- package/dist/server/app-browser-entry.js +66 -49
- package/dist/server/app-browser-entry.js.map +1 -1
- package/dist/server/app-browser-navigation-controller.d.ts +7 -5
- package/dist/server/app-browser-navigation-controller.js +43 -35
- package/dist/server/app-browser-navigation-controller.js.map +1 -1
- package/dist/server/app-browser-state.d.ts +33 -15
- package/dist/server/app-browser-state.js +52 -59
- package/dist/server/app-browser-state.js.map +1 -1
- package/dist/server/app-browser-visible-commit.d.ts +68 -0
- package/dist/server/app-browser-visible-commit.js +182 -0
- package/dist/server/app-browser-visible-commit.js.map +1 -0
- package/dist/server/app-client-reference-preloader.d.ts +15 -0
- package/dist/server/app-client-reference-preloader.js +46 -0
- package/dist/server/app-client-reference-preloader.js.map +1 -0
- package/dist/server/app-elements-wire.d.ts +130 -0
- package/dist/server/app-elements-wire.js +205 -0
- package/dist/server/app-elements-wire.js.map +1 -0
- package/dist/server/app-elements.d.ts +2 -84
- package/dist/server/app-elements.js +3 -102
- package/dist/server/app-elements.js.map +1 -1
- package/dist/server/app-fallback-renderer.d.ts +1 -1
- package/dist/server/app-middleware.d.ts +2 -1
- package/dist/server/app-middleware.js +34 -11
- package/dist/server/app-middleware.js.map +1 -1
- package/dist/server/app-page-boundary-render.d.ts +1 -1
- package/dist/server/app-page-boundary-render.js +8 -5
- package/dist/server/app-page-boundary-render.js.map +1 -1
- package/dist/server/app-page-boundary.js +2 -1
- package/dist/server/app-page-boundary.js.map +1 -1
- package/dist/server/app-page-cache.d.ts +1 -0
- package/dist/server/app-page-cache.js +8 -13
- package/dist/server/app-page-cache.js.map +1 -1
- package/dist/server/app-page-dispatch.d.ts +2 -1
- package/dist/server/app-page-dispatch.js +18 -10
- package/dist/server/app-page-dispatch.js.map +1 -1
- package/dist/server/app-page-element-builder.d.ts +1 -1
- package/dist/server/app-page-element-builder.js +8 -5
- package/dist/server/app-page-element-builder.js.map +1 -1
- package/dist/server/app-page-execution.d.ts +23 -5
- package/dist/server/app-page-execution.js +39 -24
- package/dist/server/app-page-execution.js.map +1 -1
- package/dist/server/app-page-head.js +2 -1
- package/dist/server/app-page-head.js.map +1 -1
- package/dist/server/app-page-method.js +2 -5
- package/dist/server/app-page-method.js.map +1 -1
- package/dist/server/app-page-probe.d.ts +1 -1
- package/dist/server/app-page-probe.js +5 -1
- package/dist/server/app-page-probe.js.map +1 -1
- package/dist/server/app-page-render.d.ts +1 -1
- package/dist/server/app-page-render.js +38 -3
- package/dist/server/app-page-render.js.map +1 -1
- package/dist/server/app-page-request.d.ts +0 -1
- package/dist/server/app-page-request.js +7 -10
- package/dist/server/app-page-request.js.map +1 -1
- package/dist/server/app-page-response.js +3 -2
- package/dist/server/app-page-response.js.map +1 -1
- package/dist/server/app-page-route-wiring.d.ts +5 -2
- package/dist/server/app-page-route-wiring.js +15 -12
- package/dist/server/app-page-route-wiring.js.map +1 -1
- package/dist/server/app-page-stream.d.ts +7 -0
- package/dist/server/app-page-stream.js +9 -2
- package/dist/server/app-page-stream.js.map +1 -1
- package/dist/server/app-prerender-endpoints.js +3 -2
- package/dist/server/app-prerender-endpoints.js.map +1 -1
- package/dist/server/app-route-handler-cache.js +2 -1
- package/dist/server/app-route-handler-cache.js.map +1 -1
- package/dist/server/app-route-handler-dispatch.js +6 -5
- package/dist/server/app-route-handler-dispatch.js.map +1 -1
- package/dist/server/app-route-handler-policy.js +13 -13
- package/dist/server/app-route-handler-policy.js.map +1 -1
- package/dist/server/app-route-handler-response.js +2 -1
- package/dist/server/app-route-handler-response.js.map +1 -1
- package/dist/server/app-route-handler-runtime.d.ts +9 -1
- package/dist/server/app-route-handler-runtime.js +11 -1
- package/dist/server/app-route-handler-runtime.js.map +1 -1
- package/dist/server/app-router-entry.js +9 -4
- package/dist/server/app-router-entry.js.map +1 -1
- package/dist/server/app-rsc-cache-busting.d.ts +34 -0
- package/dist/server/app-rsc-cache-busting.js +137 -0
- package/dist/server/app-rsc-cache-busting.js.map +1 -0
- package/dist/server/app-rsc-handler.js +22 -11
- package/dist/server/app-rsc-handler.js.map +1 -1
- package/dist/server/app-rsc-request-normalization.d.ts +4 -2
- package/dist/server/app-rsc-request-normalization.js +10 -6
- package/dist/server/app-rsc-request-normalization.js.map +1 -1
- package/dist/server/app-rsc-response-finalizer.js +1 -1
- package/dist/server/app-rsc-route-matching.js +8 -4
- package/dist/server/app-rsc-route-matching.js.map +1 -1
- package/dist/server/app-segment-config.js +4 -0
- package/dist/server/app-segment-config.js.map +1 -1
- package/dist/server/app-server-action-execution.js +43 -51
- package/dist/server/app-server-action-execution.js.map +1 -1
- package/dist/server/app-ssr-entry.js +21 -20
- package/dist/server/app-ssr-entry.js.map +1 -1
- package/dist/server/artifact-compatibility.d.ts +44 -0
- package/dist/server/artifact-compatibility.js +82 -0
- package/dist/server/artifact-compatibility.js.map +1 -0
- package/dist/server/cache-proof.d.ts +200 -0
- package/dist/server/cache-proof.js +342 -0
- package/dist/server/cache-proof.js.map +1 -0
- package/dist/server/dev-origin-check.js +8 -4
- package/dist/server/dev-origin-check.js.map +1 -1
- package/dist/server/dev-server.js +6 -16
- package/dist/server/dev-server.js.map +1 -1
- package/dist/server/http-error-responses.d.ts +67 -0
- package/dist/server/http-error-responses.js +77 -0
- package/dist/server/http-error-responses.js.map +1 -0
- package/dist/server/image-optimization.js +2 -1
- package/dist/server/image-optimization.js.map +1 -1
- package/dist/server/metadata-route-response.js +6 -5
- package/dist/server/metadata-route-response.js.map +1 -1
- package/dist/server/metadata-routes.d.ts +1 -0
- package/dist/server/metadata-routes.js +6 -0
- package/dist/server/metadata-routes.js.map +1 -1
- package/dist/server/middleware-matcher.js +2 -2
- package/dist/server/middleware-matcher.js.map +1 -1
- package/dist/server/middleware-response-headers.js +21 -0
- package/dist/server/middleware-response-headers.js.map +1 -1
- package/dist/server/middleware-runtime.js +3 -3
- package/dist/server/middleware-runtime.js.map +1 -1
- package/dist/server/navigation-trace.d.ts +33 -0
- package/dist/server/navigation-trace.js +35 -0
- package/dist/server/navigation-trace.js.map +1 -0
- package/dist/server/next-error-digest.d.ts +44 -0
- package/dist/server/next-error-digest.js +40 -0
- package/dist/server/next-error-digest.js.map +1 -0
- package/dist/server/pages-api-route.js +4 -7
- package/dist/server/pages-api-route.js.map +1 -1
- package/dist/server/pages-node-compat.js +4 -16
- package/dist/server/pages-node-compat.js.map +1 -1
- package/dist/server/pages-page-response.d.ts +2 -8
- package/dist/server/pages-page-response.js +44 -14
- package/dist/server/pages-page-response.js.map +1 -1
- package/dist/server/prod-server.d.ts +6 -0
- package/dist/server/prod-server.js +28 -21
- package/dist/server/prod-server.js.map +1 -1
- package/dist/server/request-pipeline.d.ts +42 -1
- package/dist/server/request-pipeline.js +97 -17
- package/dist/server/request-pipeline.js.map +1 -1
- package/dist/shims/cache-runtime.d.ts +2 -2
- package/dist/shims/cache-runtime.js +3 -6
- package/dist/shims/cache-runtime.js.map +1 -1
- package/dist/shims/cache.js +3 -5
- package/dist/shims/cache.js.map +1 -1
- package/dist/shims/fetch-cache.js +2 -3
- package/dist/shims/fetch-cache.js.map +1 -1
- package/dist/shims/head-state.js +2 -3
- package/dist/shims/head-state.js.map +1 -1
- package/dist/shims/headers.js +4 -44
- package/dist/shims/headers.js.map +1 -1
- package/dist/shims/i18n-state.js +2 -3
- package/dist/shims/i18n-state.js.map +1 -1
- package/dist/shims/internal/als-registry.d.ts +15 -0
- package/dist/shims/internal/als-registry.js +55 -0
- package/dist/shims/internal/als-registry.js.map +1 -0
- package/dist/shims/internal/cookie-serialize.d.ts +46 -0
- package/dist/shims/internal/cookie-serialize.js +51 -0
- package/dist/shims/internal/cookie-serialize.js.map +1 -0
- package/dist/shims/link.js +31 -26
- package/dist/shims/link.js.map +1 -1
- package/dist/shims/metadata.d.ts +26 -1
- package/dist/shims/metadata.js +94 -4
- package/dist/shims/metadata.js.map +1 -1
- package/dist/shims/navigation-state.js +2 -3
- package/dist/shims/navigation-state.js.map +1 -1
- package/dist/shims/navigation.d.ts +2 -7
- package/dist/shims/navigation.js +44 -36
- package/dist/shims/navigation.js.map +1 -1
- package/dist/shims/request-context.js +2 -4
- package/dist/shims/request-context.js.map +1 -1
- package/dist/shims/router-state.js +2 -3
- package/dist/shims/router-state.js.map +1 -1
- package/dist/shims/router.js +2 -2
- package/dist/shims/router.js.map +1 -1
- package/dist/shims/server.js +5 -30
- package/dist/shims/server.js.map +1 -1
- package/dist/shims/slot.d.ts +1 -1
- package/dist/shims/slot.js +5 -4
- package/dist/shims/slot.js.map +1 -1
- package/dist/shims/thenable-params.d.ts +5 -2
- package/dist/shims/thenable-params.js +26 -6
- package/dist/shims/thenable-params.js.map +1 -1
- package/dist/shims/unified-request-context.js +2 -14
- package/dist/shims/unified-request-context.js.map +1 -1
- package/dist/utils/base-path.d.ts +7 -1
- package/dist/utils/base-path.js +12 -1
- package/dist/utils/base-path.js.map +1 -1
- package/dist/utils/query.d.ts +8 -1
- package/dist/utils/query.js +12 -1
- package/dist/utils/query.js.map +1 -1
- package/dist/utils/safe-json-file.d.ts +18 -0
- package/dist/utils/safe-json-file.js +25 -0
- package/dist/utils/safe-json-file.js.map +1 -0
- package/dist/utils/text-stream.d.ts +29 -0
- package/dist/utils/text-stream.js +66 -0
- package/dist/utils/text-stream.js.map +1 -0
- package/package.json +5 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-browser-state.js","names":[],"sources":["../../src/server/app-browser-state.ts"],"sourcesContent":["import { mergeElements } from \"vinext/shims/slot\";\nimport { stripBasePath } from \"../utils/base-path.js\";\nimport {\n getMountedSlotIdsHeader,\n readAppElementsMetadata,\n type AppElements,\n type LayoutFlags,\n} from \"./app-elements.js\";\nimport type { ClientNavigationRenderSnapshot } from \"vinext/shims/navigation\";\n\nconst VINEXT_PREVIOUS_NEXT_URL_HISTORY_STATE_KEY = \"__vinext_previousNextUrl\";\n\ntype HistoryStateRecord = {\n [key: string]: unknown;\n};\n\nexport type AppRouterState = {\n elements: AppElements;\n interceptionContext: string | null;\n layoutFlags: LayoutFlags;\n previousNextUrl: string | null;\n renderId: number;\n navigationSnapshot: ClientNavigationRenderSnapshot;\n rootLayoutTreePath: string | null;\n routeId: string;\n};\n\nexport type AppRouterAction = {\n elements: AppElements;\n interceptionContext: string | null;\n layoutFlags: LayoutFlags;\n navigationSnapshot: ClientNavigationRenderSnapshot;\n previousNextUrl: string | null;\n renderId: number;\n rootLayoutTreePath: string | null;\n routeId: string;\n type: \"navigate\" | \"replace\" | \"traverse\";\n};\n\ntype PendingNavigationCommit = {\n action: AppRouterAction;\n interceptionContext: string | null;\n previousNextUrl: string | null;\n rootLayoutTreePath: string | null;\n routeId: string;\n};\n\ntype PendingNavigationCommitDisposition = \"dispatch\" | \"hard-navigate\" | \"skip\";\ntype ClassifiedPendingNavigationCommit = {\n disposition: PendingNavigationCommitDisposition;\n pending: PendingNavigationCommit;\n};\n\nfunction cloneHistoryState(state: unknown): HistoryStateRecord {\n if (!state || typeof state !== \"object\") {\n return {};\n }\n\n const nextState: HistoryStateRecord = {};\n for (const [key, value] of Object.entries(state)) {\n nextState[key] = value;\n }\n return nextState;\n}\n\nexport function createHistoryStateWithPreviousNextUrl(\n state: unknown,\n previousNextUrl: string | null,\n): HistoryStateRecord | null {\n const nextState = cloneHistoryState(state);\n\n if (previousNextUrl === null) {\n delete nextState[VINEXT_PREVIOUS_NEXT_URL_HISTORY_STATE_KEY];\n } else {\n nextState[VINEXT_PREVIOUS_NEXT_URL_HISTORY_STATE_KEY] = previousNextUrl;\n }\n\n return Object.keys(nextState).length > 0 ? nextState : null;\n}\n\nexport function readHistoryStatePreviousNextUrl(state: unknown): string | null {\n const value = cloneHistoryState(state)[VINEXT_PREVIOUS_NEXT_URL_HISTORY_STATE_KEY];\n return typeof value === \"string\" ? value : null;\n}\n\nexport function resolveInterceptionContextFromPreviousNextUrl(\n previousNextUrl: string | null,\n basePath: string = \"\",\n): string | null {\n if (previousNextUrl === null) {\n return null;\n }\n\n const parsedUrl = new URL(previousNextUrl, \"http://localhost\");\n return stripBasePath(parsedUrl.pathname, basePath);\n}\n\ntype ResolveServerActionRequestStateOptions = {\n actionId: string;\n basePath: string;\n elements: AppElements;\n previousNextUrl: string | null;\n};\n\ntype ResolveServerActionRequestStateResult = {\n headers: Headers;\n};\n\n/**\n * Pure: builds the fetch Headers for a server-action POST. Carries the same\n * interception-context and mounted-slots headers the refresh path already\n * sends, so the server-action re-render can rebuild the intercepted tree\n * instead of replacing it with the direct route.\n *\n * Next.js sends `Next-URL: state.previousNextUrl || state.nextUrl` on action\n * POSTs when `hasInterceptionRouteInCurrentTree(state.tree)`. Vinext's\n * X-Vinext-Interception-Context is the equivalent signal for the server-side\n * `findIntercept` lookup.\n */\nexport function resolveServerActionRequestState(\n options: ResolveServerActionRequestStateOptions,\n): ResolveServerActionRequestStateResult {\n const headers = new Headers({\n Accept: \"text/x-component\",\n \"x-rsc-action\": options.actionId,\n });\n\n const interceptionContext = resolveInterceptionContextFromPreviousNextUrl(\n options.previousNextUrl,\n options.basePath,\n );\n if (interceptionContext !== null) {\n headers.set(\"X-Vinext-Interception-Context\", interceptionContext);\n }\n\n const mountedSlotsHeader = getMountedSlotIdsHeader(options.elements);\n if (mountedSlotsHeader !== null) {\n headers.set(\"X-Vinext-Mounted-Slots\", mountedSlotsHeader);\n }\n\n return { headers };\n}\n\nexport function routerReducer(state: AppRouterState, action: AppRouterAction): AppRouterState {\n switch (action.type) {\n case \"traverse\":\n case \"navigate\":\n return {\n elements: mergeElements(state.elements, action.elements, action.type === \"traverse\"),\n interceptionContext: action.interceptionContext,\n layoutFlags: { ...state.layoutFlags, ...action.layoutFlags },\n navigationSnapshot: action.navigationSnapshot,\n previousNextUrl: action.previousNextUrl,\n renderId: action.renderId,\n rootLayoutTreePath: action.rootLayoutTreePath,\n routeId: action.routeId,\n };\n case \"replace\":\n return {\n elements: action.elements,\n interceptionContext: action.interceptionContext,\n layoutFlags: action.layoutFlags,\n navigationSnapshot: action.navigationSnapshot,\n previousNextUrl: action.previousNextUrl,\n renderId: action.renderId,\n rootLayoutTreePath: action.rootLayoutTreePath,\n routeId: action.routeId,\n };\n default: {\n const _exhaustive: never = action.type;\n throw new Error(\"[vinext] Unknown router action: \" + String(_exhaustive));\n }\n }\n}\n\nexport function shouldHardNavigate(\n currentRootLayoutTreePath: string | null,\n nextRootLayoutTreePath: string | null,\n): boolean {\n // `null` means the payload could not identify an enclosing root layout\n // boundary. Treat that as soft-navigation compatible so fallback payloads\n // do not force a hard reload purely because metadata is absent.\n return (\n currentRootLayoutTreePath !== null &&\n nextRootLayoutTreePath !== null &&\n currentRootLayoutTreePath !== nextRootLayoutTreePath\n );\n}\n\nexport function resolvePendingNavigationCommitDisposition(options: {\n activeNavigationId: number;\n currentRootLayoutTreePath: string | null;\n nextRootLayoutTreePath: string | null;\n startedNavigationId: number;\n}): PendingNavigationCommitDisposition {\n if (options.startedNavigationId !== options.activeNavigationId) {\n return \"skip\";\n }\n\n if (shouldHardNavigate(options.currentRootLayoutTreePath, options.nextRootLayoutTreePath)) {\n return \"hard-navigate\";\n }\n\n return \"dispatch\";\n}\n\nexport async function createPendingNavigationCommit(options: {\n currentState: AppRouterState;\n nextElements: Promise<AppElements>;\n navigationSnapshot: ClientNavigationRenderSnapshot;\n previousNextUrl?: string | null;\n renderId: number;\n type: \"navigate\" | \"replace\" | \"traverse\";\n}): Promise<PendingNavigationCommit> {\n const elements = await options.nextElements;\n const metadata = readAppElementsMetadata(elements);\n const previousNextUrl =\n options.previousNextUrl !== undefined\n ? options.previousNextUrl\n : options.currentState.previousNextUrl;\n\n return {\n action: {\n elements,\n interceptionContext: metadata.interceptionContext,\n layoutFlags: metadata.layoutFlags,\n navigationSnapshot: options.navigationSnapshot,\n previousNextUrl,\n renderId: options.renderId,\n rootLayoutTreePath: metadata.rootLayoutTreePath,\n routeId: metadata.routeId,\n type: options.type,\n },\n // Convenience aliases — always equal action.interceptionContext / action.rootLayoutTreePath / action.routeId.\n interceptionContext: metadata.interceptionContext,\n previousNextUrl,\n rootLayoutTreePath: metadata.rootLayoutTreePath,\n routeId: metadata.routeId,\n };\n}\n\nexport async function resolveAndClassifyNavigationCommit(options: {\n activeNavigationId: number;\n currentState: AppRouterState;\n navigationSnapshot: ClientNavigationRenderSnapshot;\n nextElements: Promise<AppElements>;\n previousNextUrl?: string | null;\n renderId: number;\n startedNavigationId: number;\n type: \"navigate\" | \"replace\" | \"traverse\";\n}): Promise<ClassifiedPendingNavigationCommit> {\n const pending = await createPendingNavigationCommit({\n currentState: options.currentState,\n nextElements: options.nextElements,\n navigationSnapshot: options.navigationSnapshot,\n previousNextUrl: options.previousNextUrl,\n renderId: options.renderId,\n type: options.type,\n });\n\n return {\n disposition: resolvePendingNavigationCommitDisposition({\n activeNavigationId: options.activeNavigationId,\n currentRootLayoutTreePath: options.currentState.rootLayoutTreePath,\n nextRootLayoutTreePath: pending.rootLayoutTreePath,\n startedNavigationId: options.startedNavigationId,\n }),\n pending,\n };\n}\n"],"mappings":";;;;AAUA,MAAM,6CAA6C;AA2CnD,SAAS,kBAAkB,OAAoC;AAC7D,KAAI,CAAC,SAAS,OAAO,UAAU,SAC7B,QAAO,EAAE;CAGX,MAAM,YAAgC,EAAE;AACxC,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,MAAM,CAC9C,WAAU,OAAO;AAEnB,QAAO;;AAGT,SAAgB,sCACd,OACA,iBAC2B;CAC3B,MAAM,YAAY,kBAAkB,MAAM;AAE1C,KAAI,oBAAoB,KACtB,QAAO,UAAU;KAEjB,WAAU,8CAA8C;AAG1D,QAAO,OAAO,KAAK,UAAU,CAAC,SAAS,IAAI,YAAY;;AAGzD,SAAgB,gCAAgC,OAA+B;CAC7E,MAAM,QAAQ,kBAAkB,MAAM,CAAC;AACvC,QAAO,OAAO,UAAU,WAAW,QAAQ;;AAG7C,SAAgB,8CACd,iBACA,WAAmB,IACJ;AACf,KAAI,oBAAoB,KACtB,QAAO;AAIT,QAAO,cADW,IAAI,IAAI,iBAAiB,mBAAmB,CAC/B,UAAU,SAAS;;;;;;;;;;;;;AAyBpD,SAAgB,gCACd,SACuC;CACvC,MAAM,UAAU,IAAI,QAAQ;EAC1B,QAAQ;EACR,gBAAgB,QAAQ;EACzB,CAAC;CAEF,MAAM,sBAAsB,8CAC1B,QAAQ,iBACR,QAAQ,SACT;AACD,KAAI,wBAAwB,KAC1B,SAAQ,IAAI,iCAAiC,oBAAoB;CAGnE,MAAM,qBAAqB,wBAAwB,QAAQ,SAAS;AACpE,KAAI,uBAAuB,KACzB,SAAQ,IAAI,0BAA0B,mBAAmB;AAG3D,QAAO,EAAE,SAAS;;AAGpB,SAAgB,cAAc,OAAuB,QAAyC;AAC5F,SAAQ,OAAO,MAAf;EACE,KAAK;EACL,KAAK,WACH,QAAO;GACL,UAAU,cAAc,MAAM,UAAU,OAAO,UAAU,OAAO,SAAS,WAAW;GACpF,qBAAqB,OAAO;GAC5B,aAAa;IAAE,GAAG,MAAM;IAAa,GAAG,OAAO;IAAa;GAC5D,oBAAoB,OAAO;GAC3B,iBAAiB,OAAO;GACxB,UAAU,OAAO;GACjB,oBAAoB,OAAO;GAC3B,SAAS,OAAO;GACjB;EACH,KAAK,UACH,QAAO;GACL,UAAU,OAAO;GACjB,qBAAqB,OAAO;GAC5B,aAAa,OAAO;GACpB,oBAAoB,OAAO;GAC3B,iBAAiB,OAAO;GACxB,UAAU,OAAO;GACjB,oBAAoB,OAAO;GAC3B,SAAS,OAAO;GACjB;EACH,SAAS;GACP,MAAM,cAAqB,OAAO;AAClC,SAAM,IAAI,MAAM,qCAAqC,OAAO,YAAY,CAAC;;;;AAK/E,SAAgB,mBACd,2BACA,wBACS;AAIT,QACE,8BAA8B,QAC9B,2BAA2B,QAC3B,8BAA8B;;AAIlC,SAAgB,0CAA0C,SAKnB;AACrC,KAAI,QAAQ,wBAAwB,QAAQ,mBAC1C,QAAO;AAGT,KAAI,mBAAmB,QAAQ,2BAA2B,QAAQ,uBAAuB,CACvF,QAAO;AAGT,QAAO;;AAGT,eAAsB,8BAA8B,SAOf;CACnC,MAAM,WAAW,MAAM,QAAQ;CAC/B,MAAM,WAAW,wBAAwB,SAAS;CAClD,MAAM,kBACJ,QAAQ,oBAAoB,KAAA,IACxB,QAAQ,kBACR,QAAQ,aAAa;AAE3B,QAAO;EACL,QAAQ;GACN;GACA,qBAAqB,SAAS;GAC9B,aAAa,SAAS;GACtB,oBAAoB,QAAQ;GAC5B;GACA,UAAU,QAAQ;GAClB,oBAAoB,SAAS;GAC7B,SAAS,SAAS;GAClB,MAAM,QAAQ;GACf;EAED,qBAAqB,SAAS;EAC9B;EACA,oBAAoB,SAAS;EAC7B,SAAS,SAAS;EACnB;;AAGH,eAAsB,mCAAmC,SASV;CAC7C,MAAM,UAAU,MAAM,8BAA8B;EAClD,cAAc,QAAQ;EACtB,cAAc,QAAQ;EACtB,oBAAoB,QAAQ;EAC5B,iBAAiB,QAAQ;EACzB,UAAU,QAAQ;EAClB,MAAM,QAAQ;EACf,CAAC;AAEF,QAAO;EACL,aAAa,0CAA0C;GACrD,oBAAoB,QAAQ;GAC5B,2BAA2B,QAAQ,aAAa;GAChD,wBAAwB,QAAQ;GAChC,qBAAqB,QAAQ;GAC9B,CAAC;EACF;EACD"}
|
|
1
|
+
{"version":3,"file":"app-browser-state.js","names":[],"sources":["../../src/server/app-browser-state.ts"],"sourcesContent":["import { stripBasePath } from \"../utils/base-path.js\";\nimport {\n AppElementsWire,\n getMountedSlotIdsHeader,\n type AppElements,\n type LayoutFlags,\n} from \"./app-elements.js\";\nimport { createRscRequestHeaders } from \"./app-rsc-cache-busting.js\";\nimport {\n NavigationTraceReasonCodes,\n createNavigationTrace,\n type NavigationTrace,\n type NavigationTraceReasonCode,\n} from \"./navigation-trace.js\";\nimport type { ClientNavigationRenderSnapshot } from \"vinext/shims/navigation\";\n\nconst VINEXT_PREVIOUS_NEXT_URL_HISTORY_STATE_KEY = \"__vinext_previousNextUrl\";\n\ntype HistoryStateRecord = {\n [key: string]: unknown;\n};\n\nexport type OperationLane = \"navigation\" | \"refresh\" | \"traverse\" | \"server-action\" | \"hmr\";\n\ntype OperationRecordBase = {\n id: number;\n lane: OperationLane;\n startedVisibleCommitVersion: number;\n};\n\nexport type PendingOperationRecord = OperationRecordBase & {\n state: \"pending\";\n};\n\nexport type CommittedOperationRecord = OperationRecordBase & {\n state: \"committed\";\n visibleCommitVersion: number;\n};\n\nexport type OperationRecord = PendingOperationRecord | CommittedOperationRecord;\n\nexport type AppRouterState = {\n activeOperation: OperationRecord | null;\n elements: AppElements;\n interceptionContext: string | null;\n layoutFlags: LayoutFlags;\n previousNextUrl: string | null;\n renderId: number;\n navigationSnapshot: ClientNavigationRenderSnapshot;\n rootLayoutTreePath: string | null;\n routeId: string;\n visibleCommitVersion: number;\n};\n\nexport type AppRouterAction = {\n elements: AppElements;\n interceptionContext: string | null;\n layoutFlags: LayoutFlags;\n navigationSnapshot: ClientNavigationRenderSnapshot;\n operation: PendingOperationRecord;\n previousNextUrl: string | null;\n renderId: number;\n rootLayoutTreePath: string | null;\n routeId: string;\n type: \"navigate\" | \"replace\" | \"traverse\";\n};\n\nexport type PendingNavigationCommit = {\n action: AppRouterAction;\n interceptionContext: string | null;\n previousNextUrl: string | null;\n rootLayoutTreePath: string | null;\n routeId: string;\n};\n\ntype PendingNavigationCommitDisposition = \"dispatch\" | \"hard-navigate\" | \"skip\";\ntype PendingNavigationCommitDispositionDecision = {\n disposition: PendingNavigationCommitDisposition;\n trace: NavigationTrace;\n};\n\nfunction cloneHistoryState(state: unknown): HistoryStateRecord {\n if (!state || typeof state !== \"object\") {\n return {};\n }\n\n const nextState: HistoryStateRecord = {};\n for (const [key, value] of Object.entries(state)) {\n nextState[key] = value;\n }\n return nextState;\n}\n\nexport function createHistoryStateWithPreviousNextUrl(\n state: unknown,\n previousNextUrl: string | null,\n): HistoryStateRecord | null {\n const nextState = cloneHistoryState(state);\n\n if (previousNextUrl === null) {\n delete nextState[VINEXT_PREVIOUS_NEXT_URL_HISTORY_STATE_KEY];\n } else {\n nextState[VINEXT_PREVIOUS_NEXT_URL_HISTORY_STATE_KEY] = previousNextUrl;\n }\n\n return Object.keys(nextState).length > 0 ? nextState : null;\n}\n\nexport function readHistoryStatePreviousNextUrl(state: unknown): string | null {\n const value = cloneHistoryState(state)[VINEXT_PREVIOUS_NEXT_URL_HISTORY_STATE_KEY];\n return typeof value === \"string\" ? value : null;\n}\n\nfunction createOperationRecord(options: {\n id: number;\n lane: OperationLane;\n startedVisibleCommitVersion: number;\n}): PendingOperationRecord {\n return {\n id: options.id,\n lane: options.lane,\n startedVisibleCommitVersion: options.startedVisibleCommitVersion,\n state: \"pending\",\n };\n}\n\nexport function resolveInterceptionContextFromPreviousNextUrl(\n previousNextUrl: string | null,\n basePath: string = \"\",\n): string | null {\n if (previousNextUrl === null) {\n return null;\n }\n\n const parsedUrl = new URL(previousNextUrl, \"http://localhost\");\n return stripBasePath(parsedUrl.pathname, basePath);\n}\n\ntype ResolveServerActionRequestStateOptions = {\n actionId: string;\n basePath: string;\n elements: AppElements;\n previousNextUrl: string | null;\n};\n\ntype ResolveServerActionRequestStateResult = {\n headers: Headers;\n};\n\n/**\n * Pure: builds the fetch Headers for a server-action POST. Carries the same\n * interception-context and mounted-slots headers the refresh path already\n * sends, so the server-action re-render can rebuild the intercepted tree\n * instead of replacing it with the direct route.\n *\n * Next.js sends `Next-URL: state.previousNextUrl || state.nextUrl` on action\n * POSTs when `hasInterceptionRouteInCurrentTree(state.tree)`. Vinext's\n * X-Vinext-Interception-Context is the equivalent signal for the server-side\n * `findIntercept` lookup.\n */\nexport function resolveServerActionRequestState(\n options: ResolveServerActionRequestStateOptions,\n): ResolveServerActionRequestStateResult {\n const headers = createRscRequestHeaders();\n headers.set(\"x-rsc-action\", options.actionId);\n\n const interceptionContext = resolveInterceptionContextFromPreviousNextUrl(\n options.previousNextUrl,\n options.basePath,\n );\n if (interceptionContext !== null) {\n headers.set(\"X-Vinext-Interception-Context\", interceptionContext);\n }\n\n const mountedSlotsHeader = getMountedSlotIdsHeader(options.elements);\n if (mountedSlotsHeader !== null) {\n headers.set(\"X-Vinext-Mounted-Slots\", mountedSlotsHeader);\n }\n\n return { headers };\n}\n\nexport function shouldHardNavigate(\n currentRootLayoutTreePath: string | null,\n nextRootLayoutTreePath: string | null,\n): boolean {\n // `null` means the payload could not identify an enclosing root layout\n // boundary. Treat that as soft-navigation compatible so fallback payloads\n // do not force a hard reload purely because metadata is absent.\n return (\n currentRootLayoutTreePath !== null &&\n nextRootLayoutTreePath !== null &&\n currentRootLayoutTreePath !== nextRootLayoutTreePath\n );\n}\n\nexport function resolvePendingNavigationCommitDisposition(options: {\n activeNavigationId: number;\n currentVisibleCommitVersion: number;\n currentRootLayoutTreePath: string | null;\n nextRootLayoutTreePath: string | null;\n startedNavigationId: number;\n startedVisibleCommitVersion: number;\n}): PendingNavigationCommitDisposition {\n if (options.startedNavigationId !== options.activeNavigationId) {\n return \"skip\";\n }\n\n if (options.startedVisibleCommitVersion !== options.currentVisibleCommitVersion) {\n return \"skip\";\n }\n\n if (shouldHardNavigate(options.currentRootLayoutTreePath, options.nextRootLayoutTreePath)) {\n return \"hard-navigate\";\n }\n\n return \"dispatch\";\n}\n\nexport function resolvePendingNavigationCommitDispositionDecision(options: {\n activeNavigationId: number;\n currentVisibleCommitVersion: number;\n currentRootLayoutTreePath: string | null;\n nextRootLayoutTreePath: string | null;\n startedNavigationId: number;\n startedVisibleCommitVersion: number;\n}): PendingNavigationCommitDispositionDecision {\n const disposition = resolvePendingNavigationCommitDisposition(options);\n const traceFields = {\n activeNavigationId: options.activeNavigationId,\n currentRootLayoutTreePath: options.currentRootLayoutTreePath,\n currentVisibleCommitVersion: options.currentVisibleCommitVersion,\n nextRootLayoutTreePath: options.nextRootLayoutTreePath,\n startedNavigationId: options.startedNavigationId,\n startedVisibleCommitVersion: options.startedVisibleCommitVersion,\n };\n\n return {\n disposition,\n trace: createNavigationTrace(\n getPendingNavigationCommitDispositionTraceCode({\n currentRootLayoutTreePath: options.currentRootLayoutTreePath,\n disposition,\n nextRootLayoutTreePath: options.nextRootLayoutTreePath,\n }),\n traceFields,\n ),\n };\n}\n\nfunction getPendingNavigationCommitDispositionTraceCode(options: {\n currentRootLayoutTreePath: string | null;\n disposition: PendingNavigationCommitDisposition;\n nextRootLayoutTreePath: string | null;\n}): NavigationTraceReasonCode {\n switch (options.disposition) {\n case \"skip\":\n return NavigationTraceReasonCodes.staleOperation;\n case \"hard-navigate\":\n return NavigationTraceReasonCodes.rootBoundaryChanged;\n case \"dispatch\":\n return options.currentRootLayoutTreePath === null || options.nextRootLayoutTreePath === null\n ? NavigationTraceReasonCodes.rootBoundaryUnknown\n : NavigationTraceReasonCodes.commitCurrent;\n default: {\n const _exhaustive: never = options.disposition;\n throw new Error(\"[vinext] Unknown navigation commit disposition: \" + String(_exhaustive));\n }\n }\n}\n\nexport async function createPendingNavigationCommit(options: {\n currentState: AppRouterState;\n nextElements: Promise<AppElements>;\n navigationSnapshot: ClientNavigationRenderSnapshot;\n operationLane: OperationLane;\n previousNextUrl?: string | null;\n renderId: number;\n type: \"navigate\" | \"replace\" | \"traverse\";\n}): Promise<PendingNavigationCommit> {\n const elements = await options.nextElements;\n const metadata = AppElementsWire.readMetadata(elements);\n const previousNextUrl =\n options.previousNextUrl !== undefined\n ? options.previousNextUrl\n : options.currentState.previousNextUrl;\n\n return {\n action: {\n elements,\n interceptionContext: metadata.interceptionContext,\n layoutFlags: metadata.layoutFlags,\n navigationSnapshot: options.navigationSnapshot,\n operation: createOperationRecord({\n id: options.renderId,\n lane: options.operationLane,\n startedVisibleCommitVersion: options.currentState.visibleCommitVersion,\n }),\n previousNextUrl,\n renderId: options.renderId,\n rootLayoutTreePath: metadata.rootLayoutTreePath,\n routeId: metadata.routeId,\n type: options.type,\n },\n // Convenience aliases — always equal action.interceptionContext / action.rootLayoutTreePath / action.routeId.\n interceptionContext: metadata.interceptionContext,\n previousNextUrl,\n rootLayoutTreePath: metadata.rootLayoutTreePath,\n routeId: metadata.routeId,\n };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { ClientNavigationRenderSnapshot } from "../shims/navigation.js";
|
|
2
|
+
import { AppElements } from "./app-elements-wire.js";
|
|
3
|
+
import { NavigationTrace } from "./navigation-trace.js";
|
|
4
|
+
import { AppRouterAction, AppRouterState, OperationLane, PendingNavigationCommit } from "./app-browser-state.js";
|
|
5
|
+
|
|
6
|
+
//#region src/server/app-browser-visible-commit.d.ts
|
|
7
|
+
type VisibleCommitDecision = {
|
|
8
|
+
disposition: "commit";
|
|
9
|
+
trace: NavigationTrace;
|
|
10
|
+
};
|
|
11
|
+
type HardNavigateCommitDecision = {
|
|
12
|
+
disposition: "hard-navigate";
|
|
13
|
+
trace: NavigationTrace;
|
|
14
|
+
};
|
|
15
|
+
type NoCommitDecision = {
|
|
16
|
+
disposition: "no-commit";
|
|
17
|
+
trace: NavigationTrace;
|
|
18
|
+
};
|
|
19
|
+
type CommitDecision = VisibleCommitDecision | HardNavigateCommitDecision | NoCommitDecision;
|
|
20
|
+
declare const approvedVisibleCommitBrand: unique symbol;
|
|
21
|
+
type ApprovedVisibleCommit = {
|
|
22
|
+
readonly [approvedVisibleCommitBrand]: true;
|
|
23
|
+
readonly action: AppRouterAction;
|
|
24
|
+
readonly decision: VisibleCommitDecision;
|
|
25
|
+
readonly interceptionContext: string | null;
|
|
26
|
+
readonly previousNextUrl: string | null;
|
|
27
|
+
readonly rootLayoutTreePath: string | null;
|
|
28
|
+
readonly routeId: string;
|
|
29
|
+
};
|
|
30
|
+
type VisibleCommitApproval = {
|
|
31
|
+
approvedCommit: ApprovedVisibleCommit;
|
|
32
|
+
decision: VisibleCommitDecision;
|
|
33
|
+
};
|
|
34
|
+
type NonVisibleCommitApproval = {
|
|
35
|
+
approvedCommit: null;
|
|
36
|
+
decision: HardNavigateCommitDecision | NoCommitDecision;
|
|
37
|
+
};
|
|
38
|
+
type CommitApproval = VisibleCommitApproval | NonVisibleCommitApproval;
|
|
39
|
+
type ClassifiedPendingNavigationCommit = {
|
|
40
|
+
approvedCommit: ApprovedVisibleCommit | null;
|
|
41
|
+
decision: CommitDecision;
|
|
42
|
+
pending: PendingNavigationCommit;
|
|
43
|
+
trace: NavigationTrace;
|
|
44
|
+
};
|
|
45
|
+
declare function applyApprovedVisibleCommit(state: AppRouterState, commit: ApprovedVisibleCommit): AppRouterState;
|
|
46
|
+
declare function approveHmrVisibleCommit(pending: PendingNavigationCommit): ApprovedVisibleCommit;
|
|
47
|
+
declare function approvePendingNavigationCommit(options: {
|
|
48
|
+
activeNavigationId: number;
|
|
49
|
+
currentState: AppRouterState;
|
|
50
|
+
pending: PendingNavigationCommit;
|
|
51
|
+
startedNavigationId: number;
|
|
52
|
+
}): CommitApproval;
|
|
53
|
+
declare function resolveAndClassifyNavigationCommit(options: {
|
|
54
|
+
activeNavigationId: number;
|
|
55
|
+
currentState: AppRouterState;
|
|
56
|
+
getActiveNavigationId?: () => number;
|
|
57
|
+
getCurrentStateForApproval?: () => AppRouterState;
|
|
58
|
+
navigationSnapshot: ClientNavigationRenderSnapshot;
|
|
59
|
+
nextElements: Promise<AppElements>;
|
|
60
|
+
operationLane: OperationLane;
|
|
61
|
+
previousNextUrl?: string | null;
|
|
62
|
+
renderId: number;
|
|
63
|
+
startedNavigationId: number;
|
|
64
|
+
type: "navigate" | "replace" | "traverse";
|
|
65
|
+
}): Promise<ClassifiedPendingNavigationCommit>;
|
|
66
|
+
//#endregion
|
|
67
|
+
export { ApprovedVisibleCommit, applyApprovedVisibleCommit, approveHmrVisibleCommit, approvePendingNavigationCommit, resolveAndClassifyNavigationCommit };
|
|
68
|
+
//# sourceMappingURL=app-browser-visible-commit.d.ts.map
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { mergeElements } from "../shims/slot.js";
|
|
2
|
+
import { NavigationTraceReasonCodes, NavigationTraceTransactionCodes, createNavigationTrace, prependNavigationTraceEntry } from "./navigation-trace.js";
|
|
3
|
+
import { createPendingNavigationCommit, resolvePendingNavigationCommitDispositionDecision } from "./app-browser-state.js";
|
|
4
|
+
//#region src/server/app-browser-visible-commit.ts
|
|
5
|
+
const approvedVisibleCommitBrand = Symbol("ApprovedVisibleCommit");
|
|
6
|
+
function applyApprovedVisibleCommit(state, commit) {
|
|
7
|
+
assertApprovedVisibleCommit(commit);
|
|
8
|
+
return reduceApprovedVisibleCommitState(state, commit.action);
|
|
9
|
+
}
|
|
10
|
+
function assertApprovedVisibleCommit(commit) {
|
|
11
|
+
if (commit[approvedVisibleCommitBrand] !== true) throw new Error("[vinext] Visible router state mutation requires ApprovedVisibleCommit");
|
|
12
|
+
}
|
|
13
|
+
function commitOperationRecord(operation, visibleCommitVersion) {
|
|
14
|
+
return {
|
|
15
|
+
id: operation.id,
|
|
16
|
+
lane: operation.lane,
|
|
17
|
+
startedVisibleCommitVersion: operation.startedVisibleCommitVersion,
|
|
18
|
+
state: "committed",
|
|
19
|
+
visibleCommitVersion
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function commitVisibleRouterState(state, nextState, operation) {
|
|
23
|
+
const visibleCommitVersion = state.visibleCommitVersion + 1;
|
|
24
|
+
return {
|
|
25
|
+
...nextState,
|
|
26
|
+
activeOperation: commitOperationRecord(operation, visibleCommitVersion),
|
|
27
|
+
visibleCommitVersion
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function reduceApprovedVisibleCommitState(state, action) {
|
|
31
|
+
switch (action.type) {
|
|
32
|
+
case "traverse":
|
|
33
|
+
case "navigate": return commitVisibleRouterState(state, {
|
|
34
|
+
elements: mergeElements(state.elements, action.elements, action.type === "traverse"),
|
|
35
|
+
interceptionContext: action.interceptionContext,
|
|
36
|
+
layoutFlags: {
|
|
37
|
+
...state.layoutFlags,
|
|
38
|
+
...action.layoutFlags
|
|
39
|
+
},
|
|
40
|
+
navigationSnapshot: action.navigationSnapshot,
|
|
41
|
+
previousNextUrl: action.previousNextUrl,
|
|
42
|
+
renderId: action.renderId,
|
|
43
|
+
rootLayoutTreePath: action.rootLayoutTreePath,
|
|
44
|
+
routeId: action.routeId
|
|
45
|
+
}, action.operation);
|
|
46
|
+
case "replace": return commitVisibleRouterState(state, {
|
|
47
|
+
elements: action.elements,
|
|
48
|
+
interceptionContext: action.interceptionContext,
|
|
49
|
+
layoutFlags: action.layoutFlags,
|
|
50
|
+
navigationSnapshot: action.navigationSnapshot,
|
|
51
|
+
previousNextUrl: action.previousNextUrl,
|
|
52
|
+
renderId: action.renderId,
|
|
53
|
+
rootLayoutTreePath: action.rootLayoutTreePath,
|
|
54
|
+
routeId: action.routeId
|
|
55
|
+
}, action.operation);
|
|
56
|
+
default: {
|
|
57
|
+
const _exhaustive = action.type;
|
|
58
|
+
throw new Error("[vinext] Unknown router action: " + String(_exhaustive));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function resolvePendingNavigationCommitDecision(options) {
|
|
63
|
+
const { disposition, trace } = resolvePendingNavigationCommitDispositionDecision(options);
|
|
64
|
+
switch (disposition) {
|
|
65
|
+
case "skip": return {
|
|
66
|
+
disposition: "no-commit",
|
|
67
|
+
trace
|
|
68
|
+
};
|
|
69
|
+
case "hard-navigate": return {
|
|
70
|
+
disposition: "hard-navigate",
|
|
71
|
+
trace
|
|
72
|
+
};
|
|
73
|
+
case "dispatch": return createVisibleCommitDecision(trace);
|
|
74
|
+
default: throw new Error("[vinext] Unknown navigation commit disposition: " + String(disposition));
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function createVisibleCommitDecision(trace = createNavigationTrace(NavigationTraceReasonCodes.commitCurrent)) {
|
|
78
|
+
return {
|
|
79
|
+
disposition: "commit",
|
|
80
|
+
trace
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
function createApprovedVisibleCommit(options) {
|
|
84
|
+
return {
|
|
85
|
+
[approvedVisibleCommitBrand]: true,
|
|
86
|
+
action: options.pending.action,
|
|
87
|
+
decision: options.decision,
|
|
88
|
+
interceptionContext: options.pending.interceptionContext,
|
|
89
|
+
previousNextUrl: options.pending.previousNextUrl,
|
|
90
|
+
rootLayoutTreePath: options.pending.rootLayoutTreePath,
|
|
91
|
+
routeId: options.pending.routeId
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
function createCommitTransactionFields(pending) {
|
|
95
|
+
return {
|
|
96
|
+
operationLane: pending.action.operation.lane,
|
|
97
|
+
pendingOperationId: pending.action.operation.id,
|
|
98
|
+
startedVisibleCommitVersion: pending.action.operation.startedVisibleCommitVersion
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
function prependCommitTransactionTrace(trace, code, pending) {
|
|
102
|
+
return prependNavigationTraceEntry(trace, code, createCommitTransactionFields(pending));
|
|
103
|
+
}
|
|
104
|
+
function addCommitTransactionTrace(decision, pending) {
|
|
105
|
+
switch (decision.disposition) {
|
|
106
|
+
case "commit": return {
|
|
107
|
+
...decision,
|
|
108
|
+
trace: prependCommitTransactionTrace(decision.trace, NavigationTraceTransactionCodes.visibleCommit, pending)
|
|
109
|
+
};
|
|
110
|
+
case "hard-navigate": return {
|
|
111
|
+
...decision,
|
|
112
|
+
trace: prependCommitTransactionTrace(decision.trace, NavigationTraceTransactionCodes.hardNavigate, pending)
|
|
113
|
+
};
|
|
114
|
+
case "no-commit": return {
|
|
115
|
+
...decision,
|
|
116
|
+
trace: prependCommitTransactionTrace(decision.trace, NavigationTraceTransactionCodes.noCommit, pending)
|
|
117
|
+
};
|
|
118
|
+
default: throw new Error("[vinext] Unknown commit decision: " + String(decision));
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
function approveHmrVisibleCommit(pending) {
|
|
122
|
+
if (pending.action.operation.lane !== "hmr") throw new Error("[vinext] HMR visible commit approval requires an HMR pending operation");
|
|
123
|
+
const decision = addCommitTransactionTrace(createVisibleCommitDecision(), pending);
|
|
124
|
+
if (decision.disposition !== "commit") throw new Error("[vinext] HMR visible commit approval did not produce a commit decision");
|
|
125
|
+
return createApprovedVisibleCommit({
|
|
126
|
+
decision,
|
|
127
|
+
pending
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
function approvePendingNavigationCommit(options) {
|
|
131
|
+
const decision = addCommitTransactionTrace(resolvePendingNavigationCommitDecision({
|
|
132
|
+
activeNavigationId: options.activeNavigationId,
|
|
133
|
+
currentVisibleCommitVersion: options.currentState.visibleCommitVersion,
|
|
134
|
+
currentRootLayoutTreePath: options.currentState.rootLayoutTreePath,
|
|
135
|
+
nextRootLayoutTreePath: options.pending.rootLayoutTreePath,
|
|
136
|
+
startedNavigationId: options.startedNavigationId,
|
|
137
|
+
startedVisibleCommitVersion: options.pending.action.operation.startedVisibleCommitVersion
|
|
138
|
+
}), options.pending);
|
|
139
|
+
switch (decision.disposition) {
|
|
140
|
+
case "commit": return {
|
|
141
|
+
approvedCommit: createApprovedVisibleCommit({
|
|
142
|
+
decision,
|
|
143
|
+
pending: options.pending
|
|
144
|
+
}),
|
|
145
|
+
decision
|
|
146
|
+
};
|
|
147
|
+
case "hard-navigate":
|
|
148
|
+
case "no-commit": return {
|
|
149
|
+
approvedCommit: null,
|
|
150
|
+
decision
|
|
151
|
+
};
|
|
152
|
+
default: throw new Error("[vinext] Unknown commit decision: " + String(decision));
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
async function resolveAndClassifyNavigationCommit(options) {
|
|
156
|
+
const pending = await createPendingNavigationCommit({
|
|
157
|
+
currentState: options.currentState,
|
|
158
|
+
nextElements: options.nextElements,
|
|
159
|
+
navigationSnapshot: options.navigationSnapshot,
|
|
160
|
+
operationLane: options.operationLane,
|
|
161
|
+
previousNextUrl: options.previousNextUrl,
|
|
162
|
+
renderId: options.renderId,
|
|
163
|
+
type: options.type
|
|
164
|
+
});
|
|
165
|
+
const approvalState = options.getCurrentStateForApproval?.() ?? options.currentState;
|
|
166
|
+
const approval = approvePendingNavigationCommit({
|
|
167
|
+
activeNavigationId: options.getActiveNavigationId?.() ?? options.activeNavigationId,
|
|
168
|
+
currentState: approvalState,
|
|
169
|
+
pending,
|
|
170
|
+
startedNavigationId: options.startedNavigationId
|
|
171
|
+
});
|
|
172
|
+
return {
|
|
173
|
+
approvedCommit: approval.approvedCommit,
|
|
174
|
+
decision: approval.decision,
|
|
175
|
+
pending,
|
|
176
|
+
trace: approval.decision.trace
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
//#endregion
|
|
180
|
+
export { applyApprovedVisibleCommit, approveHmrVisibleCommit, approvePendingNavigationCommit, resolveAndClassifyNavigationCommit };
|
|
181
|
+
|
|
182
|
+
//# sourceMappingURL=app-browser-visible-commit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-browser-visible-commit.js","names":[],"sources":["../../src/server/app-browser-visible-commit.ts"],"sourcesContent":["import type { ClientNavigationRenderSnapshot } from \"vinext/shims/navigation\";\nimport { mergeElements } from \"vinext/shims/slot\";\nimport type { AppElements } from \"./app-elements.js\";\nimport {\n createPendingNavigationCommit,\n resolvePendingNavigationCommitDispositionDecision,\n type AppRouterAction,\n type AppRouterState,\n type CommittedOperationRecord,\n type OperationLane,\n type PendingNavigationCommit,\n type PendingOperationRecord,\n} from \"./app-browser-state.js\";\nimport {\n NavigationTraceReasonCodes,\n NavigationTraceTransactionCodes,\n createNavigationTrace,\n prependNavigationTraceEntry,\n type NavigationTrace,\n type NavigationTraceFields,\n type NavigationTraceTransactionCode,\n} from \"./navigation-trace.js\";\n\ntype VisibleCommitDecision = {\n disposition: \"commit\";\n trace: NavigationTrace;\n};\ntype HardNavigateCommitDecision = {\n disposition: \"hard-navigate\";\n trace: NavigationTrace;\n};\ntype NoCommitDecision = {\n disposition: \"no-commit\";\n trace: NavigationTrace;\n};\ntype CommitDecision = VisibleCommitDecision | HardNavigateCommitDecision | NoCommitDecision;\nconst approvedVisibleCommitBrand: unique symbol = Symbol(\"ApprovedVisibleCommit\");\nexport type ApprovedVisibleCommit = {\n readonly [approvedVisibleCommitBrand]: true;\n readonly action: AppRouterAction;\n readonly decision: VisibleCommitDecision;\n readonly interceptionContext: string | null;\n readonly previousNextUrl: string | null;\n readonly rootLayoutTreePath: string | null;\n readonly routeId: string;\n};\ntype VisibleCommitApproval = {\n approvedCommit: ApprovedVisibleCommit;\n decision: VisibleCommitDecision;\n};\ntype NonVisibleCommitApproval = {\n approvedCommit: null;\n decision: HardNavigateCommitDecision | NoCommitDecision;\n};\ntype CommitApproval = VisibleCommitApproval | NonVisibleCommitApproval;\ntype ClassifiedPendingNavigationCommit = {\n approvedCommit: ApprovedVisibleCommit | null;\n decision: CommitDecision;\n pending: PendingNavigationCommit;\n trace: NavigationTrace;\n};\n\nexport function applyApprovedVisibleCommit(\n state: AppRouterState,\n commit: ApprovedVisibleCommit,\n): AppRouterState {\n assertApprovedVisibleCommit(commit);\n return reduceApprovedVisibleCommitState(state, commit.action);\n}\n\nfunction assertApprovedVisibleCommit(commit: ApprovedVisibleCommit): void {\n if (commit[approvedVisibleCommitBrand] !== true) {\n throw new Error(\"[vinext] Visible router state mutation requires ApprovedVisibleCommit\");\n }\n}\n\nfunction commitOperationRecord(\n operation: PendingOperationRecord,\n visibleCommitVersion: number,\n): CommittedOperationRecord {\n return {\n id: operation.id,\n lane: operation.lane,\n startedVisibleCommitVersion: operation.startedVisibleCommitVersion,\n state: \"committed\",\n visibleCommitVersion,\n };\n}\n\nfunction commitVisibleRouterState(\n state: AppRouterState,\n nextState: Omit<AppRouterState, \"activeOperation\" | \"visibleCommitVersion\">,\n operation: PendingOperationRecord,\n): AppRouterState {\n // Single owner for visibleCommitVersion: only an ApprovedVisibleCommit may\n // advance it, and every accepted visible mutation advances it exactly once.\n const visibleCommitVersion = state.visibleCommitVersion + 1;\n return {\n ...nextState,\n activeOperation: commitOperationRecord(operation, visibleCommitVersion),\n visibleCommitVersion,\n };\n}\n\nfunction reduceApprovedVisibleCommitState(\n state: AppRouterState,\n action: AppRouterAction,\n): AppRouterState {\n switch (action.type) {\n case \"traverse\":\n case \"navigate\":\n return commitVisibleRouterState(\n state,\n {\n elements: mergeElements(state.elements, action.elements, action.type === \"traverse\"),\n interceptionContext: action.interceptionContext,\n layoutFlags: { ...state.layoutFlags, ...action.layoutFlags },\n navigationSnapshot: action.navigationSnapshot,\n previousNextUrl: action.previousNextUrl,\n renderId: action.renderId,\n rootLayoutTreePath: action.rootLayoutTreePath,\n routeId: action.routeId,\n },\n action.operation,\n );\n case \"replace\":\n return commitVisibleRouterState(\n state,\n {\n elements: action.elements,\n interceptionContext: action.interceptionContext,\n layoutFlags: action.layoutFlags,\n navigationSnapshot: action.navigationSnapshot,\n previousNextUrl: action.previousNextUrl,\n renderId: action.renderId,\n rootLayoutTreePath: action.rootLayoutTreePath,\n routeId: action.routeId,\n },\n action.operation,\n );\n default: {\n const _exhaustive: never = action.type;\n throw new Error(\"[vinext] Unknown router action: \" + String(_exhaustive));\n }\n }\n}\n\nfunction resolvePendingNavigationCommitDecision(options: {\n activeNavigationId: number;\n currentVisibleCommitVersion: number;\n currentRootLayoutTreePath: string | null;\n nextRootLayoutTreePath: string | null;\n startedNavigationId: number;\n startedVisibleCommitVersion: number;\n}): CommitDecision {\n const { disposition, trace } = resolvePendingNavigationCommitDispositionDecision(options);\n\n switch (disposition) {\n case \"skip\":\n return { disposition: \"no-commit\", trace };\n case \"hard-navigate\":\n return { disposition: \"hard-navigate\", trace };\n case \"dispatch\":\n return createVisibleCommitDecision(trace);\n default: {\n const _exhaustive: never = disposition;\n throw new Error(\"[vinext] Unknown navigation commit disposition: \" + String(_exhaustive));\n }\n }\n}\n\nfunction createVisibleCommitDecision(\n trace: NavigationTrace = createNavigationTrace(NavigationTraceReasonCodes.commitCurrent),\n): VisibleCommitDecision {\n return { disposition: \"commit\", trace };\n}\n\nfunction createApprovedVisibleCommit(options: {\n decision: VisibleCommitDecision;\n pending: PendingNavigationCommit;\n}): ApprovedVisibleCommit {\n return {\n [approvedVisibleCommitBrand]: true,\n action: options.pending.action,\n decision: options.decision,\n interceptionContext: options.pending.interceptionContext,\n previousNextUrl: options.pending.previousNextUrl,\n rootLayoutTreePath: options.pending.rootLayoutTreePath,\n routeId: options.pending.routeId,\n };\n}\n\nfunction createCommitTransactionFields(pending: PendingNavigationCommit): NavigationTraceFields {\n return {\n operationLane: pending.action.operation.lane,\n pendingOperationId: pending.action.operation.id,\n startedVisibleCommitVersion: pending.action.operation.startedVisibleCommitVersion,\n };\n}\n\nfunction prependCommitTransactionTrace(\n trace: NavigationTrace,\n code: NavigationTraceTransactionCode,\n pending: PendingNavigationCommit,\n): NavigationTrace {\n return prependNavigationTraceEntry(trace, code, createCommitTransactionFields(pending));\n}\n\nfunction addCommitTransactionTrace(\n decision: CommitDecision,\n pending: PendingNavigationCommit,\n): CommitDecision {\n switch (decision.disposition) {\n case \"commit\":\n return {\n ...decision,\n trace: prependCommitTransactionTrace(\n decision.trace,\n NavigationTraceTransactionCodes.visibleCommit,\n pending,\n ),\n };\n case \"hard-navigate\":\n return {\n ...decision,\n trace: prependCommitTransactionTrace(\n decision.trace,\n NavigationTraceTransactionCodes.hardNavigate,\n pending,\n ),\n };\n case \"no-commit\":\n return {\n ...decision,\n trace: prependCommitTransactionTrace(\n decision.trace,\n NavigationTraceTransactionCodes.noCommit,\n pending,\n ),\n };\n default: {\n const _exhaustive: never = decision;\n throw new Error(\"[vinext] Unknown commit decision: \" + String(_exhaustive));\n }\n }\n}\n\nexport function approveHmrVisibleCommit(pending: PendingNavigationCommit): ApprovedVisibleCommit {\n if (pending.action.operation.lane !== \"hmr\") {\n throw new Error(\"[vinext] HMR visible commit approval requires an HMR pending operation\");\n }\n\n const decision = addCommitTransactionTrace(createVisibleCommitDecision(), pending);\n // This guard is a type narrowing assertion: createVisibleCommitDecision()\n // structurally produces a commit decision, and addCommitTransactionTrace()\n // must preserve that disposition while adding operator trace context.\n if (decision.disposition !== \"commit\") {\n throw new Error(\"[vinext] HMR visible commit approval did not produce a commit decision\");\n }\n\n return createApprovedVisibleCommit({\n decision,\n pending,\n });\n}\n\nexport function approvePendingNavigationCommit(options: {\n activeNavigationId: number;\n currentState: AppRouterState;\n pending: PendingNavigationCommit;\n startedNavigationId: number;\n}): CommitApproval {\n const decision = addCommitTransactionTrace(\n resolvePendingNavigationCommitDecision({\n activeNavigationId: options.activeNavigationId,\n currentVisibleCommitVersion: options.currentState.visibleCommitVersion,\n currentRootLayoutTreePath: options.currentState.rootLayoutTreePath,\n nextRootLayoutTreePath: options.pending.rootLayoutTreePath,\n startedNavigationId: options.startedNavigationId,\n startedVisibleCommitVersion: options.pending.action.operation.startedVisibleCommitVersion,\n }),\n options.pending,\n );\n\n switch (decision.disposition) {\n case \"commit\":\n return {\n approvedCommit: createApprovedVisibleCommit({\n decision,\n pending: options.pending,\n }),\n decision,\n };\n case \"hard-navigate\":\n case \"no-commit\":\n return {\n approvedCommit: null,\n decision,\n };\n default: {\n const _exhaustive: never = decision;\n throw new Error(\"[vinext] Unknown commit decision: \" + String(_exhaustive));\n }\n }\n}\n\nexport async function resolveAndClassifyNavigationCommit(options: {\n activeNavigationId: number;\n currentState: AppRouterState;\n // When provided, these getters are called after awaiting nextElements so\n // approval uses the latest lifecycle authority instead of the call snapshot.\n getActiveNavigationId?: () => number;\n getCurrentStateForApproval?: () => AppRouterState;\n navigationSnapshot: ClientNavigationRenderSnapshot;\n nextElements: Promise<AppElements>;\n operationLane: OperationLane;\n previousNextUrl?: string | null;\n renderId: number;\n startedNavigationId: number;\n type: \"navigate\" | \"replace\" | \"traverse\";\n}): Promise<ClassifiedPendingNavigationCommit> {\n const pending = await createPendingNavigationCommit({\n currentState: options.currentState,\n nextElements: options.nextElements,\n navigationSnapshot: options.navigationSnapshot,\n operationLane: options.operationLane,\n previousNextUrl: options.previousNextUrl,\n renderId: options.renderId,\n type: options.type,\n });\n\n const approvalState = options.getCurrentStateForApproval?.() ?? options.currentState;\n const approval = approvePendingNavigationCommit({\n activeNavigationId: options.getActiveNavigationId?.() ?? options.activeNavigationId,\n currentState: approvalState,\n pending,\n startedNavigationId: options.startedNavigationId,\n });\n\n return {\n approvedCommit: approval.approvedCommit,\n decision: approval.decision,\n pending,\n trace: approval.decision.trace,\n };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
//#region src/server/app-client-reference-preloader.d.ts
|
|
2
|
+
type ClientReferenceRequire = (id: string) => Promise<unknown>;
|
|
3
|
+
type ClientReferenceMap = Readonly<Record<string, unknown>>;
|
|
4
|
+
type ClientReferencePreloaderOptions = {
|
|
5
|
+
getReferences: () => ClientReferenceMap | undefined;
|
|
6
|
+
getClientRequire: () => ClientReferenceRequire | undefined;
|
|
7
|
+
onPreloadError?: (id: string, error: unknown) => void;
|
|
8
|
+
};
|
|
9
|
+
type ClientReferencePreloader = {
|
|
10
|
+
preload: (referenceIds?: Iterable<string>) => Promise<void>;
|
|
11
|
+
};
|
|
12
|
+
declare function createClientReferencePreloader(options: ClientReferencePreloaderOptions): ClientReferencePreloader;
|
|
13
|
+
//#endregion
|
|
14
|
+
export { createClientReferencePreloader };
|
|
15
|
+
//# sourceMappingURL=app-client-reference-preloader.d.ts.map
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
//#region src/server/app-client-reference-preloader.ts
|
|
2
|
+
const resolvedPreload = Promise.resolve();
|
|
3
|
+
function createClientReferencePreloader(options) {
|
|
4
|
+
let allReferencesPreloaded = false;
|
|
5
|
+
let allReferencesPreloadPromise = null;
|
|
6
|
+
const preloadedReferences = /* @__PURE__ */ new Set();
|
|
7
|
+
const referencePreloadPromises = /* @__PURE__ */ new Map();
|
|
8
|
+
function preloadReference(id, clientRequire) {
|
|
9
|
+
if (preloadedReferences.has(id)) return resolvedPreload;
|
|
10
|
+
const existing = referencePreloadPromises.get(id);
|
|
11
|
+
if (existing) return existing;
|
|
12
|
+
const preloadPromise = clientRequire(id).catch((error) => {
|
|
13
|
+
options.onPreloadError?.(id, error);
|
|
14
|
+
}).then(() => {
|
|
15
|
+
preloadedReferences.add(id);
|
|
16
|
+
}).finally(() => {
|
|
17
|
+
referencePreloadPromises.delete(id);
|
|
18
|
+
});
|
|
19
|
+
referencePreloadPromises.set(id, preloadPromise);
|
|
20
|
+
return preloadPromise;
|
|
21
|
+
}
|
|
22
|
+
function preloadReferenceSet(referenceIds, refs, clientRequire) {
|
|
23
|
+
const pending = [];
|
|
24
|
+
for (const id of referenceIds) if (Object.hasOwn(refs, id)) pending.push(preloadReference(id, clientRequire));
|
|
25
|
+
if (pending.length === 0) return resolvedPreload;
|
|
26
|
+
return Promise.all(pending).then(() => {});
|
|
27
|
+
}
|
|
28
|
+
return { preload(referenceIds) {
|
|
29
|
+
const refs = options.getReferences();
|
|
30
|
+
const clientRequire = options.getClientRequire();
|
|
31
|
+
if (!refs || !clientRequire) return resolvedPreload;
|
|
32
|
+
if (referenceIds) return preloadReferenceSet(referenceIds, refs, clientRequire);
|
|
33
|
+
if (allReferencesPreloaded) return resolvedPreload;
|
|
34
|
+
if (allReferencesPreloadPromise) return allReferencesPreloadPromise;
|
|
35
|
+
allReferencesPreloadPromise = preloadReferenceSet(Object.keys(refs), refs, clientRequire).then(() => {
|
|
36
|
+
allReferencesPreloaded = true;
|
|
37
|
+
}).finally(() => {
|
|
38
|
+
allReferencesPreloadPromise = null;
|
|
39
|
+
});
|
|
40
|
+
return allReferencesPreloadPromise;
|
|
41
|
+
} };
|
|
42
|
+
}
|
|
43
|
+
//#endregion
|
|
44
|
+
export { createClientReferencePreloader };
|
|
45
|
+
|
|
46
|
+
//# sourceMappingURL=app-client-reference-preloader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-client-reference-preloader.js","names":[],"sources":["../../src/server/app-client-reference-preloader.ts"],"sourcesContent":["type ClientReferenceRequire = (id: string) => Promise<unknown>;\n\ntype ClientReferenceMap = Readonly<Record<string, unknown>>;\n\ntype ClientReferencePreloaderOptions = {\n getReferences: () => ClientReferenceMap | undefined;\n getClientRequire: () => ClientReferenceRequire | undefined;\n onPreloadError?: (id: string, error: unknown) => void;\n};\n\ntype ClientReferencePreloader = {\n preload: (referenceIds?: Iterable<string>) => Promise<void>;\n};\n\nconst resolvedPreload = Promise.resolve();\n\nexport function createClientReferencePreloader(\n options: ClientReferencePreloaderOptions,\n): ClientReferencePreloader {\n let allReferencesPreloaded = false;\n let allReferencesPreloadPromise: Promise<void> | null = null;\n const preloadedReferences = new Set<string>();\n const referencePreloadPromises = new Map<string, Promise<void>>();\n\n function preloadReference(id: string, clientRequire: ClientReferenceRequire): Promise<void> {\n if (preloadedReferences.has(id)) {\n return resolvedPreload;\n }\n\n const existing = referencePreloadPromises.get(id);\n if (existing) {\n return existing;\n }\n\n const preloadPromise = clientRequire(id)\n .catch((error) => {\n options.onPreloadError?.(id, error);\n })\n .then(() => {\n preloadedReferences.add(id);\n })\n .finally(() => {\n referencePreloadPromises.delete(id);\n });\n\n referencePreloadPromises.set(id, preloadPromise);\n return preloadPromise;\n }\n\n function preloadReferenceSet(\n referenceIds: Iterable<string>,\n refs: ClientReferenceMap,\n clientRequire: ClientReferenceRequire,\n ): Promise<void> {\n const pending: Promise<void>[] = [];\n\n for (const id of referenceIds) {\n if (Object.hasOwn(refs, id)) {\n pending.push(preloadReference(id, clientRequire));\n }\n }\n\n if (pending.length === 0) {\n return resolvedPreload;\n }\n\n return Promise.all(pending).then(() => {});\n }\n\n return {\n preload(referenceIds) {\n const refs = options.getReferences();\n const clientRequire = options.getClientRequire();\n if (!refs || !clientRequire) {\n return resolvedPreload;\n }\n\n if (referenceIds) {\n return preloadReferenceSet(referenceIds, refs, clientRequire);\n }\n\n if (allReferencesPreloaded) {\n return resolvedPreload;\n }\n if (allReferencesPreloadPromise) {\n return allReferencesPreloadPromise;\n }\n\n allReferencesPreloadPromise = preloadReferenceSet(Object.keys(refs), refs, clientRequire)\n .then(() => {\n allReferencesPreloaded = true;\n })\n .finally(() => {\n allReferencesPreloadPromise = null;\n });\n\n return allReferencesPreloadPromise;\n },\n };\n}\n"],"mappings":";AAcA,MAAM,kBAAkB,QAAQ,SAAS;AAEzC,SAAgB,+BACd,SAC0B;CAC1B,IAAI,yBAAyB;CAC7B,IAAI,8BAAoD;CACxD,MAAM,sCAAsB,IAAI,KAAa;CAC7C,MAAM,2CAA2B,IAAI,KAA4B;CAEjE,SAAS,iBAAiB,IAAY,eAAsD;AAC1F,MAAI,oBAAoB,IAAI,GAAG,CAC7B,QAAO;EAGT,MAAM,WAAW,yBAAyB,IAAI,GAAG;AACjD,MAAI,SACF,QAAO;EAGT,MAAM,iBAAiB,cAAc,GAAG,CACrC,OAAO,UAAU;AAChB,WAAQ,iBAAiB,IAAI,MAAM;IACnC,CACD,WAAW;AACV,uBAAoB,IAAI,GAAG;IAC3B,CACD,cAAc;AACb,4BAAyB,OAAO,GAAG;IACnC;AAEJ,2BAAyB,IAAI,IAAI,eAAe;AAChD,SAAO;;CAGT,SAAS,oBACP,cACA,MACA,eACe;EACf,MAAM,UAA2B,EAAE;AAEnC,OAAK,MAAM,MAAM,aACf,KAAI,OAAO,OAAO,MAAM,GAAG,CACzB,SAAQ,KAAK,iBAAiB,IAAI,cAAc,CAAC;AAIrD,MAAI,QAAQ,WAAW,EACrB,QAAO;AAGT,SAAO,QAAQ,IAAI,QAAQ,CAAC,WAAW,GAAG;;AAG5C,QAAO,EACL,QAAQ,cAAc;EACpB,MAAM,OAAO,QAAQ,eAAe;EACpC,MAAM,gBAAgB,QAAQ,kBAAkB;AAChD,MAAI,CAAC,QAAQ,CAAC,cACZ,QAAO;AAGT,MAAI,aACF,QAAO,oBAAoB,cAAc,MAAM,cAAc;AAG/D,MAAI,uBACF,QAAO;AAET,MAAI,4BACF,QAAO;AAGT,gCAA8B,oBAAoB,OAAO,KAAK,KAAK,EAAE,MAAM,cAAc,CACtF,WAAW;AACV,4BAAyB;IACzB,CACD,cAAc;AACb,iCAA8B;IAC9B;AAEJ,SAAO;IAEV"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { ArtifactCompatibilityEnvelope } from "./artifact-compatibility.js";
|
|
2
|
+
import { ReactNode } from "react";
|
|
3
|
+
|
|
4
|
+
//#region src/server/app-elements-wire.d.ts
|
|
5
|
+
declare const APP_ARTIFACT_COMPATIBILITY_KEY = "__artifactCompatibility";
|
|
6
|
+
declare const APP_INTERCEPTION_CONTEXT_KEY = "__interceptionContext";
|
|
7
|
+
declare const APP_LAYOUT_FLAGS_KEY = "__layoutFlags";
|
|
8
|
+
declare const APP_ROUTE_KEY = "__route";
|
|
9
|
+
declare const APP_ROOT_LAYOUT_KEY = "__rootLayout";
|
|
10
|
+
declare const APP_UNMATCHED_SLOT_WIRE_VALUE = "__VINEXT_UNMATCHED_SLOT__";
|
|
11
|
+
declare const UNMATCHED_SLOT: unique symbol;
|
|
12
|
+
type AppElementValue = ReactNode | typeof UNMATCHED_SLOT | string | null;
|
|
13
|
+
type AppWireElementValue = ReactNode | string | null;
|
|
14
|
+
type AppElements = Readonly<Record<string, AppElementValue>>;
|
|
15
|
+
type AppWireElements = Readonly<Record<string, AppWireElementValue>>;
|
|
16
|
+
/**
|
|
17
|
+
* Per-layout static/dynamic flags. `"s"` = static (skippable on next nav);
|
|
18
|
+
* `"d"` = dynamic (must always render).
|
|
19
|
+
*
|
|
20
|
+
* Lifecycle (partial — later PRs extend this):
|
|
21
|
+
*
|
|
22
|
+
* 1. PROBE — probeAppPageLayouts (server/app-page-execution.ts) returns
|
|
23
|
+
* LayoutFlags for every layout in the route at render time.
|
|
24
|
+
*
|
|
25
|
+
* 2. ATTACH — AppElementsWire.encodeOutgoingPayload writes `__layoutFlags`
|
|
26
|
+
* into the outgoing App Router payload record.
|
|
27
|
+
*
|
|
28
|
+
* 3. WIRE — renderToReadableStream serializes the record as RSC row 0.
|
|
29
|
+
*
|
|
30
|
+
* 4. PARSE — AppElementsWire.readMetadata extracts layoutFlags from the
|
|
31
|
+
* wire payload on the client side.
|
|
32
|
+
*/
|
|
33
|
+
type LayoutFlags = Readonly<Record<string, "s" | "d">>;
|
|
34
|
+
type AppElementsMetadata = {
|
|
35
|
+
artifactCompatibility: ArtifactCompatibilityEnvelope;
|
|
36
|
+
interceptionContext: string | null;
|
|
37
|
+
layoutFlags: LayoutFlags;
|
|
38
|
+
routeId: string;
|
|
39
|
+
rootLayoutTreePath: string | null;
|
|
40
|
+
};
|
|
41
|
+
type AppElementsWireElementKey = {
|
|
42
|
+
kind: "layout";
|
|
43
|
+
treePath: string;
|
|
44
|
+
} | {
|
|
45
|
+
interceptionContext: string | null;
|
|
46
|
+
kind: "page";
|
|
47
|
+
path: string;
|
|
48
|
+
} | {
|
|
49
|
+
interceptionContext: string | null;
|
|
50
|
+
kind: "route";
|
|
51
|
+
path: string;
|
|
52
|
+
} | {
|
|
53
|
+
kind: "slot";
|
|
54
|
+
name: string;
|
|
55
|
+
treePath: string;
|
|
56
|
+
} | {
|
|
57
|
+
kind: "template";
|
|
58
|
+
treePath: string;
|
|
59
|
+
};
|
|
60
|
+
type AppElementsWireMetadataInput = {
|
|
61
|
+
interceptionContext: string | null;
|
|
62
|
+
routeId: string;
|
|
63
|
+
rootLayoutTreePath: string | null;
|
|
64
|
+
};
|
|
65
|
+
type AppElementsWireMetadataEntries = Readonly<{
|
|
66
|
+
[APP_ROUTE_KEY]: string;
|
|
67
|
+
[APP_INTERCEPTION_CONTEXT_KEY]: string | null;
|
|
68
|
+
[APP_ROOT_LAYOUT_KEY]: string | null;
|
|
69
|
+
}>;
|
|
70
|
+
/**
|
|
71
|
+
* The outgoing wire payload shape. Includes ReactNode values for the
|
|
72
|
+
* rendered tree plus metadata values like LayoutFlags attached under
|
|
73
|
+
* known keys (e.g. __layoutFlags). Distinct from AppElements / AppWireElements
|
|
74
|
+
* which only carry render-time values.
|
|
75
|
+
*/
|
|
76
|
+
type AppOutgoingElements = Readonly<Record<string, ReactNode | LayoutFlags | ArtifactCompatibilityEnvelope>>;
|
|
77
|
+
type AppElementsWireKeys = {
|
|
78
|
+
readonly artifactCompatibility: typeof APP_ARTIFACT_COMPATIBILITY_KEY;
|
|
79
|
+
readonly interceptionContext: typeof APP_INTERCEPTION_CONTEXT_KEY;
|
|
80
|
+
readonly layoutFlags: typeof APP_LAYOUT_FLAGS_KEY;
|
|
81
|
+
readonly rootLayout: typeof APP_ROOT_LAYOUT_KEY;
|
|
82
|
+
readonly route: typeof APP_ROUTE_KEY;
|
|
83
|
+
};
|
|
84
|
+
type AppElementsWireCodec = {
|
|
85
|
+
readonly keys: AppElementsWireKeys;
|
|
86
|
+
readonly unmatchedSlotValue: typeof APP_UNMATCHED_SLOT_WIRE_VALUE;
|
|
87
|
+
createMetadataEntries(input: AppElementsWireMetadataInput): AppElementsWireMetadataEntries;
|
|
88
|
+
decode(elements: AppWireElements): AppElements;
|
|
89
|
+
encodeCacheKey(rscUrl: string, interceptionContext: string | null): string;
|
|
90
|
+
encodeLayoutId(treePath: string): string;
|
|
91
|
+
encodeOutgoingPayload(input: {
|
|
92
|
+
element: ReactNode | Readonly<Record<string, ReactNode>>;
|
|
93
|
+
artifactCompatibility?: ArtifactCompatibilityEnvelope;
|
|
94
|
+
layoutFlags: LayoutFlags;
|
|
95
|
+
}): ReactNode | AppOutgoingElements;
|
|
96
|
+
encodePageId(routePath: string, interceptionContext: string | null): string;
|
|
97
|
+
encodeRouteId(routePath: string, interceptionContext: string | null): string;
|
|
98
|
+
encodeSlotId(slotName: string, treePath: string): string;
|
|
99
|
+
encodeTemplateId(treePath: string): string;
|
|
100
|
+
isSlotId(key: string): boolean;
|
|
101
|
+
parseElementKey(key: string): AppElementsWireElementKey | null;
|
|
102
|
+
readMetadata(elements: Readonly<Record<string, unknown>>): AppElementsMetadata;
|
|
103
|
+
withLayoutFlags<T extends Record<string, unknown>>(elements: T, layoutFlags: LayoutFlags): T & {
|
|
104
|
+
[APP_LAYOUT_FLAGS_KEY]: LayoutFlags;
|
|
105
|
+
};
|
|
106
|
+
};
|
|
107
|
+
declare function normalizeAppElements(elements: AppWireElements): AppElements;
|
|
108
|
+
/**
|
|
109
|
+
* Type predicate for a plain (non-null, non-array) record of app payload values.
|
|
110
|
+
* Used to distinguish the App Router payload object from bare React elements at
|
|
111
|
+
* the render boundary. Narrows to `Readonly<Record<string, unknown>>` because
|
|
112
|
+
* the outgoing payload carries heterogeneous values (ReactNodes for the rendered
|
|
113
|
+
* tree, plus metadata like `__layoutFlags` which is a plain object). Delegates
|
|
114
|
+
* to React's canonical `isValidElement` so we don't depend on React's internal
|
|
115
|
+
* `$$typeof` marker scheme.
|
|
116
|
+
*/
|
|
117
|
+
declare function isAppElementsRecord(value: unknown): value is Readonly<Record<string, unknown>>;
|
|
118
|
+
declare function withLayoutFlags<T extends Record<string, unknown>>(elements: T, layoutFlags: LayoutFlags): T & {
|
|
119
|
+
[APP_LAYOUT_FLAGS_KEY]: LayoutFlags;
|
|
120
|
+
};
|
|
121
|
+
declare function buildOutgoingAppPayload(input: {
|
|
122
|
+
element: ReactNode | Readonly<Record<string, ReactNode>>;
|
|
123
|
+
artifactCompatibility?: ArtifactCompatibilityEnvelope;
|
|
124
|
+
layoutFlags: LayoutFlags;
|
|
125
|
+
}): ReactNode | AppOutgoingElements;
|
|
126
|
+
declare function readAppElementsMetadata(elements: Readonly<Record<string, unknown>>): AppElementsMetadata;
|
|
127
|
+
declare const AppElementsWire: AppElementsWireCodec;
|
|
128
|
+
//#endregion
|
|
129
|
+
export { APP_ARTIFACT_COMPATIBILITY_KEY, APP_INTERCEPTION_CONTEXT_KEY, APP_LAYOUT_FLAGS_KEY, APP_ROOT_LAYOUT_KEY, APP_ROUTE_KEY, APP_UNMATCHED_SLOT_WIRE_VALUE, AppElementValue, AppElements, AppElementsWire, AppOutgoingElements, AppWireElements, LayoutFlags, UNMATCHED_SLOT, buildOutgoingAppPayload, isAppElementsRecord, normalizeAppElements, readAppElementsMetadata, withLayoutFlags };
|
|
130
|
+
//# sourceMappingURL=app-elements-wire.d.ts.map
|