Firefox has done awesome work here, so I apologize for stepping in as a "competitor", but Chrome DevTools can do what you're asking for with the combingation JavaScript LiveEdit and Workspaces for persistence:
That's quite nice, but it's only part of what I was asking for - it doesn't let you rewind. You have to reload the page each time if your edit was wrong.
It's not necessary to save state by each instruction, it's enough that it would be able to restart the current function.
Ideally it could walk back up the stack and restart other functions, but even if it was limited to just the function with the breakpoint that would be huge.
> You have to reload the page each time if your edit was wrong.
Nope. :) Whenever you hit Ctrl-S, the VM is patched with the new definition of the function (well, the entire file's functions, really), and then execution automatically restarts at the top of the call frame. Also, at any time, you can right-click any call frame in the "Call Stack" pane and select "Restart Frame".
You have to reload the page each time if your edit was wrong.
You'd have to do that anyway. If code is wrong, it corrupts state. Unless you're saying you want it to keep track of diffs of the heap, which might be interesting. But how would it handle, say, a socketIO connection that a bad edit terminates? There'd be no way to rewind that.
Maybe it doesn't matter for most work, since most work doesn't interact with persistent objects (sockets, file handles...)
> Unless you're saying you want it to keep track of diffs of the heap
Yup, that's exactly what I'm saying. Keep track of (store) the full browser state before entering a function, and when you rewind restore that exactly.
Local I/O is no problem, remote I/O will simply be restarted. Or it will error. It doesn't have to be perfect to be useful.
I've worked with this model a bit (I made a tool to watch the file system and automatically sync changed code into Chrome - plug: https://github.com/aidos/chromesync).
It turns out that corrupting state isn't always such a big issue. A load of what you end up doing in js is event handlers, and by being able to replace those in realtime you can save a load of dev time.
(As ever, when this conversation comes up I complain bitterly about how Chrome only allows a single websocket connection to the debugger so you need to do weird ws proxy stuff to use live reloading and devtools at the same time....)
I also use a similar thing to have live reloading in iPython for my backend work. Honestly, I'm not sure how I ever lived without being able to swap out the code in my functions without having to rebuild all the state. It's not without issue, and you _can_ corrupt your internal state, but in practice it's fine 98% of the time.
Live edit is great. It has its limits though. From a developer what I want is to mark some files / library for 'MRI execution'. When every line is hit in the file / function, it records the variable states, I can know what are the callers, callees, their states. I can go back in time, visualize call stacks as frame graph with the parameters invoked.
https://www.youtube.com/watch?v=WQZio5DlSXM https://developers.google.com/web/tools/chrome-devtools/debu... https://developers.google.com/web/tools/setup/setup-workflow...