From cf2e3b31cb084d38618539ac5097b5c862f17f20 Mon Sep 17 00:00:00 2001 From: Nate Moore Date: Tue, 21 Sep 2021 17:04:25 +0000 Subject: [PATCH] Throw Error for WIP Features --- packages/astro/components/Markdown.astro | 75 ------------- packages/astro/components/Prism.astro | 135 ++++------------------- packages/astro/components/index.js | 21 +++- packages/astro/package.json | 1 + packages/astro/src/runtime/ssr.ts | 27 ++--- 5 files changed, 50 insertions(+), 209 deletions(-) diff --git a/packages/astro/components/Markdown.astro b/packages/astro/components/Markdown.astro index c03eb73c8..fba8316a2 100644 --- a/packages/astro/components/Markdown.astro +++ b/packages/astro/components/Markdown.astro @@ -10,84 +10,9 @@ interface InternalProps extends Props { $scope: string; } -const __TopLevelAstro = { - site: new URL("http://localhost:3000"), - fetchContent: (globResult) => fetchContent(globResult, import.meta.url), - resolve(...segments) { - return segments.reduce( - (url, segment) => new URL(segment, url), - new URL("http://localhost:3000/packages/astro/components/Markdown.astro") - ).pathname - }, -}; -const Astro = __TopLevelAstro; - -export interface Props { - content?: string; -} - -// Internal props that should not be part of the external interface. -interface InternalProps extends Props { - $scope: string; -} - -const __TopLevelAstro = { - site: new URL("http://localhost:3000"), - fetchContent: (globResult) => fetchContent(globResult, import.meta.url), - resolve(...segments) { - return segments.reduce( - (url, segment) => new URL(segment, url), - new URL("http://localhost:3000/packages/astro/components/Markdown.astro") - ).pathname - }, -}; -const Astro = __TopLevelAstro; - -export interface Props { - content?: string; -} - -// Internal props that should not be part of the external interface. -interface InternalProps extends Props { - $scope: string; -} - const { content, $scope } = Astro.props as InternalProps; let html = null; - - - -// `__render()`: Render the contents of the Astro module. -import { h, Fragment } from 'astro/runtime/h.js'; -const __astroInternal = Symbol('astro.internal'); -const __astroContext = Symbol.for('astro.context'); -async function __render(props, ...children) { - const Astro = Object.create(__TopLevelAstro, { - props: { - value: props, - enumerable: true - }, - pageCSS: { - value: (props[__astroContext] && props[__astroContext].pageCSS) || [], - enumerable: true - }, - isPage: { - value: (props[__astroInternal] && props[__astroInternal].isPage) || false, - enumerable: true - }, - request: { - value: (props[__astroContext] && props[__astroContext].request) || {}, - enumerable: true - }, - }); - - const { - content, - $scope -} = Astro.props; -let html = null; - // This flow is only triggered if a user passes `` if (content) { const { content: htmlContent } = await renderMarkdown(content, { diff --git a/packages/astro/components/Prism.astro b/packages/astro/components/Prism.astro index 5942a0428..ba4b22ec3 100644 --- a/packages/astro/components/Prism.astro +++ b/packages/astro/components/Prism.astro @@ -1,12 +1,7 @@ - -import fetch from 'node-fetch'; -import loadLanguages from 'prismjs/components/index.js'; -import { addAstro } from '@astrojs/prism'; +--- import Prism from 'prismjs'; - -if(!('fetch' in globalThis)) { - globalThis.fetch = fetch; -} +import { addAstro } from '@astrojs/prism'; +import loadLanguages from 'prismjs/components/index.js'; export interface Props { class?: string; @@ -18,128 +13,40 @@ const { class: className, lang, code } = Astro.props as Props; let classLanguage = `language-${lang}` -const __TopLevelAstro = { - site: new URL("http://localhost:3000"), - fetchContent: (globResult) => fetchContent(globResult, import.meta.url), - resolve(...segments) { - return segments.reduce( - (url, segment) => new URL(segment, url), - new URL("http://localhost:3000/packages/astro/components/Prism.astro") - ).pathname - }, -}; -const Astro = __TopLevelAstro; +const languageMap = new Map([ + ['ts', 'typescript'] +]); - - - - -// `__render()`: Render the contents of the Astro module. -import { h, Fragment } from 'astro/runtime/h.js'; -const __astroInternal = Symbol('astro.internal'); -const __astroContext = Symbol.for('astro.context'); -async function __render(props, ...children) { - const Astro = Object.create(__TopLevelAstro, { - props: { - value: props, - enumerable: true - }, - pageCSS: { - value: (props[__astroContext] && props[__astroContext].pageCSS) || [], - enumerable: true - }, - isPage: { - value: (props[__astroInternal] && props[__astroInternal].isPage) || false, - enumerable: true - }, - request: { - value: (props[__astroContext] && props[__astroContext].request) || {}, - enumerable: true - }, - }); - - const { - class: className, - lang, - code -} = Astro.props; -let classLanguage = `language-${lang}`; -const languageMap = new Map([["ts", "typescript"]]); if (lang == null) { - console.warn("Prism.astro: No language provided."); + console.warn('Prism.astro: No language provided.'); } -const ensureLoaded = (lang2) => { - if (lang2 && !Prism.languages[lang2]) { - loadLanguages([lang2]); + +const ensureLoaded = lang => { + if(lang && !Prism.languages[lang]) { + loadLanguages([lang]); } }; -if (languageMap.has(lang)) { + +if(languageMap.has(lang)) { ensureLoaded(languageMap.get(lang)); -} else if (lang === "astro") { - ensureLoaded("typescript"); +} else if(lang === 'astro') { + ensureLoaded('typescript'); addAstro(Prism); } else { - ensureLoaded("markup-templating"); + ensureLoaded('markup-templating'); // Prism expects this to exist for a number of other langs ensureLoaded(lang); } -if (lang && !Prism.languages[lang]) { + +if(lang && !Prism.languages[lang]) { console.warn(`Unable to load the language: ${lang}`); } + const grammar = Prism.languages[lang]; let html = code; if (grammar) { html = Prism.highlight(code, grammar, lang); } - return h(Fragment, null, h(Fragment, null,h("pre", {"class":([className, classLanguage].join(" ")),[__astroContext]:props[__astroContext]},h("code", {"class":(classLanguage),[__astroContext]:props[__astroContext]},(html))))); -} -export default { isAstroComponent: true, __render }; - -// `__renderPage()`: Render the contents of the Astro module as a page. This is a special flow, -// triggered by loading a component directly by URL. -export async function __renderPage({request, children, props, css}) { - const currentChild = { - isAstroComponent: true, - layout: typeof __layout === 'undefined' ? undefined : __layout, - content: typeof __content === 'undefined' ? undefined : __content, - __render, - }; - - const isLayout = (__astroContext in props); - if(!isLayout) { - let astroRootUIDCounter = 0; - Object.defineProperty(props, __astroContext, { - value: { - pageCSS: css, - request, - createAstroRootUID(seed) { return seed + astroRootUIDCounter++; }, - }, - writable: false, - enumerable: false - }); - } - - Object.defineProperty(props, __astroInternal, { - value: { - isPage: !isLayout - }, - writable: false, - enumerable: false - }); - - const childBodyResult = await currentChild.__render(props, children); - - // find layout, if one was given. - if (currentChild.layout) { - return currentChild.layout({ - request, - props: {content: currentChild.content, [__astroContext]: props[__astroContext]}, - children: [childBodyResult], - }); - } - - return childBodyResult; -}; - - +--- +
{html}
diff --git a/packages/astro/components/index.js b/packages/astro/components/index.js index 8b19c7d1f..0af9e396b 100644 --- a/packages/astro/components/index.js +++ b/packages/astro/components/index.js @@ -1,4 +1,17 @@ -export { default as Code } from './Code.astro'; -export { default as Debug } from './Debug.astro'; -export { default as Markdown } from './Markdown.astro'; -export { default as Prism } from './Prism.astro'; +// export { default as Code } from './Code.astro'; +// export { default as Debug } from './Debug.astro'; +// export { default as Markdown } from './Markdown.astro'; +// export { default as Prism } from './Prism.astro'; + +export const Code = () => { + throw new Error(`Cannot render . "astro/components" are still WIP!`) +} +export const Debug = () => { + throw new Error(`Cannot render . "astro/components" are still WIP!`) +} +export const Markdown = () => { + throw new Error(`Cannot render . "astro/components" are still WIP!`) +} +export const Prism = () => { + throw new Error(`Cannot render . "astro/components" are still WIP!`) +} diff --git a/packages/astro/package.json b/packages/astro/package.json index b1efc9918..ab8872eff 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -73,6 +73,7 @@ "string-width": "^5.0.0", "strip-ansi": "^7.0.1", "supports-esm": "^1.0.0", + "tiny-glob": "^0.2.8", "vite": "^2.5.7", "yargs-parser": "^20.2.9", "zod": "^3.8.1" diff --git a/packages/astro/src/runtime/ssr.ts b/packages/astro/src/runtime/ssr.ts index f6dd1058f..02ea2c5a2 100644 --- a/packages/astro/src/runtime/ssr.ts +++ b/packages/astro/src/runtime/ssr.ts @@ -10,7 +10,7 @@ import { fileURLToPath } from 'url'; import fs from 'fs'; import path from 'path'; import { renderPage } from './astro.js'; -import { fdir } from 'fdir'; +import glob from 'tiny-glob'; import { generatePaginateFunction } from './paginate.js'; import { getParams, validateGetStaticPathsModule, validateGetStaticPathsResult } from './routing.js'; import { parseNpmName, canonicalURL as getCanonicalURL, codeFrame } from './util.js'; @@ -176,7 +176,7 @@ export async function ssr({ astroConfig, filePath, logging, mode, origin, pathna const Component = await mod.default; const ext = path.posix.extname(filePath.pathname); if (!Component) - throw new Error(`Expected an exported Astro component but recieved typeof ${typeof Component}`); + throw new Error(`Expected an exported Astro component but received typeof ${typeof Component}`); if (!Component.isAstroComponentFactory) throw new Error(`Unable to SSR non-Astro component (${route?.component})`); @@ -201,24 +201,19 @@ export async function ssr({ astroConfig, filePath, logging, mode, origin, pathna } const createFetchContent = (currentFilePath: string) => { + const fetchContentCache = new Map(); return async (pattern: string) => { const cwd = path.dirname(currentFilePath); - const crawler = new fdir().glob(pattern); - const files = await crawler.crawlWithOptions(cwd, { - resolvePaths: true, - includeBasePath: true, - filters: [(p) => p !== currentFilePath] - }).withPromise() as PathsOutput; - + const cacheKey = `${cwd}:${pattern}`; + if (fetchContentCache.has(cacheKey)) { + return fetchContentCache.get(cacheKey); + } + const files = await glob(pattern, { cwd, absolute: true }); const contents = await Promise.all(files.map(async file => { - const { default: ChildComponent } = (await viteServer.ssrLoadModule(file)) as ComponentInstance; - return renderPage({ - ...result, - createAstro: (props: any) => { - return { props } - }, - }, ChildComponent, {}, null); + const { metadata: astro = {}, frontmatter = {} } = (await viteServer.ssrLoadModule(file)) as any; + return { ...frontmatter, astro }; })) + fetchContentCache.set(cacheKey, contents); return contents; } }