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

[Feature] context for serialization #67

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open

[Feature] context for serialization #67

wants to merge 13 commits into from

Conversation

nros
Copy link

@nros nros commented Nov 7, 2017

deserialization uses a Context with all deserializers. Custom serializers become more flexible if the serialization process uses the same mechanism.

purpose

support automatic creation of references with a custom serializer.

explanation

A context can be used as a place to store temporary data for serialization. A custom serializer can make use of this temporary data to keep track on all serialized objects and serialize only IDs for those, that have already been serialized. Of course, the companion custom deserializer need to know about such IDs, decode them and behave much like the deserializer of reference().

All this would be impossible without keeping track on all already serialized entities.

@coveralls
Copy link

Coverage Status

Coverage increased (+0.5%) to 92.57% when pulling 503784b on nros:feature_serialize-context into 59fe6e5 on mobxjs:master.

@coveralls
Copy link

Coverage Status

Coverage increased (+0.5%) to 92.585% when pulling a80c0c0 on nros:feature_serialize-context into 59fe6e5 on mobxjs:master.

@coveralls
Copy link

coveralls commented Nov 8, 2017

Coverage Status

Coverage increased (+0.5%) to 92.702% when pulling dfed41d on nros:feature_serialize-context into c85a637 on mobxjs:master.

@nros
Copy link
Author

nros commented Nov 8, 2017

Thanks to these changes, I was able to create a custom serializer/deserializer that keeps track on all serialized entities and automatically stores only a reference (as the ID) in case the entity has already been serialized. This avoids breaking up in-memory references during serialization and creating duplicates upon deserializing.

To make that work, I had to tackle #65 as well with this custom serializer. So the serializer stores a class identifier along the serialized data and uses a dependency injection system to create instances for this class identifier upon deserialization.

Using a custom serializer to support these features seems less invasive than changing serializr itself. So maybe this will help others too.

I would appreciate if you accept this PR, although some internal functions are exposed. This is only done for the good, to make custom serializers integrate better with serializr, like benefitting from the reference resolving system.

@chengjianhua
Copy link
Member

I’m busy recently, I would have spare time to review this feauture seriously until weekend ... I reply to this just let you know we saw your nice works. 👍

@alexggordon
Copy link
Member

@nros let's hold off on this PR until we finish the discussion on #65

@spinorkit
Copy link

@nros I need exactly this, along with the support for containers of polymorphic objects. I've pulled your feature branch for this, but I am new to serializr (and Javascript - using Typescript actually), so a rough example of your custom serializer/deserializer maintaining the context would be very helpful for me.
By the way, I implemented a scheme that works like this in C++ over 20 years ago and have been using it ever since in applications built from plugins.

@spinorkit
Copy link

@nros to achieve what I envisage at the top level, I would like to pass a context object to the serialize<T>() function (and the deserialize<T>() function) so that I can control the lifetime of the dictionary of references. I would like to pass the reference dictionary filled in when serializing a full snapshot of the state of the app to subsequent calls to serialize() for incremental actions that occur after the snapshot is written.
I currently can't see how to achieve this control with a custom serializer alone.

@nros
Copy link
Author

nros commented Mar 21, 2018

@tkolo
Copy link

tkolo commented Oct 2, 2018

This is almost a year old by now. Any hope for it being merged? I have exactly the same use case - I need to serialize cyclic graph, preferably in a way compatible with json.net

@1R053
Copy link
Collaborator

1R053 commented Feb 10, 2019

@nros @spinorkit I am happy to have a look at this, if there is still a need.
However, please provide some test cases, that can be a basis for the discussion of the optimal API changes. Ideally you can make some respective enhancements in test/typescript/ts.ts for the PR

@peey
Copy link

peey commented Mar 18, 2021

**Update: ** I think I misunderstood the intent of this PR. I might put this suggestion in a separate issue.

I believe this same feature could easily be achieved by defining this function

export function deserializeWithContext(context: Context, _class: any, serialized: any) {
  return deserializeObjectWithSchema(context, getDefaultModelSchema(_class)!, serialized, () => {}, undefined);
}

deserializeObjectWithSchema is (defined below)

export function deserializeObjectWithSchema(

But it is not a part of the serializr public api, and thus it is not re-exported by serializr

@nros
Copy link
Author

nros commented Mar 21, 2021

It's been a while. The project depending on this fix has already been abondoned and replaced by a Java+Vue re-implementation. I'll do my best to update my MR and provide some test cases within the next weeks.

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

Successfully merging this pull request may close these issues.

None yet

8 participants