Finish proof of concept
This commit is contained in:
parent
515b378e73
commit
9fcc9fb526
5 changed files with 41 additions and 37 deletions
|
@ -69,8 +69,6 @@ export async function compile({
|
||||||
|
|
||||||
handleCompileResultErrors(transformResult, cssTransformErrors);
|
handleCompileResultErrors(transformResult, cssTransformErrors);
|
||||||
|
|
||||||
console.log(transformResult.code)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...transformResult,
|
...transformResult,
|
||||||
cssDeps,
|
cssDeps,
|
||||||
|
|
|
@ -11,6 +11,7 @@ import {
|
||||||
import { renderAllHeadContent } from './head.js';
|
import { renderAllHeadContent } from './head.js';
|
||||||
import { hasScopeFlag, ScopeFlags } from './scope.js';
|
import { hasScopeFlag, ScopeFlags } from './scope.js';
|
||||||
import { isSlotString, type SlotString } from './slot.js';
|
import { isSlotString, type SlotString } from './slot.js';
|
||||||
|
import { renderChild } from './any.js';
|
||||||
|
|
||||||
export const Fragment = Symbol.for('astro:fragment');
|
export const Fragment = Symbol.for('astro:fragment');
|
||||||
export const Renderer = Symbol.for('astro:renderer');
|
export const Renderer = Symbol.for('astro:renderer');
|
||||||
|
@ -152,3 +153,11 @@ export function chunkToByteArray(
|
||||||
let stringified = stringifyChunk(result, chunk);
|
let stringified = stringifyChunk(result, chunk);
|
||||||
return encoder.encode(stringified.toString());
|
return encoder.encode(stringified.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function renderToStringAsync(result: SSRResult, part: unknown): Promise<string> {
|
||||||
|
let out = '';
|
||||||
|
for await(const chunk of renderChild(part)) {
|
||||||
|
out += stringifyChunk(result, chunk);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
result._metadata.hasRenderedHead = true;
|
||||||
const styles = Array.from(result.styles)
|
const styles = Array.from(result.styles)
|
||||||
.filter(uniqueElements)
|
.filter(uniqueElements)
|
||||||
|
@ -30,20 +30,9 @@ export function renderScriptsAndStyles(result: SSRResult) {
|
||||||
|
|
||||||
let content = links.join('\n') + styles.join('\n') + scripts.join('\n');
|
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) {
|
if (result.extraHead.length > 0) {
|
||||||
for (const part of result.extraHead) {
|
for (const part of result.extraHead) {
|
||||||
if(typeof part === 'string') {
|
content += part;
|
||||||
content += part;
|
|
||||||
} else {
|
|
||||||
throw new Error('We can only stringify string head injection');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,10 +12,11 @@ import {
|
||||||
isRenderTemplateResult,
|
isRenderTemplateResult,
|
||||||
renderAstroTemplateResult,
|
renderAstroTemplateResult,
|
||||||
} from './astro/index.js';
|
} 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 { renderComponent } from './component.js';
|
||||||
import { maybeRenderHead, renderScriptsAndStyles } from './head.js';
|
import { maybeRenderHead } from './head.js';
|
||||||
import { createScopedResult, ScopeFlags } from './scope.js';
|
import { createScopedResult, ScopeFlags } from './scope.js';
|
||||||
|
import { renderChild } from './any.js';
|
||||||
|
|
||||||
const needsHeadRenderingSymbol = Symbol.for('astro.needsHeadRendering');
|
const needsHeadRenderingSymbol = Symbol.for('astro.needsHeadRendering');
|
||||||
|
|
||||||
|
@ -64,7 +65,13 @@ async function bufferHeadContent(result: SSRResult) {
|
||||||
}
|
}
|
||||||
const returnValue = await value.init(scoped);
|
const returnValue = await value.init(scoped);
|
||||||
if (isHeadAndContent(returnValue)) {
|
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') {
|
const bytes = chunkToByteArray(result, chunk);
|
||||||
debugger;
|
controller.enqueue(bytes);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { expect } from 'chai';
|
||||||
import * as cheerio from 'cheerio';
|
import * as cheerio from 'cheerio';
|
||||||
import { loadFixture } from './test-utils.js';
|
import { loadFixture } from './test-utils.js';
|
||||||
|
|
||||||
describe('Astro basics', () => {
|
describe('Head bubbling', () => {
|
||||||
/** @type {import('./test-utils').Fixture} */
|
/** @type {import('./test-utils').Fixture} */
|
||||||
let fixture;
|
let fixture;
|
||||||
|
|
||||||
|
@ -13,13 +13,24 @@ describe('Astro basics', () => {
|
||||||
await fixture.build();
|
await fixture.build();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('build', () => {
|
describe('index page', () => {
|
||||||
it('Renders component head contents into the head', async () => {
|
/** @type {string} */
|
||||||
const html = await fixture.readFile(`/index.html`);
|
let html;
|
||||||
console.log(html);
|
/** @type {ReturnType<typeof cheerio.load>} */
|
||||||
//const $ = cheerio.load(html);
|
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);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue