patricknelson / svelte-retag

Light DOM custom element wrapper for Svelte 3 and 4 with slots, context and Vite HMR support
https://www.npmjs.com/package/svelte-retag
MIT License
39 stars 0 forks source link

Svelte retag doesn't pass types #26

Closed baseplate-admin closed 9 months ago

baseplate-admin commented 9 months ago

Describe the bug

Types aren't preserved if i pass them from customElement to ts code.

Reproduction

Lets say i have this component

<svelte:option tag='hello' />
<script lang='ts'>
    export let val : boolean = false
$: console.log(val) // if i modify it from outside it will return "true" ( a string ) not `true` ( a bool)
</script>

<hello val="true"/>

It logs :

"true"

not

true

Logs

No response

System Info

PS C:\Programming\CoreProject-frontend> npx envinfo --system --npmPackages svelte,svelte-retag,rollup,webpack --binaries --browsers
Need to install the following packages:
envinfo@7.11.0
Ok to proceed? (y) y

  System:
    OS: Windows 11 10.0.22621
    CPU: (16) x64 AMD Ryzen 7 7700X 8-Core Processor
    Memory: 20.36 GB / 31.21 GB
  Binaries:
    Node: 20.6.1 - C:\Program Files\nodejs\node.EXE
    npm: 9.8.1 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Edge: Chromium (119.0.2151.72)
    Internet Explorer: 11.0.22621.1
  npmPackages:
    svelte: ^4.2.3 => 4.2.3

Severity

annoyance

baseplate-admin commented 9 months ago

Thinking again, i think this is a limitation of web component standard. But is it possible to somehow squeeze this into the package ( it would be awesome and thanks a lot for this awesome package )

patricknelson commented 9 months ago

Yeah, sadly this is an artifact of just how HTML attributes work. There’s no way to know (at least, not automatically) once outside of the custom element and into Svelte-land what type we should coerce it to (which is what we’d have to do here) without additional information on a per-attribute basis. Ideally it’d be inferred magically, but of course this will never be something I’d do in svelte-retag, however…

We do have #13 on the roadmap which has the goal of supporting the Svelte 4 <svelte:options …> syntax documented here which does allow you to define your type coercions. So, with that said I’ll close this out as a dupe of #13 for now but still LMK what you think.

patricknelson commented 9 months ago

p.s. You’re welcome and thanks for considering it!

For context, I built it out of necessity, but wanted to share my progress (since it is derived from svelte-tag and since mostly rewritten). We’re currently using it in production now and for the foreseeable future, since we’re running a PHP back-end with HTML template generation server-side. So, should be supporting it for as long as Svelte itself doesn’t support some of the main features itemized under the “Why?” section.

patricknelson commented 9 months ago

Just switching this to "not planned" (since it wasn't technically "completed") 😊

patricknelson commented 9 months ago

p.s. Just noticed, if you're putting <svelte:option tag='hello' /> at the top of your components while also using svelte-retag then there's a possibility you're using it wrong (i.e. that is for Svelte's built in custom elements which is redundant if you're using this library, and this library doesn't look at that, at least not yet).

patricknelson commented 9 months ago

p.s.s. Speaking of usage @baseplate-admin I was checking this out earlier to see it in use "in the wild" and I commented on this commit a few days ago: https://github.com/baseplate-admin/CoreProject/commit/3fbc611fe3578ad99dc78be2a6ff402e630c7b88#r133929547

Keep in mind that you most likely shouldn't be using hydratable in 99% of use cases, at least not with svelte-retag (unless you're using SSR/SSG to pre-render the components somehow). And if you are doing that -- let me know! That'd be pretty cool.

baseplate-admin commented 9 months ago

Keep in mind that you most likely shouldn't be using hydratable in 99% of use cases, at least not with svelte-retag (unless you're using SSR/SSG to pre-render the components somehow). And if you are doing that -- let me know! That'd be pretty cool.

This is the goal. I actually stumbled upon dxsvelte that can use py-mini-racer to render svelte component from python ( it's awesome )

I plan on using that at some point in this project's lifecycle

patricknelson commented 9 months ago

Ah interesting. I come from the PHP world and one of the main ways to do it was to actually load the V8 engine into PHP itself (potentially similar to py-mini-racer) like using https://github.com/spatie/server-side-rendering. Issue with that is it's so monolithic and not very pluggable.

My thought was instead to use some kind of worker/proxying method where svelte-retag defined custom elements could be parsed out, rendered in situ, then passed through transparently (like expanding/rendering already returned HTML from an upstream server), like reverse proxying. This would be more composable, using whatever JS rendering engine you want and then of course security (e.g. protecting/isolating your proxy), TLS termination and etc are entirely separate concerns. This is a bit more acceptable these days with things like Cloudflare workers and WinterJS and in a world where containers to roll these things are very popular

That is where the hydration: true function would shine. It's initial use case (real world, for me) was to resolve bugs with Percy.io, which we use for automated visual regression testing. It loads JS locally, renders everything, then takes a snapshot of the HTML DOM which caused bugs when it loaded a second time and re-ran (at this point svelte-retag is already rendered but needs to be hydrated, otherwise you get bugs).

So... yeah definitely interested in that, especially once we're on Kubernetes. At that point we could possibly setup a worker/proxy. However, it'd have to be approached very carefully since it could be a source of possible security issues, bloat/memory and I'm sure a host of other things. 🤔

baseplate-admin commented 9 months ago

bloat/memory

This. V8 sucks in this regrad. That's why the project invokes a new memory object and destroys it as soon as svelte is done rendering.

Cons :

baseplate-admin commented 9 months ago

Bit of off topic. Do you folks use vanilla php or uh some sort of framework like laravel/codeigniter?

patricknelson commented 9 months ago

We were already super off topic from attribute types! 😅

We're using SilverStripe. Either way, it's PHP under the hood.