'use strict' ; import path from 'path' ; import { Plugin , rollup } from 'rollup' ; import svelte , { Options as SvelteOptions } from 'rollup-plugin-svelte' ; import resolve from '@rollup/plugin-node-resolve' ; import virtual from '@rollup/plugin-virtual' ; import cheerio from 'cheerio' ; import { getBaseName } from './utils/paths' ; type Component = { fileName : string ; instances : { props : unknown ; } [ ] ; } ; type ComponentMap = { [ outputPath ] : Record < string , Component > ; } ; type Options = { svelteDir ? : string ; rollupPluginSvelteOptions ? : Partial < SvelteOptions > ; rollupInputPlugins ? : Plugin [ ] ; rollupOutputPlugins ? : Plugin [ ] ; } ; export = function ( eleventyConfig , { svelteDir = '' , rollupPluginSvelteOptions = { } , rollupInputPlugins = [ ] , rollupOutputPlugins = [ ] } ) { let componentMap = { } ; eleventyConfig . addShortcode ( 'embedSvelte' , function ( fileName , props ) { fileName = path . resolve ( svelteDir , fileName ) ; let name = getBaseName ( fileName ) ; let instanceIndex ; if ( ! componentMap [ this . page . outputPath ] ) { instanceIndex = 0 ; componentMap [ this . page . outputPath ] = { [ name ] : { fileName , instances : [ { props } ] } } ; } else { const components = componentMap [ this . page . outputPath ] ; if ( components [ name ] ) { instanceIndex = components [ name ] . instances . length ; components [ name ] . instances . push ( { props } ) ; } else { instanceIndex = 0 ; components [ name ] = { fileName , instances : [ { props } ] } ; } } return `<div id="svelte-embed-${ name }${ instanceIndex }"></div>` ; } ) ; eleventyConfig . addTransform ( 'embed-svelte' , async function ( content , outputPath ) { if ( componentMap [ outputPath ] ) { const $ = cheerio . load ( content ) ; const bundle = await rollup ( { input : 'entry' , plugins : [ virtual ( { entry : virtualEntry ( componentMap [ outputPath ] ) } ) as Plugin , resolve ( ) , svelte ( { ... rollupPluginSvelteOptions , emitCss : false } ) , ... rollupInputPlugins ] } ) ; const build = await bundle . generate ( { format : 'iife' , name : 'EmbedSvelte' , plugins : rollupOutputPlugins } ) ; await bundle . close ( ) ; let code = build . output [ 0 ] . code ; code = code . replace ( '</script>' , '<\\/script>' ) ; const body = $ ( 'body' ) ; body . append ( `\n<script>\n${ code }</script>` ) ; body . append ( `\n<script>\n${ initCode ( componentMap [ outputPath ] ) }\n</script>\n` ) ; return $ . html ( ) ; } return content ; } ) ; eleventyConfig . addWatchTarget ( svelteDir ) ; eleventyConfig . on ( 'beforeWatch' , ( ) => ( componentMap = { } ) ) ; } ; function virtualEntry ( components ) { return Object . entries ( components ) . map ( ( [ name , { fileName } ] ) => `export { default as ${ name } } from '${ fileName }';` ) . join ( '' ) ; } function initCode ( components ) { return Object . entries ( components ) . flatMap ( ( [ name , { instances } ] ) => instances . map ( ( { props } , instanceIndex ) => `new EmbedSvelte.${ name }({\n\ttarget: document.getElementById('svelte-embed-${ name }${ instanceIndex }'),\n\tprops: ${ JSON . stringify ( props ) }\n});` ) ) . join ( '\n' ) ; }