-
Notifications
You must be signed in to change notification settings - Fork 28
Description
We've spent quite some time debugging one very strange issue. The effect was in Immutable.List being serialized and later de-serialized into Immutable.Map.
I will try to explain the problem as short as possible and suggest a solution at the end.
Summary
instanceof comparisons of transit-js fails to compare Immutable types if we have multiple immutable libraries used.
Explanation
We are using Lerna monorepo and all internal packages there are symlinked (the same effect can happen if you use npm link without doing work in monorepo at all)
Bootstrapped working project structure:
packages
app
node_modules
immutable
->lib
lib
node_modules
immutable
As you can see symlinked lib will also have its own immutable like:
packages
app
node_modules
immutable
->lib
node_modules
immutable
lib
node_modules
immutable
As soon as we export anything Immutable in lib and use it in app, trying to serialize the state would result in fallback to the default case of transit-immutable-js:
"default", transit.makeWriteHandler({
tag: function() {
return 'iM';
}The reason for that is transit-js tries to do a match by using instanceof and lib->Immutable.List does not match app->Immutable.List
Possible solution
Instead of passing a mapping of Immutable.X to transit-js always use default case and use native ImmutableJS methods like Immutable.List.isList(obj) to do matching.
We checked that in the app's code and Immutable.List.isList(obj) works perfectly no matter what immutable is used there.
We did not check this on transit-immutable-js code yet. Need to see if it even possible (would be if transit-js somehow gives obj back to tag function of writeHandler