Support children inside of components (#72)
* chore(examples): add kitchen-sink * feat: support children in rendered components * feat: add support for rendering children in Svelte * fix: cleanup p/react fragment children * chore: add @ts-nocheck to svelte files * chore: update lockfiles * fix: types * feat: memoize frontend/renderer/utils * fix: disable eslint for compiled SvelteWrapper * fix: add missing dep Co-authored-by: Nate Moore <nate@skypack.dev>
This commit is contained in:
parent
ea33d7b2ab
commit
22ca9e0aac
24 changed files with 6444 additions and 286 deletions
6
examples/kitchen-sink/astro.config.mjs
Normal file
6
examples/kitchen-sink/astro.config.mjs
Normal file
|
@ -0,0 +1,6 @@
|
|||
export default {
|
||||
extensions: {
|
||||
'.jsx': 'react',
|
||||
'.tsx': 'preact',
|
||||
}
|
||||
};
|
20
examples/kitchen-sink/astro/components/PreactCounter.tsx
Normal file
20
examples/kitchen-sink/astro/components/PreactCounter.tsx
Normal file
|
@ -0,0 +1,20 @@
|
|||
import { h, Fragment } from 'preact';
|
||||
import { useState } from 'preact/hooks';
|
||||
|
||||
/** a counter written in Preact */
|
||||
export default function PreactCounter({ children }) {
|
||||
const [count, setCount] = useState(0)
|
||||
const add = () => setCount(i => i + 1);
|
||||
const subtract = () => setCount(i => i - 1);
|
||||
|
||||
return <>
|
||||
<div className="counter">
|
||||
<button onClick={subtract}>-</button>
|
||||
<pre>{count}</pre>
|
||||
<button onClick={add}>+</button>
|
||||
</div>
|
||||
<div className="children">
|
||||
{children}
|
||||
</div>
|
||||
</>
|
||||
}
|
19
examples/kitchen-sink/astro/components/ReactCounter.jsx
Normal file
19
examples/kitchen-sink/astro/components/ReactCounter.jsx
Normal file
|
@ -0,0 +1,19 @@
|
|||
import React, { useState } from 'react';
|
||||
|
||||
/** a counter written in React */
|
||||
export default function ReactCounter({ children }) {
|
||||
const [count, setCount] = useState(0)
|
||||
const add = () => setCount(i => i + 1);
|
||||
const subtract = () => setCount(i => i - 1);
|
||||
|
||||
return <>
|
||||
<div className="counter">
|
||||
<button onClick={subtract}>-</button>
|
||||
<pre>{count}</pre>
|
||||
<button onClick={add}>+</button>
|
||||
</div>
|
||||
<div className="children">
|
||||
{children}
|
||||
</div>
|
||||
</>
|
||||
}
|
22
examples/kitchen-sink/astro/components/SvelteCounter.svelte
Normal file
22
examples/kitchen-sink/astro/components/SvelteCounter.svelte
Normal file
|
@ -0,0 +1,22 @@
|
|||
|
||||
<script>
|
||||
let children;
|
||||
let count = 0;
|
||||
|
||||
function add() {
|
||||
count += 1;
|
||||
}
|
||||
|
||||
function subtract() {
|
||||
count -= 1;
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="counter">
|
||||
<button on:click={subtract}>-</button>
|
||||
<pre>{ count }</pre>
|
||||
<button on:click={add}>+</button>
|
||||
</div>
|
||||
<div class="children">
|
||||
<slot />
|
||||
</div>
|
27
examples/kitchen-sink/astro/components/VueCounter.vue
Normal file
27
examples/kitchen-sink/astro/components/VueCounter.vue
Normal file
|
@ -0,0 +1,27 @@
|
|||
<template>
|
||||
<div class="counter">
|
||||
<button @click="subtract()">-</button>
|
||||
<pre>{{ count }}</pre>
|
||||
<button @click="add()">+</button>
|
||||
</div>
|
||||
<div class="children">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref } from 'vue';
|
||||
export default {
|
||||
setup() {
|
||||
const count = ref(0)
|
||||
const add = () => count.value = count.value + 1;
|
||||
const subtract = () => count.value = count.value - 1;
|
||||
|
||||
return {
|
||||
count,
|
||||
add,
|
||||
subtract
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
51
examples/kitchen-sink/astro/pages/index.astro
Normal file
51
examples/kitchen-sink/astro/pages/index.astro
Normal file
|
@ -0,0 +1,51 @@
|
|||
---
|
||||
import ReactCounter from '../components/ReactCounter.jsx';
|
||||
import PreactCounter from '../components/PreactCounter.tsx';
|
||||
import VueCounter from '../components/VueCounter.vue';
|
||||
import SvelteCounter from '../components/SvelteCounter.svelte';
|
||||
---
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
||||
<style>
|
||||
:global(:root) {
|
||||
font-family: system-ui;
|
||||
padding: 2em 0;
|
||||
}
|
||||
:global(.counter) {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
place-items: center;
|
||||
font-size: 2em;
|
||||
margin-top: 2em;
|
||||
}
|
||||
:global(.children) {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<ReactCounter:load>
|
||||
<h1>Hello React!</h1>
|
||||
<p>What's up?</p>
|
||||
</ReactCounter:load>
|
||||
|
||||
<PreactCounter:load>
|
||||
<h1>Hello Preact!</h1>
|
||||
</PreactCounter:load>
|
||||
|
||||
<VueCounter:load>
|
||||
<h1>Hello Vue!</h1>
|
||||
</VueCounter:load>
|
||||
|
||||
<SvelteCounter:load>
|
||||
<h1>Hello Svelte!</h1>
|
||||
</SvelteCounter:load>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
5408
examples/kitchen-sink/package-lock.json
generated
Normal file
5408
examples/kitchen-sink/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
14
examples/kitchen-sink/package.json
Normal file
14
examples/kitchen-sink/package.json
Normal file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"name": "kitchen-sink",
|
||||
"private": true,
|
||||
"version": "1.0.0",
|
||||
"scripts": {
|
||||
"start": "nodemon -w ../../lib -x 'astro dev .'",
|
||||
"build": "astro build"
|
||||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"astro": "file:../../",
|
||||
"nodemon": "^2.0.7"
|
||||
}
|
||||
}
|
573
examples/snowpack/package-lock.json
generated
573
examples/snowpack/package-lock.json
generated
File diff suppressed because it is too large
Load diff
230
package-lock.json
generated
230
package-lock.json
generated
|
@ -295,6 +295,14 @@
|
|||
"integrity": "sha512-J/rMZa7RqiH/rT29TEVZO4nBoDP9XJOjnbbIofg7GQKs4JIduEO3WLpte+6WeUz/TcrXKlY+bM7FYrp8yFB+3g==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/hast": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.1.tgz",
|
||||
"integrity": "sha512-viwwrB+6xGzw+G1eWpF9geV3fnsDgXqHG+cqgiHrvQfDUW5hzhCyV7Sy3UJxhfRFBsgky2SSW33qi/YrIkjX5Q==",
|
||||
"requires": {
|
||||
"@types/unist": "*"
|
||||
}
|
||||
},
|
||||
"@types/json-schema": {
|
||||
"version": "7.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz",
|
||||
|
@ -312,6 +320,11 @@
|
|||
"integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/parse5": {
|
||||
"version": "5.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-5.0.3.tgz",
|
||||
"integrity": "sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw=="
|
||||
},
|
||||
"@types/prop-types": {
|
||||
"version": "15.7.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz",
|
||||
|
@ -532,32 +545,6 @@
|
|||
"source-map": "^0.6.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vue/compiler-core": {
|
||||
"version": "3.0.11",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.0.11.tgz",
|
||||
"integrity": "sha512-6sFj6TBac1y2cWCvYCA8YzHJEbsVkX7zdRs/3yK/n1ilvRqcn983XvpBbnN3v4mZ1UiQycTvOiajJmOgN9EVgw==",
|
||||
"requires": {
|
||||
"@babel/parser": "^7.12.0",
|
||||
"@babel/types": "^7.12.0",
|
||||
"@vue/shared": "3.0.11",
|
||||
"estree-walker": "^2.0.1",
|
||||
"source-map": "^0.6.1"
|
||||
}
|
||||
},
|
||||
"@vue/compiler-dom": {
|
||||
"version": "3.0.11",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.0.11.tgz",
|
||||
"integrity": "sha512-+3xB50uGeY5Fv9eMKVJs2WSRULfgwaTJsy23OIltKgMrynnIj8hTYY2UL97HCoz78aDw1VDXdrBQ4qepWjnQcw==",
|
||||
"requires": {
|
||||
"@vue/compiler-core": "3.0.11",
|
||||
"@vue/shared": "3.0.11"
|
||||
}
|
||||
},
|
||||
"@vue/shared": {
|
||||
"version": "3.0.11",
|
||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.0.11.tgz",
|
||||
"integrity": "sha512-b+zB8A2so8eCE0JsxjL24J7vdGl8rzPQ09hZNhystm+KqSbKcAej1A+Hbva1rCMmTTqA+hFnUSDc5kouEo0JzA=="
|
||||
},
|
||||
"estree-walker": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
|
||||
|
@ -741,6 +728,11 @@
|
|||
"postcss-value-parser": "^4.1.0"
|
||||
}
|
||||
},
|
||||
"bail": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz",
|
||||
"integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ=="
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||
|
@ -946,6 +938,11 @@
|
|||
"resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz",
|
||||
"integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w=="
|
||||
},
|
||||
"comma-separated-tokens": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz",
|
||||
"integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw=="
|
||||
},
|
||||
"commander": {
|
||||
"version": "2.20.3",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
||||
|
@ -1505,6 +1502,11 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"extend": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
||||
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
|
||||
},
|
||||
"extend-shallow": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
|
||||
|
@ -1525,6 +1527,11 @@
|
|||
"integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==",
|
||||
"dev": true
|
||||
},
|
||||
"fast-equals": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-2.0.0.tgz",
|
||||
"integrity": "sha512-u6RBd8cSiLLxAiC04wVsLV6GBFDOXcTCgWkd3wEoFXgidPSoAJENqC9m7Jb2vewSvjBIfXV6icKeh3GTKfIaXA=="
|
||||
},
|
||||
"fast-glob": {
|
||||
"version": "3.2.5",
|
||||
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz",
|
||||
|
@ -1703,6 +1710,11 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"globalyzer": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz",
|
||||
"integrity": "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q=="
|
||||
},
|
||||
"globby": {
|
||||
"version": "11.0.2",
|
||||
"resolved": "https://registry.npmjs.org/globby/-/globby-11.0.2.tgz",
|
||||
|
@ -1717,6 +1729,11 @@
|
|||
"slash": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"globrex": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz",
|
||||
"integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg=="
|
||||
},
|
||||
"good-listener": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz",
|
||||
|
@ -1755,6 +1772,50 @@
|
|||
"resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-2.0.0.tgz",
|
||||
"integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg=="
|
||||
},
|
||||
"hast-to-hyperscript": {
|
||||
"version": "9.0.1",
|
||||
"resolved": "https://registry.npmjs.org/hast-to-hyperscript/-/hast-to-hyperscript-9.0.1.tgz",
|
||||
"integrity": "sha512-zQgLKqF+O2F72S1aa4y2ivxzSlko3MAvxkwG8ehGmNiqd98BIN3JM1rAJPmplEyLmGLO2QZYJtIneOSZ2YbJuA==",
|
||||
"requires": {
|
||||
"@types/unist": "^2.0.3",
|
||||
"comma-separated-tokens": "^1.0.0",
|
||||
"property-information": "^5.3.0",
|
||||
"space-separated-tokens": "^1.0.0",
|
||||
"style-to-object": "^0.3.0",
|
||||
"unist-util-is": "^4.0.0",
|
||||
"web-namespaces": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"hast-util-from-parse5": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-6.0.1.tgz",
|
||||
"integrity": "sha512-jeJUWiN5pSxW12Rh01smtVkZgZr33wBokLzKLwinYOUfSzm1Nl/c3GUGebDyOKjdsRgMvoVbV0VpAcpjF4NrJA==",
|
||||
"requires": {
|
||||
"@types/parse5": "^5.0.0",
|
||||
"hastscript": "^6.0.0",
|
||||
"property-information": "^5.0.0",
|
||||
"vfile": "^4.0.0",
|
||||
"vfile-location": "^3.2.0",
|
||||
"web-namespaces": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"hast-util-parse-selector": {
|
||||
"version": "2.2.5",
|
||||
"resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz",
|
||||
"integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ=="
|
||||
},
|
||||
"hastscript": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz",
|
||||
"integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==",
|
||||
"requires": {
|
||||
"@types/hast": "^2.0.0",
|
||||
"comma-separated-tokens": "^1.0.0",
|
||||
"hast-util-parse-selector": "^2.0.0",
|
||||
"property-information": "^5.0.0",
|
||||
"space-separated-tokens": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"hosted-git-info": {
|
||||
"version": "2.8.8",
|
||||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz",
|
||||
|
@ -1862,6 +1923,11 @@
|
|||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||
"dev": true
|
||||
},
|
||||
"inline-style-parser": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz",
|
||||
"integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q=="
|
||||
},
|
||||
"is-alphabetical": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz",
|
||||
|
@ -1890,6 +1956,11 @@
|
|||
"binary-extensions": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"is-buffer": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz",
|
||||
"integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ=="
|
||||
},
|
||||
"is-core-module": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz",
|
||||
|
@ -1942,6 +2013,11 @@
|
|||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="
|
||||
},
|
||||
"is-plain-obj": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
|
||||
"integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA=="
|
||||
},
|
||||
"is-stream": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
|
||||
|
@ -2133,6 +2209,11 @@
|
|||
"integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
|
||||
"dev": true
|
||||
},
|
||||
"micro-memoize": {
|
||||
"version": "4.0.9",
|
||||
"resolved": "https://registry.npmjs.org/micro-memoize/-/micro-memoize-4.0.9.tgz",
|
||||
"integrity": "sha512-Z2uZi/IUMGQDCXASdujXRqrXXEwSY0XffUrAOllhqzQI3wpUyZbiZTiE2JuYC0HSG2G7DbCS5jZmsEKEGZuemg=="
|
||||
},
|
||||
"micromark": {
|
||||
"version": "2.11.4",
|
||||
"resolved": "https://registry.npmjs.org/micromark/-/micromark-2.11.4.tgz",
|
||||
|
@ -2246,6 +2327,15 @@
|
|||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
|
||||
},
|
||||
"moize": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/moize/-/moize-6.0.1.tgz",
|
||||
"integrity": "sha512-Bl91P98A6Xba35mn9XoAW9DuGoQb3HyoY888TxrvQbMr9+1v3dzBzi9n4Guh5Lne8ENdqbXjQ0a8mf7UUvZ9wg==",
|
||||
"requires": {
|
||||
"fast-equals": "2.0.0",
|
||||
"micro-memoize": "4.0.9"
|
||||
}
|
||||
},
|
||||
"mri": {
|
||||
"version": "1.1.6",
|
||||
"resolved": "https://registry.npmjs.org/mri/-/mri-1.1.6.tgz",
|
||||
|
@ -2657,6 +2747,14 @@
|
|||
"integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
|
||||
"dev": true
|
||||
},
|
||||
"property-information": {
|
||||
"version": "5.6.0",
|
||||
"resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz",
|
||||
"integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==",
|
||||
"requires": {
|
||||
"xtend": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"punycode": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
|
||||
|
@ -2730,6 +2828,15 @@
|
|||
"integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==",
|
||||
"dev": true
|
||||
},
|
||||
"rehype-parse": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-7.0.1.tgz",
|
||||
"integrity": "sha512-fOiR9a9xH+Le19i4fGzIEowAbwG7idy2Jzs4mOrFWBSJ0sNUgy0ev871dwWnbOo371SjgjG4pwzrbgSVrKxecw==",
|
||||
"requires": {
|
||||
"hast-util-from-parse5": "^6.0.0",
|
||||
"parse5": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"require-directory": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
||||
|
@ -2975,6 +3082,11 @@
|
|||
"resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
|
||||
"integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA=="
|
||||
},
|
||||
"space-separated-tokens": {
|
||||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz",
|
||||
"integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA=="
|
||||
},
|
||||
"spawn-command": {
|
||||
"version": "0.0.2-1",
|
||||
"resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz",
|
||||
|
@ -3069,6 +3181,14 @@
|
|||
"min-indent": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"style-to-object": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.3.0.tgz",
|
||||
"integrity": "sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA==",
|
||||
"requires": {
|
||||
"inline-style-parser": "0.1.1"
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||
|
@ -3159,6 +3279,15 @@
|
|||
"integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==",
|
||||
"optional": true
|
||||
},
|
||||
"tiny-glob": {
|
||||
"version": "0.2.8",
|
||||
"resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.8.tgz",
|
||||
"integrity": "sha512-vkQP7qOslq63XRX9kMswlby99kyO5OvKptw7AMwBVMjXEI7Tb61eoI5DydyEMOseyGS5anDN1VPoVxEvH01q8w==",
|
||||
"requires": {
|
||||
"globalyzer": "0.1.0",
|
||||
"globrex": "^0.1.2"
|
||||
}
|
||||
},
|
||||
"to-fast-properties": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
|
||||
|
@ -3184,6 +3313,11 @@
|
|||
"integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==",
|
||||
"dev": true
|
||||
},
|
||||
"trough": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz",
|
||||
"integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA=="
|
||||
},
|
||||
"tslib": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||
|
@ -3220,11 +3354,29 @@
|
|||
"integrity": "sha512-qOcYwxaByStAWrBf4x0fibwZvMRG+r4cQoTjbPtUlrWjBHbmCAww1i448U0GJ+3cNNEtebDteo/cHOR3xJ4wEw==",
|
||||
"dev": true
|
||||
},
|
||||
"unified": {
|
||||
"version": "9.2.1",
|
||||
"resolved": "https://registry.npmjs.org/unified/-/unified-9.2.1.tgz",
|
||||
"integrity": "sha512-juWjuI8Z4xFg8pJbnEZ41b5xjGUWGHqXALmBZ3FC3WX0PIx1CZBIIJ6mXbYMcf6Yw4Fi0rFUTA1cdz/BglbOhA==",
|
||||
"requires": {
|
||||
"bail": "^1.0.0",
|
||||
"extend": "^3.0.0",
|
||||
"is-buffer": "^2.0.0",
|
||||
"is-plain-obj": "^2.0.0",
|
||||
"trough": "^1.0.0",
|
||||
"vfile": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"uniq": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz",
|
||||
"integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8="
|
||||
},
|
||||
"unist-util-is": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz",
|
||||
"integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg=="
|
||||
},
|
||||
"unist-util-stringify-position": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz",
|
||||
|
@ -3276,6 +3428,22 @@
|
|||
"spdx-expression-parse": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"vfile": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz",
|
||||
"integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==",
|
||||
"requires": {
|
||||
"@types/unist": "^2.0.0",
|
||||
"is-buffer": "^2.0.0",
|
||||
"unist-util-stringify-position": "^2.0.0",
|
||||
"vfile-message": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"vfile-location": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-3.2.0.tgz",
|
||||
"integrity": "sha512-aLEIZKv/oxuCDZ8lkJGhuhztf/BW4M+iHdCwglA/eWc+vtuRFJj8EtgceYFX4LRjOhCAAiNHsKGssC6onJ+jbA=="
|
||||
},
|
||||
"vfile-message": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz",
|
||||
|
@ -3295,6 +3463,11 @@
|
|||
"@vue/shared": "3.0.11"
|
||||
}
|
||||
},
|
||||
"web-namespaces": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-1.1.4.tgz",
|
||||
"integrity": "sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw=="
|
||||
},
|
||||
"which": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||
|
@ -3343,6 +3516,11 @@
|
|||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
|
||||
"dev": true
|
||||
},
|
||||
"xtend": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
|
||||
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="
|
||||
},
|
||||
"y18n": {
|
||||
"version": "5.0.5",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz",
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
"@snowpack/plugin-sass": "^1.4.0",
|
||||
"@snowpack/plugin-svelte": "^3.6.0",
|
||||
"@snowpack/plugin-vue": "^2.4.0",
|
||||
"@vue/server-renderer": "^3.0.11",
|
||||
"@vue/server-renderer": "^3.0.10",
|
||||
"acorn": "^7.4.0",
|
||||
"autoprefixer": "^10.2.5",
|
||||
"cheerio": "^1.0.0-rc.5",
|
||||
|
@ -46,6 +46,7 @@
|
|||
"find-up": "^5.0.0",
|
||||
"github-slugger": "^1.3.0",
|
||||
"gray-matter": "^4.0.2",
|
||||
"hast-to-hyperscript": "^9.0.1",
|
||||
"kleur": "^4.1.4",
|
||||
"locate-character": "^2.0.5",
|
||||
"magic-string": "^0.25.3",
|
||||
|
@ -53,6 +54,7 @@
|
|||
"micromark-extension-gfm": "^0.3.3",
|
||||
"micromark-extension-mdx-expression": "^0.3.2",
|
||||
"micromark-extension-mdx-jsx": "^0.3.3",
|
||||
"moize": "^6.0.1",
|
||||
"node-fetch": "^2.6.1",
|
||||
"picomatch": "^2.2.3",
|
||||
"postcss": "^8.2.8",
|
||||
|
@ -62,12 +64,15 @@
|
|||
"prismjs": "^1.23.0",
|
||||
"react": "^17.0.1",
|
||||
"react-dom": "^17.0.1",
|
||||
"rehype-parse": "^7.0.1",
|
||||
"rollup": "^2.43.1",
|
||||
"rollup-plugin-terser": "^7.0.2",
|
||||
"sass": "^1.32.8",
|
||||
"snowpack": "^3.2.2",
|
||||
"svelte": "^3.35.0",
|
||||
"vue": "^3.0.11",
|
||||
"tiny-glob": "^0.2.8",
|
||||
"unified": "^9.2.1",
|
||||
"vue": "^3.0.10",
|
||||
"yargs-parser": "^20.2.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
@ -11,6 +11,8 @@ export interface DynamicRenderContext {
|
|||
|
||||
export interface ComponentRenderer<T> {
|
||||
renderStatic: StaticRendererGenerator<T>;
|
||||
jsxPragma?: (...args: any) => any;
|
||||
jsxPragmaName?: string;
|
||||
render(context: { root: string; Component: string; props: string; [key: string]: string }): string;
|
||||
imports?: Record<string, string[]>;
|
||||
}
|
||||
|
|
|
@ -208,6 +208,9 @@ function getComponentWrapper(_name: string, { type, plugin, url }: ComponentInfo
|
|||
wrapper: `__svelte_${kind}(${name}, ${JSON.stringify({
|
||||
componentUrl: getComponentUrl('.svelte.js'),
|
||||
componentExport: 'default',
|
||||
frameworkUrls: {
|
||||
'astro/frontend/runtime/svelte': internalImport('runtime/svelte.js'),
|
||||
},
|
||||
})})`,
|
||||
wrapperImport: `import {__svelte_${kind}} from '${internalImport('render/svelte.js')}';`,
|
||||
};
|
||||
|
|
7
src/frontend/SvelteWrapper.svelte
Normal file
7
src/frontend/SvelteWrapper.svelte
Normal file
|
@ -0,0 +1,7 @@
|
|||
<script>
|
||||
const { __astro_component: Component, __astro_children, ...props } = $$props;
|
||||
</script>
|
||||
|
||||
<Component {...props}>
|
||||
{@html __astro_children}
|
||||
</Component>
|
168
src/frontend/SvelteWrapper.svelte.client.ts
Normal file
168
src/frontend/SvelteWrapper.svelte.client.ts
Normal file
|
@ -0,0 +1,168 @@
|
|||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
// TODO: don't precompile this, but it works for now
|
||||
import {
|
||||
HtmlTag,
|
||||
SvelteComponentDev,
|
||||
assign,
|
||||
claim_component,
|
||||
create_component,
|
||||
destroy_component,
|
||||
detach_dev,
|
||||
dispatch_dev,
|
||||
empty,
|
||||
exclude_internal_props,
|
||||
get_spread_object,
|
||||
get_spread_update,
|
||||
init,
|
||||
insert_dev,
|
||||
mount_component,
|
||||
noop,
|
||||
not_equal,
|
||||
transition_in,
|
||||
transition_out,
|
||||
validate_slots
|
||||
} from "svelte/internal";
|
||||
|
||||
const file = "App.svelte";
|
||||
|
||||
// (5:0) <Component {...props}>
|
||||
function create_default_slot(ctx) {
|
||||
let html_tag;
|
||||
let html_anchor;
|
||||
|
||||
const block = {
|
||||
c: function create() {
|
||||
html_anchor = empty();
|
||||
this.h();
|
||||
},
|
||||
l: function claim(nodes) {
|
||||
html_anchor = empty();
|
||||
this.h();
|
||||
},
|
||||
h: function hydrate() {
|
||||
html_tag = new HtmlTag(html_anchor);
|
||||
},
|
||||
m: function mount(target, anchor) {
|
||||
html_tag.m(/*__astro_children*/ ctx[1], target, anchor);
|
||||
insert_dev(target, html_anchor, anchor);
|
||||
},
|
||||
p: noop,
|
||||
d: function destroy(detaching) {
|
||||
if (detaching) detach_dev(html_anchor);
|
||||
if (detaching) html_tag.d();
|
||||
}
|
||||
};
|
||||
|
||||
dispatch_dev("SvelteRegisterBlock", {
|
||||
block,
|
||||
id: create_default_slot.name,
|
||||
type: "slot",
|
||||
source: "(5:0) <Component {...props}>",
|
||||
ctx
|
||||
});
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
function create_fragment(ctx) {
|
||||
let component;
|
||||
let current;
|
||||
const component_spread_levels = [/*props*/ ctx[2]];
|
||||
|
||||
let component_props = {
|
||||
$$slots: { default: [create_default_slot] },
|
||||
$$scope: { ctx }
|
||||
};
|
||||
|
||||
for (let i = 0; i < component_spread_levels.length; i += 1) {
|
||||
component_props = assign(component_props, component_spread_levels[i]);
|
||||
}
|
||||
|
||||
component = new /*Component*/ ctx[0]({ props: component_props, $$inline: true });
|
||||
|
||||
const block = {
|
||||
c: function create() {
|
||||
create_component(component.$$.fragment);
|
||||
},
|
||||
l: function claim(nodes) {
|
||||
claim_component(component.$$.fragment, nodes);
|
||||
},
|
||||
m: function mount(target, anchor) {
|
||||
mount_component(component, target, anchor);
|
||||
current = true;
|
||||
},
|
||||
p: function update(ctx, [dirty]) {
|
||||
const component_changes = (dirty & /*props*/ 4)
|
||||
? get_spread_update(component_spread_levels, [get_spread_object(/*props*/ ctx[2])])
|
||||
: {};
|
||||
|
||||
if (dirty & /*$$scope*/ 16) {
|
||||
component_changes.$$scope = { dirty, ctx };
|
||||
}
|
||||
|
||||
component.$set(component_changes);
|
||||
},
|
||||
i: function intro(local) {
|
||||
if (current) return;
|
||||
transition_in(component.$$.fragment, local);
|
||||
current = true;
|
||||
},
|
||||
o: function outro(local) {
|
||||
transition_out(component.$$.fragment, local);
|
||||
current = false;
|
||||
},
|
||||
d: function destroy(detaching) {
|
||||
destroy_component(component, detaching);
|
||||
}
|
||||
};
|
||||
|
||||
dispatch_dev("SvelteRegisterBlock", {
|
||||
block,
|
||||
id: create_fragment.name,
|
||||
type: "component",
|
||||
source: "",
|
||||
ctx
|
||||
});
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
function instance($$self, $$props, $$invalidate) {
|
||||
let { $$slots: slots = {}, $$scope } = $$props;
|
||||
validate_slots("App", slots, []);
|
||||
const { __astro_component: Component, __astro_children, ...props } = $$props;
|
||||
|
||||
$$self.$$set = $$new_props => {
|
||||
$$invalidate(3, $$props = assign(assign({}, $$props), exclude_internal_props($$new_props)));
|
||||
};
|
||||
|
||||
$$self.$capture_state = () => ({ Component, __astro_children, props });
|
||||
|
||||
$$self.$inject_state = $$new_props => {
|
||||
$$invalidate(3, $$props = assign(assign({}, $$props), $$new_props));
|
||||
};
|
||||
|
||||
if ($$props && "$$inject" in $$props) {
|
||||
$$self.$inject_state($$props.$$inject);
|
||||
}
|
||||
|
||||
$$props = exclude_internal_props($$props);
|
||||
return [Component, __astro_children, props];
|
||||
}
|
||||
|
||||
class App extends SvelteComponentDev {
|
||||
constructor(options) {
|
||||
super(options);
|
||||
init(this, options, instance, create_fragment, not_equal, {});
|
||||
|
||||
dispatch_dev("SvelteRegisterComponent", {
|
||||
component: this,
|
||||
tagName: "App",
|
||||
options,
|
||||
id: create_fragment.name
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default App;
|
12
src/frontend/SvelteWrapper.svelte.server.ts
Normal file
12
src/frontend/SvelteWrapper.svelte.server.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
// TODO: don't precompile this, but it works for now
|
||||
/* App.svelte generated by Svelte v3.37.0 */
|
||||
import { create_ssr_component, validate_component } from "svelte/internal";
|
||||
|
||||
const App = create_ssr_component(($$result, $$props, $$bindings, slots) => {
|
||||
const { __astro_component: Component, __astro_children, ...props } = $$props;
|
||||
return `${validate_component(Component, "Component").$$render($$result, Object.assign(props), {}, { default: () => `${__astro_children}` })}`;
|
||||
});
|
||||
|
||||
export default App;
|
|
@ -1,5 +1,6 @@
|
|||
import { h, render, ComponentType } from 'preact';
|
||||
import { renderToString } from 'preact-render-to-string';
|
||||
import { childrenToVnodes } from './utils';
|
||||
import type { ComponentRenderer } from '../../@types/renderer';
|
||||
import { createRenderer } from './renderer';
|
||||
|
||||
|
@ -7,14 +8,18 @@ import { createRenderer } from './renderer';
|
|||
Function.prototype(render);
|
||||
|
||||
const Preact: ComponentRenderer<ComponentType> = {
|
||||
jsxPragma: h,
|
||||
jsxPragmaName: 'h',
|
||||
renderStatic(Component) {
|
||||
return async (props, ...children) => renderToString(h(Component, props, ...children));
|
||||
return async (props, ...children) => {
|
||||
return renderToString(h(Component, props, childrenToVnodes(h, children)));
|
||||
}
|
||||
},
|
||||
imports: {
|
||||
preact: ['render', 'h'],
|
||||
preact: ['render', 'Fragment', 'h'],
|
||||
},
|
||||
render({ Component, root, props }) {
|
||||
return `render(h(${Component}, ${props}), ${root})`;
|
||||
render({ Component, root, props, children }) {
|
||||
return `render(h(${Component}, ${props}, h(Fragment, null, ...${children})), ${root})`;
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -2,17 +2,22 @@ import type { ComponentRenderer } from '../../@types/renderer';
|
|||
import React, { ComponentType } from 'react';
|
||||
import ReactDOMServer from 'react-dom/server';
|
||||
import { createRenderer } from './renderer';
|
||||
import { childrenToVnodes } from './utils';
|
||||
|
||||
const ReactRenderer: ComponentRenderer<ComponentType> = {
|
||||
jsxPragma: React.createElement,
|
||||
jsxPragmaName: 'React.createElement',
|
||||
renderStatic(Component) {
|
||||
return async (props, ...children) => ReactDOMServer.renderToString(React.createElement(Component, props, children));
|
||||
return async (props, ...children) => {
|
||||
return ReactDOMServer.renderToString(React.createElement(Component, props, childrenToVnodes(React.createElement, children)));
|
||||
}
|
||||
},
|
||||
imports: {
|
||||
react: ['default: React'],
|
||||
'react-dom': ['default: ReactDOM'],
|
||||
},
|
||||
render({ Component, root, props }) {
|
||||
return `ReactDOM.render(React.createElement(${Component}, ${props}), ${root})`;
|
||||
render({ Component, root, children, props }) {
|
||||
return `ReactDOM.hydrate(React.createElement(${Component}, ${props}, React.createElement(React.Fragment, null, ...${children})), ${root})`;
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import type { DynamicRenderContext, DynamicRendererGenerator, SupportedComponentRenderer, StaticRendererGenerator } from '../../@types/renderer';
|
||||
import { childrenToH } from './utils';
|
||||
|
||||
/** Initialize Astro Component renderer for Static and Dynamic components */
|
||||
export function createRenderer(renderer: SupportedComponentRenderer) {
|
||||
|
@ -16,7 +17,7 @@ export function createRenderer(renderer: SupportedComponentRenderer) {
|
|||
.join(',');
|
||||
return `const [{${context.componentExport}: Component}, ${values}] = await Promise.all([import("${context.componentUrl}")${renderer.imports ? ', ' + libs : ''}]);`;
|
||||
};
|
||||
const serializeProps = (props: Record<string, any>) => JSON.stringify(props);
|
||||
const serializeProps = ({ children: _, ...props }: Record<string, any>) => JSON.stringify(props);
|
||||
const createContext = () => {
|
||||
const astroId = `${Math.floor(Math.random() * 1e16)}`;
|
||||
return { ['data-astro-id']: astroId, root: `document.querySelector('[data-astro-id="${astroId}"]')`, Component: 'Component' };
|
||||
|
@ -32,10 +33,19 @@ export function createRenderer(renderer: SupportedComponentRenderer) {
|
|||
}
|
||||
value = `<div data-astro-id="${innerContext['data-astro-id']}">${value}</div>`;
|
||||
|
||||
return `${value}\n<script type="module">${typeof wrapperStart === 'function' ? wrapperStart(innerContext) : wrapperStart}\n${_imports(renderContext)}\n${renderer.render({
|
||||
...innerContext,
|
||||
props: serializeProps(props),
|
||||
})}\n${typeof wrapperEnd === 'function' ? wrapperEnd(innerContext) : wrapperEnd}</script>`;
|
||||
const script = `
|
||||
${typeof wrapperStart === 'function' ? wrapperStart(innerContext) : wrapperStart}
|
||||
${_imports(renderContext)}
|
||||
${renderer.render({
|
||||
...innerContext,
|
||||
props: serializeProps(props),
|
||||
children: `[${childrenToH(renderer, children) ?? ''}]`,
|
||||
childrenAsString: `\`${children}\``
|
||||
})}
|
||||
${typeof wrapperEnd === 'function' ? wrapperEnd(innerContext) : wrapperEnd}
|
||||
`;
|
||||
|
||||
return [value, `<script type="module">${script.trim()}</script>`].join('\n');
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -45,7 +55,7 @@ export function createRenderer(renderer: SupportedComponentRenderer) {
|
|||
idle: createDynamicRender('requestIdleCallback(async () => {', '})'),
|
||||
visible: createDynamicRender(
|
||||
'const o = new IntersectionObserver(async ([entry]) => { if (!entry.isIntersecting) { return; } o.disconnect();',
|
||||
({ root }) => `}); o.observe(${root})`
|
||||
({ root }) => `}); Array.from(${root}.item(0).children).forEach(child => o.observe(child))`
|
||||
),
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
import type { ComponentRenderer } from '../../@types/renderer';
|
||||
import type { SvelteComponent } from 'svelte';
|
||||
import { createRenderer } from './renderer';
|
||||
import SvelteWrapper from '../SvelteWrapper.svelte.server';
|
||||
|
||||
const SvelteRenderer: ComponentRenderer<SvelteComponent> = {
|
||||
renderStatic(Component) {
|
||||
return async (props, ...children) => {
|
||||
const { html } = Component.render(props);
|
||||
const { html } = SvelteWrapper.render({ __astro_component: Component, __astro_children: children.join('\n'), ...props });
|
||||
return html;
|
||||
};
|
||||
},
|
||||
render({ Component, root, props }) {
|
||||
return `new ${Component}({
|
||||
target: ${root},
|
||||
props: ${props},
|
||||
hydrate: true
|
||||
})`;
|
||||
imports: {
|
||||
'astro/frontend/runtime/svelte': ['default: render']
|
||||
},
|
||||
render({ Component, root, props, childrenAsString }) {
|
||||
return `render(${root}, ${Component}, ${props}, ${childrenAsString});`;
|
||||
},
|
||||
};
|
||||
|
||||
|
|
47
src/frontend/render/utils.ts
Normal file
47
src/frontend/render/utils.ts
Normal file
|
@ -0,0 +1,47 @@
|
|||
import unified from 'unified';
|
||||
import parse from 'rehype-parse';
|
||||
import toH from 'hast-to-hyperscript';
|
||||
import { ComponentRenderer } from '../../@types/renderer';
|
||||
import moize from 'moize';
|
||||
|
||||
/** @internal */
|
||||
function childrenToTree(children: string[]) {
|
||||
return children.map(child => (unified().use(parse, { fragment: true }).parse(child) as any).children.pop());
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an HTML fragment string into vnodes for rendering via provided framework
|
||||
* @param h framework's `createElement` function
|
||||
* @param children the HTML string children
|
||||
*/
|
||||
export const childrenToVnodes = moize.deep(function childrenToVnodes(h: any, children: string[]) {
|
||||
const tree = childrenToTree(children);
|
||||
const vnodes = tree.map(subtree => toH(h, subtree));
|
||||
return vnodes;
|
||||
})
|
||||
|
||||
/**
|
||||
* Converts an HTML fragment string into h function calls as a string
|
||||
* @param h framework's `createElement` function
|
||||
* @param children the HTML string children
|
||||
*/
|
||||
export const childrenToH = moize.deep(function childrenToH(renderer: ComponentRenderer<any>, children: string[]): any {
|
||||
if (!renderer.jsxPragma) return;
|
||||
const tree = childrenToTree(children);
|
||||
const innerH = (name: any, attrs: Record<string, any>|null = null, _children: string[]|null = null) => {
|
||||
const vnode = renderer.jsxPragma?.(name, attrs, _children);
|
||||
const childStr = _children ? `, [${_children.map(child => serializeChild(child)).join(',')}]` : '';
|
||||
/* fix(react): avoid hard-coding keys into the serialized tree */
|
||||
if (attrs && attrs.key) attrs.key = undefined;
|
||||
const __SERIALIZED = `${renderer.jsxPragmaName}("${name}", ${attrs ? JSON.stringify(attrs) : 'null'}${childStr})` as string;
|
||||
return { ...vnode, __SERIALIZED }
|
||||
}
|
||||
const serializeChild = (child: unknown) => {
|
||||
if (typeof child === 'string') return `\`${child}\``;
|
||||
if (typeof child === 'number' || typeof child === 'boolean') return `${child}`;
|
||||
if (child === null) return `null`;
|
||||
if ((child as any).__SERIALIZED) return (child as any).__SERIALIZED;
|
||||
return innerH(child).__SERIALIZED;
|
||||
}
|
||||
return tree.map(subtree => toH(innerH, subtree).__SERIALIZED);
|
||||
})
|
|
@ -1,20 +1,45 @@
|
|||
import type { ComponentRenderer } from '../../@types/renderer';
|
||||
import type { Component as VueComponent } from 'vue';
|
||||
import { renderToString } from '@vue/server-renderer';
|
||||
import { createSSRApp, h as createElement } from 'vue';
|
||||
import { defineComponent, createSSRApp, h as createElement } from 'vue';
|
||||
import { createRenderer } from './renderer';
|
||||
|
||||
/**
|
||||
* Users might attempt to use :vueAttribute syntax to pass primitive values.
|
||||
* If so, try to JSON.parse them to get the primitives
|
||||
*/
|
||||
function cleanPropsForVue(obj: Record<string, any>) {
|
||||
let cleaned = {} as any;
|
||||
for (let [key, value] of Object.entries(obj)) {
|
||||
if (key.startsWith(':')) {
|
||||
key = key.slice(1);
|
||||
if (typeof value === 'string') {
|
||||
try {
|
||||
value = JSON.parse(value);
|
||||
} catch (e) {}
|
||||
}
|
||||
}
|
||||
cleaned[key] = value;
|
||||
}
|
||||
return cleaned;
|
||||
}
|
||||
|
||||
const Vue: ComponentRenderer<VueComponent> = {
|
||||
jsxPragma: createElement,
|
||||
jsxPragmaName: 'createElement',
|
||||
renderStatic(Component) {
|
||||
return async (props, ...children) => {
|
||||
const app = createSSRApp({
|
||||
const App = defineComponent({
|
||||
components: {
|
||||
Component,
|
||||
Component
|
||||
},
|
||||
render() {
|
||||
return createElement(Component as any, props);
|
||||
data() {
|
||||
return { props }
|
||||
},
|
||||
template: `<Component v-bind="props">${children.join('\n')}</Component>`
|
||||
});
|
||||
|
||||
const app = createSSRApp(App);
|
||||
const html = await renderToString(app);
|
||||
return html;
|
||||
};
|
||||
|
@ -22,8 +47,9 @@ const Vue: ComponentRenderer<VueComponent> = {
|
|||
imports: {
|
||||
vue: ['createApp', 'h: createElement'],
|
||||
},
|
||||
render({ Component, root, props }) {
|
||||
return `const App = { render() { return createElement(${Component}, ${props} )} };
|
||||
render({ Component, root, props, children }) {
|
||||
const vueProps = cleanPropsForVue(JSON.parse(props));
|
||||
return `const App = { render: () => createElement(${Component}, ${JSON.stringify(vueProps)}, { default: () => ${children} }) };
|
||||
createApp(App).mount(${root});`;
|
||||
},
|
||||
};
|
||||
|
|
10
src/frontend/runtime/svelte.ts
Normal file
10
src/frontend/runtime/svelte.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
import SvelteWrapper from '../SvelteWrapper.svelte.client';
|
||||
import type { SvelteComponent } from 'svelte';
|
||||
|
||||
export default (target: Element, component: SvelteComponent, props: any, children: string) => {
|
||||
new SvelteWrapper({
|
||||
target,
|
||||
props: { __astro_component: component, __astro_children: children, ...props },
|
||||
hydrate: true
|
||||
})
|
||||
}
|
|
@ -261,7 +261,7 @@ async function createSnowpack(astroConfig: AstroConfig, env: Record<string, any>
|
|||
plugins: [
|
||||
[fileURLToPath(new URL('../snowpack-plugin.cjs', import.meta.url)), astroPlugOptions],
|
||||
require.resolve('@snowpack/plugin-sass'),
|
||||
require.resolve('@snowpack/plugin-svelte'),
|
||||
[require.resolve('@snowpack/plugin-svelte'), { compilerOptions: { hydratable: true }}],
|
||||
require.resolve('@snowpack/plugin-vue'),
|
||||
],
|
||||
devOptions: {
|
||||
|
|
Loading…
Reference in a new issue