diff --git a/.changeset/many-nails-arrive.md b/.changeset/many-nails-arrive.md new file mode 100644 index 000000000000..b620c712a1a3 --- /dev/null +++ b/.changeset/many-nails-arrive.md @@ -0,0 +1,5 @@ +--- +'@astrojs/markdoc': patch +--- + +Handle internal access change diff --git a/packages/astro/src/@types/astro.ts b/packages/astro/src/@types/astro.ts index 185401a898be..861104e91c4c 100644 --- a/packages/astro/src/@types/astro.ts +++ b/packages/astro/src/@types/astro.ts @@ -1932,16 +1932,6 @@ export interface SSRElement { children: string; } -export interface SSRMetadata { - renderers: SSRLoadedRenderer[]; - pathname: string; - hasHydrationScript: boolean; - hasDirectives: Set; - hasRenderedHead: boolean; - headInTree: boolean; - clientDirectives: Map; -} - /** * A hint on whether the Astro runtime needs to wait on a component to render head * content. The meanings: @@ -1964,9 +1954,6 @@ export interface SSRResult { scripts: Set; links: Set; componentMetadata: Map; - propagators: Map; - extraHead: Array; - cookies: AstroCookies | undefined; createAstro( Astro: AstroGlobalPartial, props: Record, @@ -1974,13 +1961,32 @@ export interface SSRResult { ): AstroGlobal; resolve: (s: string) => Promise; response: ResponseInit; - // Bits 1 = astro, 2 = jsx, 4 = slot - // As rendering occurs these bits are manipulated to determine where content - // is within a slot. This is used for head injection. - scope: number; + renderers: SSRLoadedRenderer[]; + /** + * Map of directive name (e.g. `load`) to the directive script code + */ + clientDirectives: Map; + /** + * Only used for logging + */ + pathname: string; + cookies: AstroCookies | undefined; _metadata: SSRMetadata; } +/** + * Ephemeral and mutable state during rendering that doesn't rely + * on external configuration + */ +export interface SSRMetadata { + hasHydrationScript: boolean; + hasDirectives: Set; + hasRenderedHead: boolean; + headInTree: boolean; + extraHead: string[]; + propagators: Map; +} + /* Preview server stuff */ export interface PreviewServer { host?: string; diff --git a/packages/astro/src/core/app/index.ts b/packages/astro/src/core/app/index.ts index c69267b92a4b..0e3dd0993e04 100644 --- a/packages/astro/src/core/app/index.ts +++ b/packages/astro/src/core/app/index.ts @@ -227,7 +227,6 @@ export class App { const mod = (await page.page()) as any; const renderContext = await createRenderContext({ request, - origin: url.origin, pathname, componentMetadata: this.#manifest.componentMetadata, scripts, @@ -295,7 +294,6 @@ export class App { const ctx = await createRenderContext({ request, - origin: url.origin, pathname, route: routeData, status, diff --git a/packages/astro/src/core/build/generate.ts b/packages/astro/src/core/build/generate.ts index 5a91962be8c3..09160082c981 100644 --- a/packages/astro/src/core/build/generate.ts +++ b/packages/astro/src/core/build/generate.ts @@ -539,7 +539,6 @@ async function generatePath( }); const renderContext = await createRenderContext({ - origin, pathname, request: createRequest({ url, headers: new Headers(), logging, ssr }), componentMetadata: manifest.componentMetadata, diff --git a/packages/astro/src/core/endpoint/dev/index.ts b/packages/astro/src/core/endpoint/dev/index.ts index 1f091716653c..13f2bfa272c9 100644 --- a/packages/astro/src/core/endpoint/dev/index.ts +++ b/packages/astro/src/core/endpoint/dev/index.ts @@ -10,7 +10,6 @@ export async function call(options: SSROptions, logging: LogOptions) { const ctx = await createRenderContext({ request: options.request, - origin: options.origin, pathname: options.pathname, route: options.route, env, diff --git a/packages/astro/src/core/render/context.ts b/packages/astro/src/core/render/context.ts index e8ca1017e8cc..5b26eda18e39 100644 --- a/packages/astro/src/core/render/context.ts +++ b/packages/astro/src/core/render/context.ts @@ -1,5 +1,4 @@ import type { - AstroCookies, ComponentInstance, Params, Props, @@ -18,23 +17,21 @@ const clientLocalsSymbol = Symbol.for('astro.locals'); */ export interface RenderContext { request: Request; - origin: string; pathname: string; - url: URL; scripts?: Set; links?: Set; styles?: Set; componentMetadata?: SSRResult['componentMetadata']; route?: RouteData; status?: number; - cookies?: AstroCookies; params: Params; props: Props; locals?: object; } -export type CreateRenderContextArgs = Partial & { - origin?: string; +export type CreateRenderContextArgs = Partial< + Omit +> & { request: RenderContext['request']; mod: ComponentInstance; env: Environment; @@ -44,9 +41,7 @@ export async function createRenderContext( options: CreateRenderContextArgs ): Promise { const request = options.request; - const url = new URL(request.url); - const origin = options.origin ?? url.origin; - const pathname = options.pathname ?? url.pathname; + const pathname = options.pathname ?? new URL(request.url).pathname; const [params, props] = await getParamsAndProps({ mod: options.mod as any, route: options.route, @@ -56,11 +51,9 @@ export async function createRenderContext( ssr: options.env.ssr, }); - let context = { + const context: RenderContext = { ...options, - origin, pathname, - url, params, props, }; diff --git a/packages/astro/src/core/render/core.ts b/packages/astro/src/core/render/core.ts index 201b91292445..1c91cebea460 100644 --- a/packages/astro/src/core/render/core.ts +++ b/packages/astro/src/core/render/core.ts @@ -41,10 +41,7 @@ export async function renderPage({ styles: renderContext.styles, logging: env.logging, markdown: env.markdown, - mode: env.mode, - origin: renderContext.origin, params: renderContext.params, - props: renderContext.props, pathname: renderContext.pathname, componentMetadata: renderContext.componentMetadata, resolve: env.resolve, diff --git a/packages/astro/src/core/render/dev/index.ts b/packages/astro/src/core/render/dev/index.ts index 3fd0203fc7ad..360832af4759 100644 --- a/packages/astro/src/core/render/dev/index.ts +++ b/packages/astro/src/core/render/dev/index.ts @@ -24,8 +24,6 @@ export interface SSROptions { env: DevelopmentEnvironment; /** location of file on disk */ filePath: URL; - /** production website */ - origin: string; /** the web request (needed for dynamic routes) */ pathname: string; /** The runtime component instance */ @@ -157,7 +155,6 @@ export async function renderPage(options: SSROptions): Promise { const renderContext = await createRenderContext({ request: options.request, - origin: options.origin, pathname: options.pathname, scripts, links, diff --git a/packages/astro/src/core/render/result.ts b/packages/astro/src/core/render/result.ts index 905593b6a3a4..9d72c455ad38 100644 --- a/packages/astro/src/core/render/result.ts +++ b/packages/astro/src/core/render/result.ts @@ -3,8 +3,6 @@ import type { AstroGlobal, AstroGlobalPartial, Params, - Props, - RuntimeMode, SSRElement, SSRLoadedRenderer, SSRResult, @@ -33,15 +31,12 @@ export interface CreateResultArgs { */ ssr: boolean; logging: LogOptions; - origin: string; /** * Used to support `Astro.__renderMarkdown` for legacy `` component */ markdown: MarkdownRenderingOptions; - mode: RuntimeMode; params: Params; pathname: string; - props: Props; renderers: SSRLoadedRenderer[]; clientDirectives: Map; resolve: (s: string) => Promise; @@ -170,9 +165,9 @@ export function createResult(args: CreateResultArgs): SSRResult { scripts: args.scripts ?? new Set(), links: args.links ?? new Set(), componentMetadata, - propagators: new Map(), - extraHead: [], - scope: 0, + renderers, + clientDirectives, + pathname, cookies, /** This function returns the `Astro` faux-global */ createAstro( @@ -259,16 +254,15 @@ export function createResult(args: CreateResultArgs): SSRResult { return Astro; }, resolve, + response, _metadata: { - renderers, - pathname, hasHydrationScript: false, hasRenderedHead: false, hasDirectives: new Set(), headInTree: false, - clientDirectives, + extraHead: [], + propagators: new Map(), }, - response, }; return result; diff --git a/packages/astro/src/runtime/server/hydration.ts b/packages/astro/src/runtime/server/hydration.ts index 9394be581146..bb8d64912979 100644 --- a/packages/astro/src/runtime/server/hydration.ts +++ b/packages/astro/src/runtime/server/hydration.ts @@ -26,7 +26,7 @@ interface ExtractedProps { // Finds these special props and removes them from what gets passed into the component. export function extractDirectives( inputProps: Record, - clientDirectives: SSRResult['_metadata']['clientDirectives'] + clientDirectives: SSRResult['clientDirectives'] ): ExtractedProps { let extracted: ExtractedProps = { isPage: false, diff --git a/packages/astro/src/runtime/server/jsx.ts b/packages/astro/src/runtime/server/jsx.ts index 6bea1bc71aac..6498421f3825 100644 --- a/packages/astro/src/runtime/server/jsx.ts +++ b/packages/astro/src/runtime/server/jsx.ts @@ -76,7 +76,7 @@ async function renderJSXVNode(result: SSRResult, vnode: AstroVNode, skip: Skip): if (isVNode(vnode)) { switch (true) { case !vnode.type: { - throw new Error(`Unable to render ${result._metadata.pathname} because it contains an undefined Component! + throw new Error(`Unable to render ${result.pathname} because it contains an undefined Component! Did you forget to import the component or is it possible there is a typo?`); } case (vnode.type as any) === Symbol.for('astro:fragment'): diff --git a/packages/astro/src/runtime/server/render/astro/instance.ts b/packages/astro/src/runtime/server/render/astro/instance.ts index ed5044575ae5..527d4a8c67f2 100644 --- a/packages/astro/src/runtime/server/render/astro/instance.ts +++ b/packages/astro/src/runtime/server/render/astro/instance.ts @@ -80,8 +80,8 @@ export function createAstroComponentInstance( ) { validateComponentProps(props, displayName); const instance = new AstroComponentInstance(result, props, slots, factory); - if (isAPropagatingComponent(result, factory) && !result.propagators.has(factory)) { - result.propagators.set(factory, instance); + if (isAPropagatingComponent(result, factory) && !result._metadata.propagators.has(factory)) { + result._metadata.propagators.set(factory, instance); } return instance; } diff --git a/packages/astro/src/runtime/server/render/component.ts b/packages/astro/src/runtime/server/render/component.ts index 7fee7da2bdec..67d61ce614b1 100644 --- a/packages/astro/src/runtime/server/render/component.ts +++ b/packages/astro/src/runtime/server/render/component.ts @@ -74,7 +74,7 @@ async function renderFrameworkComponent( ); } - const { renderers, clientDirectives } = result._metadata; + const { renderers, clientDirectives } = result; const metadata: AstroComponentMetadata = { astroStaticSlot: true, displayName, diff --git a/packages/astro/src/runtime/server/render/head.ts b/packages/astro/src/runtime/server/render/head.ts index 8ac9df0e0695..7bb38f07db5f 100644 --- a/packages/astro/src/runtime/server/render/head.ts +++ b/packages/astro/src/runtime/server/render/head.ts @@ -1,6 +1,7 @@ import type { SSRResult } from '../../../@types/astro'; import { markHTMLString } from '../escape.js'; +import type { MaybeRenderHeadInstruction, RenderHeadInstruction } from './types'; import { renderElement } from './util.js'; // Filter out duplicate elements in our set @@ -34,8 +35,8 @@ export function renderAllHeadContent(result: SSRResult) { let content = links.join('\n') + styles.join('\n') + scripts.join('\n'); - if (result.extraHead.length > 0) { - for (const part of result.extraHead) { + if (result._metadata.extraHead.length > 0) { + for (const part of result._metadata.extraHead) { content += part; } } @@ -43,20 +44,16 @@ export function renderAllHeadContent(result: SSRResult) { return markHTMLString(content); } -export function* renderHead(result: SSRResult) { - yield { type: 'head', result } as const; +export function* renderHead(): Generator { + yield { type: 'head' }; } // This function is called by Astro components that do not contain a component // This accommodates the fact that using a is optional in Astro, so this // is called before a component's first non-head HTML element. If the head was // already injected it is a noop. -export function* maybeRenderHead(result: SSRResult) { - if (result._metadata.hasRenderedHead) { - return; - } - +export function* maybeRenderHead(): Generator { // This is an instruction informing the page rendering that head might need rendering. // This allows the page to deduplicate head injections. - yield { type: 'maybe-head', result, scope: result.scope } as const; + yield { type: 'maybe-head' }; } diff --git a/packages/astro/src/runtime/server/render/page.ts b/packages/astro/src/runtime/server/render/page.ts index d7b81e96c2e1..ffbc11b9e6d7 100644 --- a/packages/astro/src/runtime/server/render/page.ts +++ b/packages/astro/src/runtime/server/render/page.ts @@ -55,7 +55,7 @@ async function iterableToHTMLBytes( // Recursively calls component instances that might have head content // to be propagated up. async function bufferHeadContent(result: SSRResult) { - const iterator = result.propagators.values(); + const iterator = result._metadata.propagators.values(); while (true) { const { value, done } = iterator.next(); if (done) { @@ -63,7 +63,7 @@ async function bufferHeadContent(result: SSRResult) { } const returnValue = await value.init(result); if (isHeadAndContent(returnValue)) { - result.extraHead.push(returnValue.head); + result._metadata.extraHead.push(returnValue.head); } } } @@ -86,7 +86,7 @@ export async function renderPage( try { if (nonAstroPageNeedsHeadInjection(componentFactory)) { const parts = new HTMLParts(); - for await (const chunk of maybeRenderHead(result)) { + for await (const chunk of maybeRenderHead()) { parts.append(chunk, result); } head = parts.toString(); diff --git a/packages/astro/src/runtime/server/render/types.ts b/packages/astro/src/runtime/server/render/types.ts index 31702f44409d..1c3a888db1e8 100644 --- a/packages/astro/src/runtime/server/render/types.ts +++ b/packages/astro/src/runtime/server/render/types.ts @@ -1,21 +1,16 @@ -import type { SSRResult } from '../../../@types/astro'; import type { HydrationMetadata } from '../hydration.js'; export type RenderDirectiveInstruction = { type: 'directive'; - result: SSRResult; hydration: HydrationMetadata; }; export type RenderHeadInstruction = { type: 'head'; - result: SSRResult; }; export type MaybeRenderHeadInstruction = { type: 'maybe-head'; - result: SSRResult; - scope: number; }; export type RenderInstruction = diff --git a/packages/astro/src/runtime/server/scripts.ts b/packages/astro/src/runtime/server/scripts.ts index 4ba12d1ab08e..a56f6686adb6 100644 --- a/packages/astro/src/runtime/server/scripts.ts +++ b/packages/astro/src/runtime/server/scripts.ts @@ -21,7 +21,7 @@ export function determinesIfNeedsDirectiveScript(result: SSRResult, directive: s export type PrescriptType = null | 'both' | 'directive'; function getDirectiveScriptText(result: SSRResult, directive: string): string { - const clientDirectives = result._metadata.clientDirectives; + const clientDirectives = result.clientDirectives; const clientDirective = clientDirectives.get(directive); if (!clientDirective) { throw new Error(`Unknown directive: ${directive}`); diff --git a/packages/astro/src/vite-plugin-astro-server/route.ts b/packages/astro/src/vite-plugin-astro-server/route.ts index ae8abace7683..59185f914a9f 100644 --- a/packages/astro/src/vite-plugin-astro-server/route.ts +++ b/packages/astro/src/vite-plugin-astro-server/route.ts @@ -165,7 +165,6 @@ export async function handleRoute( const options: SSROptions = { env, filePath, - origin, preload: preloadedComponent, pathname, request, diff --git a/packages/integrations/markdoc/components/TreeNode.ts b/packages/integrations/markdoc/components/TreeNode.ts index 082495a87f24..31976c19d321 100644 --- a/packages/integrations/markdoc/components/TreeNode.ts +++ b/packages/integrations/markdoc/components/TreeNode.ts @@ -89,7 +89,10 @@ export const ComponentNode = createComponent({ ); // Let the runtime know that this component is being used. - result.propagators.set( + // `result.propagators` has been moved to `result._metadata.propagators` + // TODO: remove this fallback in the next markdoc integration major + const propagators = result._metadata.propagators || result.propagators; + propagators.set( {}, { init() {