blitz-js / superjson

Safely serialize JavaScript expressions to a superset of JSON, which includes Dates, BigInts, and more.
MIT License
3.88k stars 83 forks source link

Skipping transformation #283

Open luixo opened 7 months ago

luixo commented 7 months ago

Hello, I'm using superjson in my project (with tRPC) and there is a bunch of fields which are optional - hence emitting undefined in a server response going client-side. It resolves to emptiness in json field, but a bunch of undefineds in meta which I don't actually need as I don't go through object props anywhere in my project. Can I turn off this transformation somehow? Can I register an override over this type? If so - how can I make it be omitted?

Skn0tt commented 7 months ago

Hi @luixo! Can you elaborate on why you’re looking to cut out those superfluous fields in meta? If it‘s because of bandwidth concerns, I recommend to check how much of a size impact they really have after going through gzip. meta tends to be highly compressable.

If you still want to omit those bytes afterwards, you could traverse the object before passing it to SuperJSON and delete all undefined fields.

I try to keep SuperJSON light on config, so I‘m always recommending user-land solutions first. Let me know if that works for you!

luixo commented 7 months ago

It's mostly DX. Going through a big amount of superfluous fields just feels.. sad.

so I‘m always recommending user-land solutions first

That would be great, actually. Can I override (through register function) a transformer for a type that already has a transformer? If yes - can I make a serializer emit nothing to meta?

Skn0tt commented 6 months ago

Going through a big amount of superfluous fields just feels.. sad.

I get that feeling :D But I promise you, if you neatly tuck it away into its own little function, it will spark a little more joy, and the function will feel a sense of purpose in its life.

Jokes aside - I get it, but this is a matter of complexity on SuperJSON's end, and i'd like to keep that as low as possible.

Can I override (through register function) a transformer for a type that already has a transformer?

Going off the current implementation, it looks like custom-registered transformers are taking precedence over built-in transformers for undefined:

https://github.com/blitz-js/superjson/blob/0130a809f87df142b5e190e1b519be0c0280fb16/src/transformer.ts#L313-L339

So this should work, yes! If you end up using this, please send a pull request with a test for this, so we can make sure there's no regressions to it.

If yes - can I make a serializer emit nothing to meta?

Try it out and let us know what you found!

luixo commented 4 months ago

Try it out and let us know what you found!

I investigated the source code and found no way to omit transforming a non-deep object (which is not a plain object, array, map, set or registered class). Should it be added? Is it in the scope of this package to let objects change between serialization / deserialization?

Or should I do deep omitting of undefined values myself before feeding the object to superjson?