Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fetch snapshot of previous version #45

Closed
codingisacopingstrategy opened this issue Mar 2, 2015 · 8 comments
Closed

Fetch snapshot of previous version #45

codingisacopingstrategy opened this issue Mar 2, 2015 · 8 comments

Comments

@codingisacopingstrategy
Copy link

Hello—

The docs state how I can fetch the operations leading up to a previous version, but not how I can apply these operations to then obtain a snapshot of that version. I wonder if you could add this to the docs?

Feature request: ideally, I would be able to pass a version argument to the fetch method, to directly request a snapshot of a certain version.

Thanks for share.js and kind regards,

@g-borgulya
Copy link

@codingisacopingstrategy do you have a workaround for this?

@curran
Copy link
Contributor

curran commented Nov 30, 2016

@g-borgulya @codingisacopingstrategy See this related thread josephg/ShareJS#12

From there, here's an implementation of getSnapshotAtRevision by @luto . The algorithm is:

  • Fetch the current snapshot
  • Fetch the ops between the current snapshot and the desired snapshot
  • For each op in reverse order, invert it and apply it to the snapshot.

Here's a copy of the implementation (authored by @luto):

function getSnapshotAtRevision(docname, v, cb)
{
  var snapshot
    , ops = []

  async.waterfall(
    [
      // get latest revision
      function (cb)
      {
        model.getSnapshot(docname,
          function (err, _snapshot)
          {
            snapshot = _snapshot;
            cb(err);
          }
        );
      },
      // get ops that happend between `v` and `snapshot.v`
      function (cb)
      {
        if(v == snapshot.v)
          return cb();

        model.getOps(docname, v, snapshot.v,
          function (err, _ops)
          {
            ops = _ops;
            cb(err);
          }
        );
      },
      // invert and apply ops
      function (cb)
      {
        var json = sharejs.types.json;
        var content = snapshot.snapshot;
        var err = null;

        try
        {
          for (var i = ops.length - 1; i >= 0; i--) // reverse order
          {
            var op = ops[i].op;
            op = json.invert(op);
            content = json.apply(content, op);
          }
        }
        catch (_err)
        {
          err = _err;
        }

        cb(err, content);
      }
    ],
    cb
  );
}

@g-borgulya
Copy link

Nice!! Thank you, @curran .

@curran
Copy link
Contributor

curran commented Dec 1, 2016

@g-borgulya My pleasure! It would be amazing to integrate something like this into the project. One possible stumbling block is that I'm not sure all OT Types are invertable. Maybe there could be a variant that builds up the doc by replaying all ops in the forward direction from the beginning.

@curran
Copy link
Contributor

curran commented May 24, 2017

I started packaging the above code into a library: https://github.com/curran/sharedb-snapshot/tree/master

@nickasd
Copy link

nickasd commented Jun 27, 2017

I agree that this would be a useful feature. I'm implementing a search and replace feature and in this case it would be useful being able to apply the replace operations on the snapshot version at the time of the search; applying the replace operations on the current version could not work if a change is applied in the meantime.

@luto
Copy link

luto commented Jun 27, 2017

@curran nice, thank you ;)

@alecgibson
Copy link
Collaborator

This was implemented in #220

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants