trdis icon indicating copy to clipboard operation
trdis copied to clipboard

Browser and demo

Open benoitwimart opened this issue 6 years ago • 12 comments

It's look like something great but how to use it on browser ? I would like to make a undo/redo on an object, there is information but a real example (codepen or another) could be precious.

const past = [1, 2, 3]
const future = [1, 2, 3, 4]

const present = diff(past, future)

const future = Array.from({ ...past, ...present.do })

Not clear.

benoitwimart avatar Aug 02 '19 22:08 benoitwimart

Hi, thank you for your interest in T(a)rdis.

I tried to make all the examples that is needed to fully understand how T(a)rdis works.

The past/future/present term was (for me) the greater way to hilight how T(a)rdis works, but I can understand how it can be confusing.

When your use the diff function, you will get an object with both the do and undo key that are two objects to perform the actions to re-apply the change between the past and the future, or to undo the changes.

These objects are meant in the way that merging them with the source is how you apply the patch.

Merging source with patch.do will perform the action to move to target. And merging target with patch.undo will lead back to the source.

I hope I was clear, and will answer any of your further questions.

Swizz avatar Aug 22 '19 09:08 Swizz

Thank you. I understand at 99%, but make multiple changes, save diff in an array and play with this array when I do multiple undo and redo is not easy. I make it without diff in a big array of full json, it's work (without your script). I can do an undo and redo with t(a)rdis, but my json time machine never works for me.

For now my cheap solution works, but I spend a lot of time to make it better with your script. So a demo with history undo redo will be really appreciate for novices and me.

My json looks like '{a:[0, 1],b:[0, 0]}'.

benoitwimart avatar Aug 22 '19 17:08 benoitwimart

For this task, I urge to use the deep flag on the diff function, and the patch function that come with T(a)rdis, it will help your to handle all the patch stuff.

Given the following object :

{ 
  a: [0, 1],
  b: [0, 0]
}

if you perform the following change :

{ 
  a: [0, 1],
- b: [0, 0]
+ b: [1, 1]
}

Using the diff function that way :

const changes = diff(source, target, true)

will give you the following changes output :

{
  do: {
    a: { length: 2 }, 
    b: {0: 1, 1: 1, length: 2}
  },
  undo: {
    a: { length: 2 }, 
    b: { 0: 0, 1: 0, length: 2 }
  }
}

(Array are changed to objects in the diff result to only keep track of changed items, and length for added/removed items)

To apply the changes, I recommand you to use the patch function that use the exact same options/flags.

Undo changes :

const source = patch(target, changes.undo, true, true, true)

Redo changes :

const target = patch(source, changes.do, true, true, true)

The API reference is here : https://github.com/Swizz/trdis#api

Swizz avatar Aug 22 '19 18:08 Swizz

The 3 true flags are for respectivly :

deep The deep paramater allow you to create a deep patch object of nested objects.

array If the array parameter is set to true, arrays will be automatically returned if the length property is present (may break some things if you use a lengthproperty not for arrays too).

clean The patch function return an object with all the keys, the deleted properties will appear as undefined, unless you set the clean parameter to true.

Swizz avatar Aug 22 '19 18:08 Swizz

I try this : https://codepen.io/benoitwimart/pen/Vozgrq?editors=1012

benoitwimart avatar Aug 23 '19 09:08 benoitwimart

I see two misstakes and one bug of mine (I will fix it within the day).

First you need to use the diff this way : diff(old, new), so

   37   function dataDiffUpdate(){
   38     dataDiff = dataDiff.slice(0,historyPosition);
-  39     dataDiff.push(diff(data,_data,true,true,true));
+  39     dataDiff.push(diff(_data,data,true));
   40     _data = JSON.parse(JSON.stringify(data));
   41     historyPosition = dataDiff.length;
   42     console.log(historyPosition);
   43
   44   }

(diff only have one option : deep)

And this one, is more about how you use cursor to get the current change.

   29   function undo(){
   30     if(historyPosition>1){
   31       historyPosition--;
-  32       data = ( patch(data,dataDiff[historyPosition-1].undo,true,true,true)); 
+  32       data = ( patch(data,dataDiff[historyPosition].undo,true,true,true)); 
   33       console.log(JSON.stringify(data));
   34   
   35     }
   36   }

The bug I will fix is about how deep and array works.

Swizz avatar Aug 23 '19 10:08 Swizz

Oh yes, I remember on an other test the wrong switch between old and new :)

benoitwimart avatar Aug 23 '19 12:08 benoitwimart

The fix is now published under 1.0.1

Swizz avatar Aug 26 '19 08:08 Swizz

I will try in few days, thank you !

benoitwimart avatar Aug 26 '19 15:08 benoitwimart

Something go wrong :( I make 3 clicks, 3 undos, 3 clicks, 3 undos (the 2 undos is wrong) https://codepen.io/benoitwimart/pen/Vozgrq?editors=1010 :(

benoitwimart avatar Sep 02 '19 11:09 benoitwimart

it's look ok 👍 https://codepen.io/benoitwimart/pen/KKPXzVy?editors=1010

benoitwimart avatar Sep 02 '19 12:09 benoitwimart

Finaly, it's not 100% ok

from {a:[[1,1,1,1],0,0]} to {a:[[1,1,1,1],[1,1,1,1],0]} undo return an objet :( I have {a:[{0:1,1:1,2:1,3:1},0,0]}

Here https://codepen.io/benoitwimart/pen/xxxKyJv?editors=1011

benoitwimart avatar Oct 04 '19 08:10 benoitwimart