Throw Error for WIP Features

This commit is contained in:
Nate Moore 2021-09-21 17:04:25 +00:00 committed by Matthew Phillips
parent 3c1fcc237d
commit cf2e3b31cb
5 changed files with 50 additions and 209 deletions

View file

@ -10,84 +10,9 @@ interface InternalProps extends Props {
$scope: string; $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; const { content, $scope } = Astro.props as InternalProps;
let html = null; 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 `<Markdown content={content} />` // This flow is only triggered if a user passes `<Markdown content={content} />`
if (content) { if (content) {
const { content: htmlContent } = await renderMarkdown(content, { const { content: htmlContent } = await renderMarkdown(content, {

View file

@ -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'; import Prism from 'prismjs';
import { addAstro } from '@astrojs/prism';
if(!('fetch' in globalThis)) { import loadLanguages from 'prismjs/components/index.js';
globalThis.fetch = fetch;
}
export interface Props { export interface Props {
class?: string; class?: string;
@ -18,128 +13,40 @@ const { class: className, lang, code } = Astro.props as Props;
let classLanguage = `language-${lang}` let classLanguage = `language-${lang}`
const __TopLevelAstro = { const languageMap = new Map([
site: new URL("http://localhost:3000"), ['ts', 'typescript']
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;
// `__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) { 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]) { const ensureLoaded = lang => {
loadLanguages([lang2]); if(lang && !Prism.languages[lang]) {
loadLanguages([lang]);
} }
}; };
if (languageMap.has(lang)) {
if(languageMap.has(lang)) {
ensureLoaded(languageMap.get(lang)); ensureLoaded(languageMap.get(lang));
} else if (lang === "astro") { } else if(lang === 'astro') {
ensureLoaded("typescript"); ensureLoaded('typescript');
addAstro(Prism); addAstro(Prism);
} else { } else {
ensureLoaded("markup-templating"); ensureLoaded('markup-templating'); // Prism expects this to exist for a number of other langs
ensureLoaded(lang); ensureLoaded(lang);
} }
if (lang && !Prism.languages[lang]) {
if(lang && !Prism.languages[lang]) {
console.warn(`Unable to load the language: ${lang}`); console.warn(`Unable to load the language: ${lang}`);
} }
const grammar = Prism.languages[lang]; const grammar = Prism.languages[lang];
let html = code; let html = code;
if (grammar) { if (grammar) {
html = Prism.highlight(code, grammar, lang); 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;
};
<pre class={[className, classLanguage].join(' ')}><code class={classLanguage}>{html}</code></pre>

View file

@ -1,4 +1,17 @@
export { default as Code } from './Code.astro'; // export { default as Code } from './Code.astro';
export { default as Debug } from './Debug.astro'; // export { default as Debug } from './Debug.astro';
export { default as Markdown } from './Markdown.astro'; // export { default as Markdown } from './Markdown.astro';
export { default as Prism } from './Prism.astro'; // export { default as Prism } from './Prism.astro';
export const Code = () => {
throw new Error(`Cannot render <Code />. "astro/components" are still WIP!`)
}
export const Debug = () => {
throw new Error(`Cannot render <Debug />. "astro/components" are still WIP!`)
}
export const Markdown = () => {
throw new Error(`Cannot render <Markdown />. "astro/components" are still WIP!`)
}
export const Prism = () => {
throw new Error(`Cannot render <Prism />. "astro/components" are still WIP!`)
}

View file

@ -73,6 +73,7 @@
"string-width": "^5.0.0", "string-width": "^5.0.0",
"strip-ansi": "^7.0.1", "strip-ansi": "^7.0.1",
"supports-esm": "^1.0.0", "supports-esm": "^1.0.0",
"tiny-glob": "^0.2.8",
"vite": "^2.5.7", "vite": "^2.5.7",
"yargs-parser": "^20.2.9", "yargs-parser": "^20.2.9",
"zod": "^3.8.1" "zod": "^3.8.1"

View file

@ -10,7 +10,7 @@ import { fileURLToPath } from 'url';
import fs from 'fs'; import fs from 'fs';
import path from 'path'; import path from 'path';
import { renderPage } from './astro.js'; import { renderPage } from './astro.js';
import { fdir } from 'fdir'; import glob from 'tiny-glob';
import { generatePaginateFunction } from './paginate.js'; import { generatePaginateFunction } from './paginate.js';
import { getParams, validateGetStaticPathsModule, validateGetStaticPathsResult } from './routing.js'; import { getParams, validateGetStaticPathsModule, validateGetStaticPathsResult } from './routing.js';
import { parseNpmName, canonicalURL as getCanonicalURL, codeFrame } from './util.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 Component = await mod.default;
const ext = path.posix.extname(filePath.pathname); const ext = path.posix.extname(filePath.pathname);
if (!Component) 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})`); 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 createFetchContent = (currentFilePath: string) => {
const fetchContentCache = new Map<string, any>();
return async (pattern: string) => { return async (pattern: string) => {
const cwd = path.dirname(currentFilePath); const cwd = path.dirname(currentFilePath);
const crawler = new fdir().glob(pattern); const cacheKey = `${cwd}:${pattern}`;
const files = await crawler.crawlWithOptions(cwd, { if (fetchContentCache.has(cacheKey)) {
resolvePaths: true, return fetchContentCache.get(cacheKey);
includeBasePath: true, }
filters: [(p) => p !== currentFilePath] const files = await glob(pattern, { cwd, absolute: true });
}).withPromise() as PathsOutput;
const contents = await Promise.all(files.map(async file => { const contents = await Promise.all(files.map(async file => {
const { default: ChildComponent } = (await viteServer.ssrLoadModule(file)) as ComponentInstance; const { metadata: astro = {}, frontmatter = {} } = (await viteServer.ssrLoadModule(file)) as any;
return renderPage({ return { ...frontmatter, astro };
...result,
createAstro: (props: any) => {
return { props }
},
}, ChildComponent, {}, null);
})) }))
fetchContentCache.set(cacheKey, contents);
return contents; return contents;
} }
} }