astro-ghostcms/.pnpm-store/v3/files/38/0a32a4d26605d1a89e1d80ce4e5...

116 lines
3.6 KiB
Plaintext

import { AstroError, AstroErrorData } from "../../../../core/errors/index.js";
import { chunkToByteArray, chunkToString, encoder } from "../common.js";
import { isHeadAndContent } from "./head-and-content.js";
import { isRenderTemplateResult } from "./render-template.js";
async function renderToString(result, componentFactory, props, children, isPage = false, route) {
const templateResult = await callComponentAsTemplateResultOrResponse(
result,
componentFactory,
props,
children,
route
);
if (templateResult instanceof Response)
return templateResult;
let str = "";
let renderedFirstPageChunk = false;
const destination = {
write(chunk) {
if (isPage && !renderedFirstPageChunk) {
renderedFirstPageChunk = true;
if (!result.partial && !/<!doctype html/i.test(String(chunk))) {
const doctype = result.compressHTML ? "<!DOCTYPE html>" : "<!DOCTYPE html>\n";
str += doctype;
}
}
if (chunk instanceof Response)
return;
str += chunkToString(result, chunk);
}
};
await templateResult.render(destination);
return str;
}
async function renderToReadableStream(result, componentFactory, props, children, isPage = false, route) {
const templateResult = await callComponentAsTemplateResultOrResponse(
result,
componentFactory,
props,
children,
route
);
if (templateResult instanceof Response)
return templateResult;
let renderedFirstPageChunk = false;
if (isPage) {
await bufferHeadContent(result);
}
return new ReadableStream({
start(controller) {
const destination = {
write(chunk) {
if (isPage && !renderedFirstPageChunk) {
renderedFirstPageChunk = true;
if (!result.partial && !/<!doctype html/i.test(String(chunk))) {
const doctype = result.compressHTML ? "<!DOCTYPE html>" : "<!DOCTYPE html>\n";
controller.enqueue(encoder.encode(doctype));
}
}
if (chunk instanceof Response) {
throw new AstroError({
...AstroErrorData.ResponseSentError
});
}
const bytes = chunkToByteArray(result, chunk);
controller.enqueue(bytes);
}
};
(async () => {
try {
await templateResult.render(destination);
controller.close();
} catch (e) {
if (AstroError.is(e) && !e.loc) {
e.setLocation({
file: route?.component
});
}
setTimeout(() => controller.error(e), 0);
}
})();
}
});
}
async function callComponentAsTemplateResultOrResponse(result, componentFactory, props, children, route) {
const factoryResult = await componentFactory(result, props, children);
if (factoryResult instanceof Response) {
return factoryResult;
} else if (!isRenderTemplateResult(factoryResult)) {
throw new AstroError({
...AstroErrorData.OnlyResponseCanBeReturned,
message: AstroErrorData.OnlyResponseCanBeReturned.message(route?.route, typeof factoryResult),
location: {
file: route?.component
}
});
}
return isHeadAndContent(factoryResult) ? factoryResult.content : factoryResult;
}
async function bufferHeadContent(result) {
const iterator = result._metadata.propagators.values();
while (true) {
const { value, done } = iterator.next();
if (done) {
break;
}
const returnValue = await value.init(result);
if (isHeadAndContent(returnValue)) {
result._metadata.extraHead.push(returnValue.head);
}
}
}
export {
renderToReadableStream,
renderToString
};