import React from 'react'; import ReactDOM from 'react-dom/server'; import StaticHtml from './static-html.js'; const slotName = (str) => str.trim().replace(/[-_]([a-z])/g, (_, w) => w.toUpperCase()); const reactTypeof = Symbol.for('react.element'); function errorIsComingFromPreactComponent(err) { return ( err.message && (err.message.startsWith("Cannot read property '__H'") || err.message.includes("(reading '__H')")) ); } async function check(Component, props, children) { // Note: there are packages that do some unholy things to create "components". // Checking the $$typeof property catches most of these patterns. if (typeof Component === 'object') { const $$typeof = Component['$$typeof']; return $$typeof && $$typeof.toString().slice('Symbol('.length).startsWith('react'); } if (typeof Component !== 'function') return false; if (Component.prototype != null && typeof Component.prototype.render === 'function') { return React.Component.isPrototypeOf(Component) || React.PureComponent.isPrototypeOf(Component); } let error = null; let isReactComponent = false; function Tester(...args) { try { const vnode = Component(...args); if (vnode && vnode['$$typeof'] === reactTypeof) { isReactComponent = true; } } catch (err) { if (!errorIsComingFromPreactComponent(err)) { error = err; } } return React.createElement('div'); } await renderToStaticMarkup(Tester, props, children, {}); if (error) { throw error; } return isReactComponent; } async function getNodeWritable() { let nodeStreamBuiltinModuleName = 'stream'; let { Writable } = await import(/* @vite-ignore */ nodeStreamBuiltinModuleName); return Writable; } async function renderToStaticMarkup(Component, props, { default: children, ...slotted }, metadata) { delete props['class']; const slots = {}; for (const [key, value] of Object.entries(slotted)) { const name = slotName(key); slots[name] = React.createElement(StaticHtml, { value, name }); } // Note: create newProps to avoid mutating `props` before they are serialized const newProps = { ...props, ...slots, }; if (children != null) { newProps.children = React.createElement(StaticHtml, { value: children }); } const vnode = React.createElement(Component, newProps); let html; if (metadata && metadata.hydrate) { html = ReactDOM.renderToString(vnode); if ('renderToReadableStream' in ReactDOM) { html = await renderToReadableStreamAsync(vnode); } else { html = await renderToPipeableStreamAsync(vnode); } } else { if ('renderToReadableStream' in ReactDOM) { html = await renderToReadableStreamAsync(vnode); } else { html = await renderToStaticNodeStreamAsync(vnode); } } return { html }; } async function renderToPipeableStreamAsync(vnode) { const Writable = await getNodeWritable(); let html = ''; return new Promise((resolve, reject) => { let error = undefined; let stream = ReactDOM.renderToPipeableStream(vnode, { onError(err) { error = err; reject(error); }, onAllReady() { stream.pipe( new Writable({ write(chunk, _encoding, callback) { html += chunk.toString('utf-8'); callback(); }, destroy() { resolve(html); }, }) ); }, }); }); } async function renderToStaticNodeStreamAsync(vnode) { const Writable = await getNodeWritable(); let html = ''; return new Promise((resolve, reject) => { let stream = ReactDOM.renderToStaticNodeStream(vnode); stream.on('error', err => { reject(err); }); stream.pipe( new Writable({ write(chunk, _encoding, callback) { html += chunk.toString('utf-8'); callback(); }, destroy() { resolve(html); }, }) ); }); } /** * Use a while loop instead of "for await" due to cloudflare and Vercel Edge issues * See https://github.com/facebook/react/issues/24169 */ async function readResult(stream) { const reader = stream.getReader(); let result = ''; const decoder = new TextDecoder('utf-8'); while (true) { const { done, value } = await reader.read(); if (done) { if (value) { result += decoder.decode(value); } else { // This closes the decoder decoder.decode(new Uint8Array()); } return result; } result += decoder.decode(value, { stream: true }); } } async function renderToReadableStreamAsync(vnode) { return await readResult(await ReactDOM.renderToReadableStream(vnode)); } export default { check, renderToStaticMarkup, }; folio Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/packages/create-astro/src/components/Finalize.tsx (unfollow)
AgeCommit message (Expand)AuthorFilesLines
2021-09-14fix bad ci pathsGravatar Fred K. Schott 1-5/+5
2021-09-14update changesetsGravatar Fred K. Schott 1-1/+1
2021-09-14Fix passing Markdown content through props (#1259) (#1343)Gravatar kelvinsjk 4-0/+22
2021-09-14Improve stats logging to use `pretty-bytes` so that 20B doesn't get output as...Gravatar Caleb Jasik 4-2/+13
2021-09-14[ci] yarn formatGravatar FredKSchott 1-1/+1
2021-09-14Merge "Remove check for referenced files" (#1196)Gravatar (none) 6-6/+45
2021-09-14Docs: Add READMEs for renderers (#1351)Gravatar Drew Powers 8-1/+184
2021-09-14Update deployment docs for Netlify deployment (#1361)Gravatar Cassidy Williams 1-7/+9
2021-09-14Delete perfect-kids-occur.md (#1372)Gravatar Fred K. Schott 1-5/+0
2021-09-14[ci] yarn formatGravatar FredKSchott 1-15/+10
2021-09-14Self-host homepage fonts to improve page load speed (#1370)Gravatar mundry 14-5/+52
2021-09-14Add types to examples and docs (#1347)Gravatar Matthew Phillips 8-20/+60
2021-09-14[ci] collect statsGravatar FredKSchott 1-0/+1
2021-09-13Fix typo (#1360)Gravatar Marcus Otterström 1-1/+1
2021-09-13Disclaimer for Github pages / jekyll quirk (#1355)Gravatar Tc001 2-0/+7
2021-09-13fix outdated lockfile issue (#1357)Gravatar Fred K. Schott 1-3/+1
2021-09-13Add `astro.build/play` link (#1359)Gravatar Nate Moore 1-0/+6
2021-09-13[ci] yarn formatGravatar FredKSchott 2-8/+7
2021-09-13Add a new lockfile (#1356)Gravatar Matthew Phillips 1-19/+19
2021-09-13[ci] collect statsGravatar FredKSchott 1-0/+1
2021-09-12[ci] collect statsGravatar FredKSchott 1-0/+1
2021-09-11[ci] collect statsGravatar FredKSchott 1-0/+1
2021-09-10Prevent removing CSS preloads during bundling (#1326)Gravatar Bartek Igielski 8-18/+96
2021-09-10Fix typos in Netlify sponsorship announcement blog post (#1346)Gravatar mundry 1-4/+4
2021-09-10[ci] collect statsGravatar FredKSchott 2-1/+2
2021-09-09blog: announce netlify sponsorship (#1345)Gravatar Fred K. Schott 4-5/+64
2021-09-09Version Packages (#1344)Gravatar github-actions[bot] 29-53/+42
2021-09-09Revert "Version Packages (#1303)"Gravatar Fred K. Schott 29-42/+53
2021-09-09update lockfileastro@0.20.5@astrojs/markdown-support@0.3.1Gravatar Fred K. Schott 1-9/+9
2021-09-09Version Packages (#1303)Gravatar github-actions[bot] 29-53/+42
2021-09-09[ci] collect statsGravatar FredKSchott 2-1/+2
2021-09-08Update netlify deploy instructions for `.nvmrc` syntax (#1337)Gravatar Caleb Jasik 1-1/+1
2021-09-08[ci] yarn formatGravatar jasikpark 1-1/+0