From 9fcc9fb526dc12063b0be346e6ac1dc6ec48c14a Mon Sep 17 00:00:00 2001 From: Matthew Phillips Date: Fri, 17 Feb 2023 12:15:13 -0500 Subject: [PATCH] Finish proof of concept --- packages/astro/src/core/compile/compile.ts | 2 -- .../astro/src/runtime/server/render/common.ts | 9 +++++++ .../astro/src/runtime/server/render/head.ts | 15 ++--------- .../astro/src/runtime/server/render/page.ts | 27 +++++++++---------- packages/astro/test/head-bubbling.test.js | 25 ++++++++++++----- 5 files changed, 41 insertions(+), 37 deletions(-) diff --git a/packages/astro/src/core/compile/compile.ts b/packages/astro/src/core/compile/compile.ts index 14e120341..3083c5cf1 100644 --- a/packages/astro/src/core/compile/compile.ts +++ b/packages/astro/src/core/compile/compile.ts @@ -69,8 +69,6 @@ export async function compile({ handleCompileResultErrors(transformResult, cssTransformErrors); - console.log(transformResult.code) - return { ...transformResult, cssDeps, diff --git a/packages/astro/src/runtime/server/render/common.ts b/packages/astro/src/runtime/server/render/common.ts index a0da5af90..f28ef0624 100644 --- a/packages/astro/src/runtime/server/render/common.ts +++ b/packages/astro/src/runtime/server/render/common.ts @@ -11,6 +11,7 @@ import { import { renderAllHeadContent } from './head.js'; import { hasScopeFlag, ScopeFlags } from './scope.js'; import { isSlotString, type SlotString } from './slot.js'; +import { renderChild } from './any.js'; export const Fragment = Symbol.for('astro:fragment'); export const Renderer = Symbol.for('astro:renderer'); @@ -152,3 +153,11 @@ export function chunkToByteArray( let stringified = stringifyChunk(result, chunk); return encoder.encode(stringified.toString()); } + +export async function renderToStringAsync(result: SSRResult, part: unknown): Promise { + let out = ''; + for await(const chunk of renderChild(part)) { + out += stringifyChunk(result, chunk); + } + return out; +} diff --git a/packages/astro/src/runtime/server/render/head.ts b/packages/astro/src/runtime/server/render/head.ts index d693ecdf7..16a97e9ab 100644 --- a/packages/astro/src/runtime/server/render/head.ts +++ b/packages/astro/src/runtime/server/render/head.ts @@ -12,7 +12,7 @@ const uniqueElements = (item: any, index: number, all: any[]) => { ); }; -export function renderScriptsAndStyles(result: SSRResult) { +export function renderAllHeadContent(result: SSRResult) { result._metadata.hasRenderedHead = true; const styles = Array.from(result.styles) .filter(uniqueElements) @@ -30,20 +30,9 @@ export function renderScriptsAndStyles(result: SSRResult) { let content = links.join('\n') + styles.join('\n') + scripts.join('\n'); - return markHTMLString(content); -} - -export function renderAllHeadContent(result: SSRResult) { - result._metadata.hasRenderedHead = true; - let content = renderScriptsAndStyles(result); - if (result.extraHead.length > 0) { for (const part of result.extraHead) { - if(typeof part === 'string') { - content += part; - } else { - throw new Error('We can only stringify string head injection'); - } + content += part; } } diff --git a/packages/astro/src/runtime/server/render/page.ts b/packages/astro/src/runtime/server/render/page.ts index 1dbf8ea48..334c5191a 100644 --- a/packages/astro/src/runtime/server/render/page.ts +++ b/packages/astro/src/runtime/server/render/page.ts @@ -12,10 +12,11 @@ import { isRenderTemplateResult, renderAstroTemplateResult, } from './astro/index.js'; -import { chunkToByteArray, encoder, HTMLParts, isRenderInstruction } from './common.js'; +import { chunkToByteArray, encoder, HTMLParts, renderToStringAsync } from './common.js'; import { renderComponent } from './component.js'; -import { maybeRenderHead, renderScriptsAndStyles } from './head.js'; +import { maybeRenderHead } from './head.js'; import { createScopedResult, ScopeFlags } from './scope.js'; +import { renderChild } from './any.js'; const needsHeadRenderingSymbol = Symbol.for('astro.needsHeadRendering'); @@ -64,7 +65,13 @@ async function bufferHeadContent(result: SSRResult) { } const returnValue = await value.init(scoped); if (isHeadAndContent(returnValue)) { - result.extraHead.push(returnValue.head); + if(typeof returnValue.head === 'string') { + result.extraHead.push(returnValue.head); + } else { + const head = await renderToStringAsync(result, returnValue.head); + result.extraHead.push(head); + } + } } } @@ -149,18 +156,8 @@ export async function renderPage( } } - if(isRenderInstruction(chunk) && chunk.type === 'head') { - debugger; - let head = renderScriptsAndStyles(result); - for await(const part of result.extraHead) { - head += part; - } - const bytes = encoder.encode(head); - controller.enqueue(bytes); - } else { - const bytes = chunkToByteArray(result, chunk); - controller.enqueue(bytes); - } + const bytes = chunkToByteArray(result, chunk); + controller.enqueue(bytes); i++; } diff --git a/packages/astro/test/head-bubbling.test.js b/packages/astro/test/head-bubbling.test.js index 61b59e7cb..f228fc9bd 100644 --- a/packages/astro/test/head-bubbling.test.js +++ b/packages/astro/test/head-bubbling.test.js @@ -2,7 +2,7 @@ import { expect } from 'chai'; import * as cheerio from 'cheerio'; import { loadFixture } from './test-utils.js'; -describe('Astro basics', () => { +describe('Head bubbling', () => { /** @type {import('./test-utils').Fixture} */ let fixture; @@ -13,13 +13,24 @@ describe('Astro basics', () => { await fixture.build(); }); - describe('build', () => { - it('Renders component head contents into the head', async () => { - const html = await fixture.readFile(`/index.html`); - console.log(html); - //const $ = cheerio.load(html); + describe('index page', () => { + /** @type {string} */ + let html; + /** @type {ReturnType} */ + let $; + before(async () => { + html = await fixture.readFile(`/index.html`); + $ = cheerio.load(html); + }); - //expect($('h1').text()).to.equal('Hello world!'); + it('Renders component head contents into the head', async () => { + const $metas = $('head meta'); + + expect($metas).to.have.a.lengthOf(2); + }); + + it('Body contents in the body', async () => { + expect($('body article')).to.have.a.lengthOf(1); }); }); });