Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions build/server-worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,12 @@ if (!indexModulePath) {
try {
/** @type {import("../entry.ssr.js")} */
const indexModule = await import(pathToFileURL(indexModulePath).href);
const html = await indexModule?.render(reqPath, context, {
client: compilationStats.find((x) => x.name === "client") || {},
legacy: compilationStats.find((x) => x.name === "legacy") || {},
});
const html = process.env.FRED_SIMPLE_HTML
? `<!doctype html><meta charset="UTF-8">${await indexModule?.renderSimple(reqPath, context)}`
: await indexModule?.render(reqPath, context, {
client: compilationStats.find((x) => x.name === "client") || {},
legacy: compilationStats.find((x) => x.name === "legacy") || {},
});
parentPort?.postMessage({ html });
} catch (error) {
parentPort?.postMessage({ error });
Expand Down
10 changes: 9 additions & 1 deletion components/doc/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,16 @@ import { ServerComponent } from "../server/index.js";
export class Doc extends ServerComponent {
/**
* @param {import("@fred").Context<import("@rari").DocPage>} context
*/ render(context) {
*/
render(context) {
context.pageTitle = context.doc.pageTitle;
return PageLayout.render(context, ReferenceLayout.render(context));
}

/**
* @param {import("@fred").Context<import("@rari").DocPage>} context
*/
Comment on lines +14 to +16
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: explain what this method omits (even if it's comparably trivial from looking at render/renderSimple side-by-side

renderSimple(context) {
return ReferenceLayout.render(context);
}
}
2 changes: 1 addition & 1 deletion components/outer-layout/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export class OuterLayout extends ServerComponent {
*/
render(context, markup) {
const asyncStore = asyncLocalStorage.getStore();
if (!asyncStore) {
if (!asyncStore || "renderSimple" in asyncStore) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why would renderSimple end up in asyncStore?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It wouldn't in the outer layout, since we don't call it from the renderSimple root function: this is simply to make typescript happy.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I realize that I don't fully understand what asyncLocalStorage holds.

I looked at https://github.com/mdn/fred/blob/22628366e1b9ecc0d8f36811492c5a6f08e62db4/components/server/async-local-storage.js and it doesn't have any information, it just creates an instance of AsyncLocalStorage without any semantic notion of what it contains.

It is not clear to me why "renderSimple" in asyncStore implies that asyncLocalStorage is missing. It would probably be better to throw a separate error in this case, because if asyncStore is truthy, it's apparently not missing.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah it's a little bit esoteric: the top level render methods (in entry.ssr.js) populate it. I'll add a jsdoc comment or similar to explain what's going on, and point back to there.

Agreed on the error, that was just me being a little lazy.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a comment, and realised the name of AsyncLocalStorageContents may have seemed a little "official" - like it was coming from node itself - rather than something we had defined so renamed it, in 198df40 (#1072)

throw new Error("asyncLocalStorage missing");
}
const { componentsUsed, componentsWithStylesInHead, compilationStats } =
Expand Down
14 changes: 14 additions & 0 deletions components/reference-layout/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,18 @@ export class ReferenceLayout extends ServerComponent {
</div>
`;
}

/**
* @param {import("@fred").Context<import("@rari").DocPage>} context
*/
Comment on lines +48 to +50
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: explain what this simplified/minimal rendering omits

renderSimple(context) {
const { doc } = context;
const sections =
doc.body?.map((section) => ContentSection.render(context, section)) || [];

return html`
<h1>${doc.title}</h1>
${BaselineIndicator.render(context)} ${sections}
`;
}
}
17 changes: 16 additions & 1 deletion components/server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ export class ServerComponent {
if (!asyncStore) {
throw new Error("asyncLocalStorage missing");
}

const component = new this();

if ("renderSimple" in asyncStore) {
return component.renderSimple(...args);
}

const { componentsUsed, componentsWithStylesInHead, compilationStats } =
asyncStore;
const componentUsedBefore = componentsUsed.has(this.name);
Expand All @@ -35,7 +42,7 @@ export class ServerComponent {
componentsUsed.add("legacy");
}

let res = new this().render(...args);
let res = component.render(...args);

if (!res || res === nothing) {
if (!componentUsedBefore) {
Expand Down Expand Up @@ -73,4 +80,12 @@ export class ServerComponent {
render(..._args) {
throw new Error("Must be implemented by subclass");
}

/**
* @param {...any} args
* @returns {any}
*/
Comment on lines +84 to +87
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: add description of this method

renderSimple(...args) {
return this.render(...args);
}
}
14 changes: 9 additions & 5 deletions components/server/types.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
export interface AsyncLocalStorageContents {
componentsUsed: Set<string>;
componentsWithStylesInHead: Set<string>;
compilationStats: import("@fred").CompilationStats;
}
export type AsyncLocalStorageContents =
| {
componentsUsed: Set<string>;
componentsWithStylesInHead: Set<string>;
compilationStats: import("@fred").CompilationStats;
}
| {
renderSimple: true;
};
32 changes: 32 additions & 0 deletions entry.ssr.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
import { render as r } from "@lit-labs/ssr";
import { collectResult } from "@lit-labs/ssr/lib/render-result.js";

import { nothing } from "lit";

import { Advertising } from "./components/advertising/server.js";
import { BlogIndex } from "./components/blog-index/server.js";
import { BlogPost } from "./components/blog-post/server.js";
Expand Down Expand Up @@ -130,3 +132,33 @@ export async function render(path, partialContext, compilationStats) {
}),
);
}

/**
* @param {string} path
* @param {import("@fred").PartialContext} partialContext
*/
export async function renderSimple(path, partialContext) {
const locale = path.split("/")[1] || "en-US";
const context = {
path,
...(await addFluent(locale)),
...partialContext,
};
/** @type {import("./components/server/types.js").AsyncLocalStorageContents} */
const storageContents = {
renderSimple: true,
};
return asyncLocalStorage.run(storageContents, () =>
runWithContext({ locale }, async () => {
const component = await (async () => {
switch (context.renderer) {
case "Doc":
return Doc.render(context);
default:
return nothing;
}
})();
return await collectResult(r(component));
}),
);
}
Loading