Allow importing from arbitrary npm packages for better demos
I had wanted to use Limber for showcasing https://github.com/NullVoxPopuli/ember-statechart-component/, because the story here is really slick with template imports -- but xstate (and ember-statechart-component) are not included in the Limber build.
It'd be great if you could import from 'x' and have x added to your page at runtime, kinda like what https://runkit.com/ does for node packages
How this might look (but with gjs live instead of just gjs)
example:
this should be able to work: [import { toBlob } from 'html-to-image'](http://localhost:4200/?t=%23%23%20Importing%20from%20Modules%0AThis%20example%3A%0A%20-%20imports%20from%20a%20third%20party%20library%20(external%20%2F%20on%20npm)%0A%20-%20imports%20from%20the%20host%20app%0A%0A%60%60%60gjs%20live%0Aimport%20Component%20from%20%27%40glimmer%2Fcomponent%27%3B%0Aimport%20%7B%20action%20%7D%20from%20%27%40ember%2Fobject%27%3B%0Aimport%20%7B%20on%20%7D%20from%20%27%40ember%2Fmodifier%27%3B%0Aimport%20%7B%20toBlob%20%7D%20from%20%27html-to-image%27%3B%0A%0Aimport%20Menu%20from%20%27limber%2Fcomponents%2Flimber%2Fmenu%27%3B%0A%0Aexport%20default%20class%20CopyMenu%20extends%20Component%20%7B%0A%20%20%40action%0A%20%20copyAsText(event)%20%7B%0A%20%20%20%20let%20code%20%3D%20getSnippetElement(event)%3B%0A%0A%20%20%20%20navigator.clipboard.writeText(code.innerText)%3B%0A%20%20%7D%0A%0A%20%20%40action%0A%20%20async%20copyAsImage(event)%20%7B%0A%20%20%20%20let%20code%20%3D%20getSnippetElement(event)%3B%0A%0A%20%20%20%20await%20withExtraStyles(code%2C%20()%20%3D%3E%20toClipboard(code))%3B%0A%20%20%7D%0A%0A%0A%20%20%3Ctemplate%3E%0A%20%20%20%20%3CMenu%3E%0A%20%20%20%20%20%20%3C%3Atrigger%3E%F0%9F%93%8B%3C%2F%3Atrigger%3E%0A%0A%20%20%20%20%20%20%3C%3Aoptions%20as%20%7CItem%7C%3E%0A%20%20%20%20%20%20%20%20%3CItem%20%7B%7Bon%20%27click%27%20this.copyAsText%7D%7D%3E%0A%20%20%20%20%20%20%20%20%20%20Copy%20as%20text%0A%20%20%20%20%20%20%20%20%3C%2FItem%3E%0A%20%20%20%20%20%20%20%20%3CItem%20%7B%7Bon%20%27click%27%20this.copyAsImage%7D%7D%3E%0A%20%20%20%20%20%20%20%20%20%20Copy%20as%20image%0A%20%20%20%20%20%20%20%20%3C%2FItem%3E%0A%20%20%20%20%20%20%3C%2F%3Aoptions%3E%0A%20%20%20%20%3C%2FMenu%3E%0A%20%20%3C%2Ftemplate%3E%0A%7D%0A%0A%2F*************************************************%0A%20*%0A%20*%20Helpers%20and%20stuff%0A%20*%0A%20*%20********************************************%2F%0A%0Afunction%20getSnippetElement(event)%20%7B%0A%20%20let%20target%20%3D%20event.target%3B%0A%0A%20%20%2F**%0A%20%20%20*%20This%20component%20has%20intimate%20knowledge%0A%20%20%20*%20of%20how%20we%20build%20markdown%20previews%20in%0A%20%20%20*%20markdown-to-ember.ts%0A%20%20%20*%0A%20%20%20*%20We%20can%27t%20select%20the%20pre%20tag%20directly%2C%20otherwise%20html-to-image%0A%20%20%20*%20loses%20the%20padding%2C%20border-radius%2C%20shadow%0A%20%20%20*%2F%0A%20%20let%20code%20%3D%20target.closest(%27.glimdown-snippet%27)%3B%0A%0A%20%20if%20(!code)%20%7B%0A%20%20%20%20return%20target.closest(%27%5Bdata-test-output%5D%27)%3B%0A%20%20%7D%0A%0A%20%20return%20code%3B%0A%7D%0A%0Aasync%20function%20withExtraStyles(target%2C%20next)%20%7B%0A%20%20let%20pre%20%3D%20target.querySelector(%27pre%27)%3B%0A%0A%20%20if%20(!pre)%20%7B%0A%20%20%20%20return%20await%20next()%3B%0A%20%20%7D%0A%0A%20%20pre.classList.add(%27shadow-lg%27)%3B%0A%20%20pre.style.margin%20%3D%20%270%27%3B%0A%0A%20%20try%20%7B%0A%20%20%20%20await%20next()%3B%0A%20%20%7D%20finally%20%7B%0A%20%20%20%20pre.classList.remove(%27shadow-lg%27)%3B%0A%20%20%20%20pre.setAttribute(%27style%27%2C%20%27%27)%3B%0A%20%20%7D%0A%7D%0A%0Aasync%20function%20toClipboard(target)%20%7B%0A%20%20let%20backgroundColor%20%3D%20%27%23ffffff%27%3B%0A%20%20let%20canCopyToImage%20%3D%20%27ClipboardItem%27%20in%20window%3B%0A%20%20let%20filter%20%3D%20(node)%20%3D%3E%20%7B%0A%20%20%20%20if%20(node%20instanceof%20Text)%20return%20true%3B%0A%0A%20%20%20%20return%20!node.hasAttribute(%27data-test-copy-menu%27)%3B%0A%20%20%7D%3B%0A%0A%20%20let%20box%20%3D%20target.getBoundingClientRect()%3B%0A%0A%20%20let%20options%20%3D%20%7B%0A%20%20%20%20filter%2C%0A%20%20%20%20backgroundColor%2C%0A%20%20%20%20%2F%2F%20tell%20html-to-image%20to%20include%20margins%20in%20dimensions%0A%20%20%20%20%2F%2F%20html-to-image%20does%20not%20make%20adjustments%20if%20margins%20exist%20anyway%0A%20%20%20%20width%3A%20box.width%20%2B%2032%2C%0A%20%20%20%20height%3A%20box.height%20%2B%2032%2C%0A%20%20%20%20style%3A%20%7B%0A%20%20%20%20%20%20%2F%2F%20m-0%0A%20%20%20%20%20%20%2F%2F%20make%20margin%20uniform%20all%20the%20way%20around%0A%20%20%20%20%20%20margin%3A%20%271rem%27%2C%0A%20%20%20%20%7D%2C%0A%20%20%7D%3B%0A%0A%20%20if%20(!canCopyToImage)%20%7B%0A%20%20%20%20let%20image%20%3D%20new%20Image()%3B%0A%20%20%20%20let%20dataUri%20%3D%20await%20toPng(target%2C%20options)%3B%0A%0A%20%20%20%20image.src%20%3D%20dataUri%3B%0A%0A%20%20%20%20let%20w%20%3D%20window.open(%27%27)%3B%0A%0A%20%20%20%20w%3F.document.write(%0A%20%20%20%20%20%20%60Your%20browser%20does%20not%20yet%20support%20%60%20%2B%0A%20%20%20%20%20%20%20%20%60%3Ca%20target%3D%22_blank%22%20href%3D%22https%3A%2F%2Fcaniuse.com%2F%3Fsearch%3DClipboardItem%22%3EClipboardItem%3C%2Fa%3E.%20%3Cbr%3E%3Cbr%3E%60%20%2B%0A%20%20%20%20%20%20%20%20image.outerHTML%0A%20%20%20%20)%3B%0A%0A%20%20%20%20return%3B%0A%20%20%7D%0A%0A%20%20let%20blob%20%3D%20await%20toBlob(target%2C%20options)%3B%0A%0A%20%20%2F%2F%20Works%20in%20chrome-based%20browsers%20only%20%3A(%0A%20%20%2F%2F%20eslint-disable-next-line%20%40typescript-eslint%2Fban-ts-comment%0A%20%20%2F%2F%20%40ts-ignore%0A%20%20navigator.clipboard.write(%5Bnew%20ClipboardItem(%7B%20%27image%2Fpng%27%3A%20blob%20%7D)%5D)%3B%0A%7D%0A%0A%60%60%60 )
Also, importing components from from the app should be doable as well
In case browsers don't support script[type=module] properly, or import maps: https://github.com/guybedford/es-module-shims
For re-writing imports in scripts without jscodeshift or silly regex: https://github.com/guybedford/es-module-lexer
Example of dynamic updating of the import-map: https://github.com/huozhi/devjar/blob/main/lib/module.js
Allowing service worker composition: https://mswjs.io/docs/recipes/merging-service-workers/