ethul / purescript-react-redux

MIT License
15 stars 6 forks source link

Redux devtools usability question #4

Open BartAdv opened 7 years ago

BartAdv commented 7 years ago

Hi,

Do you have any tips for improving experience with redux devtools? It prints JSON representation of the runtime data, which means that sometimes it just doesn't show relevant info, for example empty constructor of a sum type is displayed as {} (chrome would display ConName {} where ConName is just constructor.name of the JS object).

I was able to improve it a bit by hooking own JSON replacer, but it's far from complete.

ethul commented 7 years ago

I agree that the view of the actions are currently not too useful in the redux devtools. I will have to take a closer look at how to improve this. I am open to ideas or suggestions.

Hooking into the JSON replacer sounds promising. Good idea.

On Mon, Jan 16, 2017 at 09:52 Bartosz notifications@github.com wrote:

Hi,

Do you have any tips for improving experience with redux devtools? It prints JSON representation of the runtime data, which means that sometimes it just doesn't show relevant info, for example empty constructor of a sum type is displayed as {} (chrome would display ConName {} where ConName is just constructor.name of the JS object).

I was able to improve it a bit by hooking own JSON replacer, but it's far from complete.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/ethul/purescript-react-redux/issues/4, or mute the thread https://github.com/notifications/unsubscribe-auth/AAVYy1oIFMTH4DATm4RgIvHKWBuPRwGrks5rS4QVgaJpZM4Lkoyv .

BartAdv commented 7 years ago

I currently got away with following hack:

var cfg = {
    serialize: {
        // hacks for PS ADTs
        replacer: function (key, value) {
            if (typeof value === "object" && !Array.isArray(value)) {
                var replacement = {};
                for (var k in value) {
                    if (Object.hasOwnProperty.call(value, k)) {
                        if(k == "value0") {
                            replacement[value[k].constructor.name] = value[k];
                        } else {
                                replacement[k] = value[k];
                        }
                    }
                }
                return replacement;
            }
            return value;
        }
    }
};

exports.reduxDevtoolsExtensionEnhancer_ = !window.__REDUX_DEVTOOLS_EXTENSION__ ? function(k){return k;} : window.__REDUX_DEVTOOLS_EXTENSION__(cfg);

This gives something like this:

{
  type: '@@PURESCRIPT_REACT_REDUX/Login',
  action: {
    AttemptLogin: {
      LoginData: {
        Object: {
          username: 'admin',
          password: 'pass'
        }
      }
    }
  }
}

but it doesn't do anything useful with contructors that don't take any values. (And I don't have corresponding reviver, so it probably breaks possibility to store state and load from there)...

ethul commented 7 years ago

Nice. Thanks for sharing.

I wonder if there is a way to move the serialize/deserialize into PureScript and use Argonaut's EncodeJson and DecodeJson. This would mean that Action would have to have these instances though...

BartAdv commented 7 years ago

I guess just Generic instance would do. I asked around an some people on IRC suggested using 'purescript-foreign-generic'. Now, I dont know what are exact differences yet, but you're right it would first require change in devtools to allow own serialise/deserialize. Probably doable, but will require some time, so for now Im Rolling with above hack.

ethul commented 7 years ago

Indeed, generic would work. Good idea.

zalmoxisus commented 7 years ago

Maybe it could be similar to the way we support ImmutableJS. Redux Extension allows you to mark specific data, adding a __serializedType__ key. So you can deserialize it back while importing or persisting data. Moreover, it will also show a nice preview showing the native type:

screen shot 2017-01-08 at 1 00 22 pm

As for classes, apart from replacer and reviver for serializeparameter, there's an undocumented refs key. So in replacer you can compare if the data is an instance of that class and mark correspondingly, like we do for Immutable Record classes.

Also you could send data to the extension right from PureScript, but you'll have to implement monitor actions by yourself in this case.

ethul commented 7 years ago

Wow! Thanks @zalmoxisus for the ideas and pointers. This looks like just what we need.

https://github.com/zalmoxisus/redux-devtools-extension/blob/master/docs/API/Arguments.md#parameters

zalmoxisus/redux-devtools-extension#278