Widdershin / rx-undoable

Easily add undo and redo to your RxJS or Cycle.js apps
MIT License
22 stars 0 forks source link

Set the size of the undo history #7

Open afhole opened 7 years ago

afhole commented 7 years ago

Is there any way to set the size of the history 'window'? i.e. only store the last n copies? Also is there any way to skip a number (or just the first) state in the history? I'm trying to work out how I can avoid undo returning to the seed state, so it can never go back past the first updated value.

Widdershin commented 7 years ago

Is there any way to set the size of the history 'window'? i.e. only store the last n copies?

Not currently, but this would be very doable. I'll have a play.

is there any way to skip a number (or just the first) state in the history? I'm trying to work out how I can avoid undo returning to the seed state, so it can never go back past the first updated value.

Just curious, why is this useful? If you could give me an example of where you might apply this it's easier for me to consider.

Widdershin commented 7 years ago

I've just released v0.4.0 with the ability to pass an options object with {historySize: 100} or similar.

Could you give it a go and let me know if it meets your use case?

Widdershin commented 7 years ago

Usage is like:

undoableScan(
  numbers$,
  (total, change) => total + change,
  0,
  undo$,
  redo$,
  {historySize: 50}
);
afhole commented 7 years ago

That's awesome! Thank you - I will try it out as soon as I can.

Regarding my other note (sorry, maybe it should have been a separate ticket) the general idea is this: I would like to have a way of signalling to the scan that an update should overwrite the present state instead of creating a new one and adding the old one to the history. This way it would become easy to do certain things like: Have undo 'milestones' so you could for example batch a load of updates, and an undo would revert that entire batch of updates. If the initial seed value is something that you wouldn't want to revert to, you could mark the second update as a 'milestone' so it would overwrite the seed value in the history, and that way you could only undo to that safe 'milestone' copy of the state.

An example for us is having the seed value as an empty object (actually an Immutable.js Record) which is then replaced with a full document object loaded from an API - with this idea it would then not be possible to undo and revert to the seed state before the document was loaded.

I hope that make sense! Whether it is beyond the scope of a simple undoable scan is another question. I'm not sure how I would go about implementing it - initial ideas are to either have each new value coming into the scan be a tuple of value + a constant denoting whether or not it should overwrite the present or whether it should add a new state to the past history; or possibly have that constant as part of the accumulator (but then that blurs the responsibilities between the scan and the update operation).

Hopefully that is a decent explanation of my reasoning - I'd be very interested to hear your thoughts. And thanks again for adding historySize - it's neat having a config object for that to keep the arity sane.