feat: make og images an emitter to properly await image generation (#1826)
* checkpoint * make emitters async generators * fix * custom font spec * replace spinner, use disk cache for fonts * use readline instead * make og images look nice
This commit is contained in:
		@@ -9,7 +9,7 @@ import styles from "../../styles/custom.scss"
 | 
			
		||||
import popoverStyle from "../../components/styles/popover.scss"
 | 
			
		||||
import { BuildCtx } from "../../util/ctx"
 | 
			
		||||
import { QuartzComponent } from "../../components/types"
 | 
			
		||||
import { googleFontHref, joinStyles } from "../../util/theme"
 | 
			
		||||
import { googleFontHref, joinStyles, processGoogleFonts } from "../../util/theme"
 | 
			
		||||
import { Features, transform } from "lightningcss"
 | 
			
		||||
import { transform as transpile } from "esbuild"
 | 
			
		||||
import { write } from "./helpers"
 | 
			
		||||
@@ -207,8 +207,7 @@ export const ComponentResources: QuartzEmitterPlugin = () => {
 | 
			
		||||
    async getDependencyGraph(_ctx, _content, _resources) {
 | 
			
		||||
      return new DepGraph<FilePath>()
 | 
			
		||||
    },
 | 
			
		||||
    async emit(ctx, _content, _resources): Promise<FilePath[]> {
 | 
			
		||||
      const promises: Promise<FilePath>[] = []
 | 
			
		||||
    async *emit(ctx, _content, _resources) {
 | 
			
		||||
      const cfg = ctx.cfg.configuration
 | 
			
		||||
      // component specific scripts and styles
 | 
			
		||||
      const componentResources = getComponentResources(ctx)
 | 
			
		||||
@@ -217,42 +216,35 @@ export const ComponentResources: QuartzEmitterPlugin = () => {
 | 
			
		||||
        // let the user do it themselves in css
 | 
			
		||||
      } else if (cfg.theme.fontOrigin === "googleFonts" && !cfg.theme.cdnCaching) {
 | 
			
		||||
        // when cdnCaching is true, we link to google fonts in Head.tsx
 | 
			
		||||
        let match
 | 
			
		||||
        const response = await fetch(googleFontHref(ctx.cfg.configuration.theme))
 | 
			
		||||
        googleFontsStyleSheet = await response.text()
 | 
			
		||||
 | 
			
		||||
        const fontSourceRegex = /url\((https:\/\/fonts.gstatic.com\/s\/[^)]+\.(woff2|ttf))\)/g
 | 
			
		||||
 | 
			
		||||
        googleFontsStyleSheet = await (
 | 
			
		||||
          await fetch(googleFontHref(ctx.cfg.configuration.theme))
 | 
			
		||||
        ).text()
 | 
			
		||||
 | 
			
		||||
        while ((match = fontSourceRegex.exec(googleFontsStyleSheet)) !== null) {
 | 
			
		||||
          // match[0] is the `url(path)`, match[1] is the `path`
 | 
			
		||||
          const url = match[1]
 | 
			
		||||
          // the static name of this file.
 | 
			
		||||
          const [filename, ext] = url.split("/").pop()!.split(".")
 | 
			
		||||
 | 
			
		||||
          googleFontsStyleSheet = googleFontsStyleSheet.replace(
 | 
			
		||||
            url,
 | 
			
		||||
            `https://${cfg.baseUrl}/static/fonts/${filename}.ttf`,
 | 
			
		||||
        if (!cfg.baseUrl) {
 | 
			
		||||
          throw new Error(
 | 
			
		||||
            "baseUrl must be defined when using Google Fonts without cfg.theme.cdnCaching",
 | 
			
		||||
          )
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
          promises.push(
 | 
			
		||||
            fetch(url)
 | 
			
		||||
              .then((res) => {
 | 
			
		||||
                if (!res.ok) {
 | 
			
		||||
                  throw new Error(`Failed to fetch font`)
 | 
			
		||||
                }
 | 
			
		||||
                return res.arrayBuffer()
 | 
			
		||||
              })
 | 
			
		||||
              .then((buf) =>
 | 
			
		||||
                write({
 | 
			
		||||
                  ctx,
 | 
			
		||||
                  slug: joinSegments("static", "fonts", filename) as FullSlug,
 | 
			
		||||
                  ext: `.${ext}`,
 | 
			
		||||
                  content: Buffer.from(buf),
 | 
			
		||||
                }),
 | 
			
		||||
              ),
 | 
			
		||||
          )
 | 
			
		||||
        const { processedStylesheet, fontFiles } = await processGoogleFonts(
 | 
			
		||||
          googleFontsStyleSheet,
 | 
			
		||||
          cfg.baseUrl,
 | 
			
		||||
        )
 | 
			
		||||
        googleFontsStyleSheet = processedStylesheet
 | 
			
		||||
 | 
			
		||||
        // Download and save font files
 | 
			
		||||
        for (const fontFile of fontFiles) {
 | 
			
		||||
          const res = await fetch(fontFile.url)
 | 
			
		||||
          if (!res.ok) {
 | 
			
		||||
            throw new Error(`failed to fetch font ${fontFile.filename}`)
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          const buf = await res.arrayBuffer()
 | 
			
		||||
          yield write({
 | 
			
		||||
            ctx,
 | 
			
		||||
            slug: joinSegments("static", "fonts", fontFile.filename) as FullSlug,
 | 
			
		||||
            ext: `.${fontFile.extension}`,
 | 
			
		||||
            content: Buffer.from(buf),
 | 
			
		||||
          })
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@@ -267,45 +259,42 @@ export const ComponentResources: QuartzEmitterPlugin = () => {
 | 
			
		||||
        ...componentResources.css,
 | 
			
		||||
        styles,
 | 
			
		||||
      )
 | 
			
		||||
 | 
			
		||||
      const [prescript, postscript] = await Promise.all([
 | 
			
		||||
        joinScripts(componentResources.beforeDOMLoaded),
 | 
			
		||||
        joinScripts(componentResources.afterDOMLoaded),
 | 
			
		||||
      ])
 | 
			
		||||
 | 
			
		||||
      promises.push(
 | 
			
		||||
        write({
 | 
			
		||||
          ctx,
 | 
			
		||||
          slug: "index" as FullSlug,
 | 
			
		||||
          ext: ".css",
 | 
			
		||||
          content: transform({
 | 
			
		||||
            filename: "index.css",
 | 
			
		||||
            code: Buffer.from(stylesheet),
 | 
			
		||||
            minify: true,
 | 
			
		||||
            targets: {
 | 
			
		||||
              safari: (15 << 16) | (6 << 8), // 15.6
 | 
			
		||||
              ios_saf: (15 << 16) | (6 << 8), // 15.6
 | 
			
		||||
              edge: 115 << 16,
 | 
			
		||||
              firefox: 102 << 16,
 | 
			
		||||
              chrome: 109 << 16,
 | 
			
		||||
            },
 | 
			
		||||
            include: Features.MediaQueries,
 | 
			
		||||
          }).code.toString(),
 | 
			
		||||
        }),
 | 
			
		||||
        write({
 | 
			
		||||
      yield write({
 | 
			
		||||
        ctx,
 | 
			
		||||
        slug: "index" as FullSlug,
 | 
			
		||||
        ext: ".css",
 | 
			
		||||
        content: transform({
 | 
			
		||||
          filename: "index.css",
 | 
			
		||||
          code: Buffer.from(stylesheet),
 | 
			
		||||
          minify: true,
 | 
			
		||||
          targets: {
 | 
			
		||||
            safari: (15 << 16) | (6 << 8), // 15.6
 | 
			
		||||
            ios_saf: (15 << 16) | (6 << 8), // 15.6
 | 
			
		||||
            edge: 115 << 16,
 | 
			
		||||
            firefox: 102 << 16,
 | 
			
		||||
            chrome: 109 << 16,
 | 
			
		||||
          },
 | 
			
		||||
          include: Features.MediaQueries,
 | 
			
		||||
        }).code.toString(),
 | 
			
		||||
      }),
 | 
			
		||||
        yield write({
 | 
			
		||||
          ctx,
 | 
			
		||||
          slug: "prescript" as FullSlug,
 | 
			
		||||
          ext: ".js",
 | 
			
		||||
          content: prescript,
 | 
			
		||||
        }),
 | 
			
		||||
        write({
 | 
			
		||||
        yield write({
 | 
			
		||||
          ctx,
 | 
			
		||||
          slug: "postscript" as FullSlug,
 | 
			
		||||
          ext: ".js",
 | 
			
		||||
          content: postscript,
 | 
			
		||||
        }),
 | 
			
		||||
      )
 | 
			
		||||
 | 
			
		||||
      return await Promise.all(promises)
 | 
			
		||||
        })
 | 
			
		||||
    },
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user