Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow opting out of serialization #41

Closed
XiNiHa opened this issue Jul 11, 2024 · 2 comments · Fixed by #42
Closed

Allow opting out of serialization #41

XiNiHa opened this issue Jul 11, 2024 · 2 comments · Fixed by #42

Comments

@XiNiHa
Copy link

XiNiHa commented Jul 11, 2024

If possible, it'll be pretty convenient to mark some value to be not serialized. Imagine this arbitrary API:

import { serialize, NoSerialization } from "seroval";

console.log(serialize({
  title: "My Article",
  load: new NoSerialization(() => import("./my-article.mdx")),
})) // { title: "My Article" }

In this case, without NoSerialization, the load property should've filtered first not to make any serialization error, since anonymous functions are not serializable. However, because it's marked as NoSerialization, Seroval can just skip the serialization and remove the property.

@lxsmnsyc
Copy link
Owner

lxsmnsyc commented Jul 12, 2024

This reminded me of React's Taint API which usually raises an error when an expected (or in your words, marked) value is encountered during serialization. I did consider this before however there were three reasons why I didn't:

  • I didn't like the API. I just don't like marking the value globally.
  • The internal map might be a source of memory leak.
  • Users can just wrap their own values with an unserializable value.

Now in your case it's a bit different since it doesn't exactly raise an error, it just omits the value. Usually my answer here would be to "defer this problem to the user by making the necessary changes manually" however this might be considered and can open as an opportunity. I like the idea of omitting, but I just need to have a decent API for this.

Here's some of my ideas:

  • Introduce a UnserializableReference class which is basically just a class with a value property that holds the value you want to hide from the serializer e.g. new UnserializableReference(value) then you can access value if you want to recover it.
  • Introduce a UnserializableReference abstract class. This is one is just for inheritance check, but not might be ideal. It works, but i'm still 50/50.
  • Instead of a class, we do an object with an specific symbol. Usually I would provide an API for this (createUnserializableReference perhaps)

Now the term unserializable itself might not be a great term, hidden might be good replacement term, there's also opaque, but that's just me. I'd like to discuss the name.

Also, as expected here, if the value is encountered, it's going to be replaced by a new value (by default it would be undefined HOWEVER I'm thinking of allowing this to be configurable through the reference creation e.g. createUnserializableReference(value, replacement)), and once the value is serializable, I would expect the users to expect that deserializing the value will not able to recover whatever that value is.

@XiNiHa
Copy link
Author

XiNiHa commented Jul 12, 2024

Thanks for looking into the issue! Between the ideas, I like the first and the third one, mostly because the second one requires creating a separate class. For the naming, I also can think of skip, but I'm happy with anything else 😅 I also love the customizable replacement value idea!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants