withastro / astro

The web framework for content-driven websites. ⭐️ Star to support our work!
https://astro.build
Other
46.81k stars 2.49k forks source link

Infinity is null #12088

Closed jstask82 closed 1 month ago

jstask82 commented 1 month ago

Astro Info

> astro@0.0.1 astro
> astro info

Astro                    v4.15.8
Node                     v22.5.1
System                   macOS (arm64)
Package Manager          npm
Output                   static
Adapter                  none
Integrations             @astrojs/svelte
                         @astrojs/tailwind

If this issue only occurs in one browser, which browser is a problem?

No response

Describe the Bug

In Astro Infinity is null in the browser. Typscript won't warn you about that, since Infinity is defined as of type number.

What's the expected result?

Ìnfinity should be Ìnfinity like in a svelte component (or in node.js for instance).

How it should work as a svelte example.

Link to Minimal Reproducible Example

https://stackblitz.com/edit/github-izfcuo?file=src%2Fpages%2Findex.astro,src%2Fcomponents%2FInfinityComponent.svelte

Participation

Fryuni commented 1 month ago

That is expected, any argument to a client component should be JSON-(de)serializable since it has to be passed from the server (or build) to the client. Infinity, -Infinity, -0 and NaN are not, -0 is turned into 0 and the other 3 are turned into null.

The svelte example has the source of the App passing the Infinity value sent to the client as well, so the argument is computed on the client and not passed from server to client.

A similar effect would happen for any value that is not JSON-serializable. Some values can be serialized to JSON but are deserialized to entirely different values (like Date).

jstask82 commented 1 month ago

Thanks for the clarification. What bugs me is that typescript does not catch this. Maybe this could be addressed? Knowing about this, my solution is to wrap the svelte-component in a svelte-wrapper component that does the typecasting from nullto Infinity on the client.

Fryuni commented 1 month ago

As far as TS is concerned there is no broken types. The components expects a numer and you are passing a number. TS doesn't know anything about JSON, much less about special values within a type.

My suggestion would be to make you component accept number | 'Inf' | '-Inf' and then call Number.parseFloat inside of the component. Passing a number returns it unchanged and passing the string Inf returns infinity

bluwy commented 1 month ago

Island props doesn't strictly need to be JSON-serializable. We have a custom serializer to handle certain types at https://github.com/withastro/astro/blob/main/packages/astro/src/runtime/server/serialize.ts

If we want to support Infinity, we could probably extend it to work, or revive https://github.com/withastro/astro/pull/8004 so it works reliably for more custom types ootb (I'm currently testing something locally)

Fryuni commented 1 month ago

Couldn't we use devalue for it and just add handling for some extra types instead of having custom logic?

bluwy commented 1 month ago

Yeah I'm working on it and sending a PR soon