purescript-react-redux icon indicating copy to clipboard operation
purescript-react-redux copied to clipboard

Redux devtools usability question

Open BartAdv opened this issue 8 years ago • 7 comments

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.

BartAdv avatar Jan 16 '17 14:01 BartAdv

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 [email protected] 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 .

ethul avatar Jan 17 '17 02:01 ethul

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)...

BartAdv avatar Jan 17 '17 05:01 BartAdv

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...

ethul avatar Jan 18 '17 23:01 ethul

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.

BartAdv avatar Jan 19 '17 06:01 BartAdv

Indeed, generic would work. Good idea.

ethul avatar Jan 19 '17 13:01 ethul

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.

zalmoxisus avatar Jan 24 '17 21:01 zalmoxisus

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

ethul avatar Jan 24 '17 22:01 ethul