# Some questions/notes on collab

**URL:** https://discuss.prosemirror.net/t/some-questions-notes-on-collab/600
**Category:** Uncategorized
**Created:** [January 29, 2017, 3:00am UTC](https://discuss.prosemirror.net/t/some-questions-notes-on-collab/600 "2017-01-29T03:00:41Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![kofifus](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/kofifus/32/288_2.png) [@kofifus](https://discuss.prosemirror.net/u/kofifus)
#### Post date: [January 29, 2017, 3:00am UTC](https://discuss.prosemirror.net/t/some-questions-notes-on-collab/600/1 "2017-01-29T03:00:41Z")

</div>

1. 

`getVersion` is defined as ‘Get the version up to which the collab plugin has synced with the central authority’, however if it is called before any `receiveTransaction` it still returns 0, the same as when only one version (version 0) was received. Can we have it so that in this case it returns -1 or null ? or maybe I’m confused and the first version is ver 1 ?

A related question which I think needs to be clarified in the docs, what is the version returned by `sendableSteps` ? is that the version we’re synced with or the one to be sent (that is the next one) ?

1. 

Can we have it so that the third parameter to `receiveTransaction` can optionally be a single clientID in which case it will apply to all the steps, I keep going through the hustle of bilding a clientIDs array of the same ID

1. 

I am missing an easy way to call `sendableSteps`, send them to the server and on success mark those steps as confirmed without going through `receiveTransaction` which is tricky to call in this case and goes through unnecessary rebasing of steps with my own clientID. I can then tell the server to not to notify me on that version change as I know it’s confirmed and save the roundtrip. Any thinking on that ?

1. 

Is there a way to distinguish transactions that don’t modify the editor content (ie cursor movement) so I can tell collab not to store such items on the server (so to not return them from `sendableSteps`)

1. 

Can there be a way to collapse steps ? ie for `sendableSteps` to collapse consequent adding of characters into one step ? this is important so save database space etc ?

1. 

In the case of a simple collab, `dispatchTransaction` does not change the editor state, so I do something like: `dispatchTransaction: transaction => { // get steps and send them, does not change editor state view.updateState(view.editor.state.apply(transaction)); }` Since this kind of thing is probably quite common can we have a shortcut so we can do: `dispatchTransaction: transaction => { // get steps and send them, does not change editor state return true; }`

thx !

---

<div class="post-metadata">

### Author: ![marijn](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/marijn/32/15_2.png) [@marijn](https://discuss.prosemirror.net/u/marijn)
#### Post date: [January 29, 2017, 9:09am UTC](https://discuss.prosemirror.net/t/some-questions-notes-on-collab/600/2 "2017-01-29T09:09:09Z")

</div>

> [@kofifus](#):
>
> Can we have it so that in this case it returns -1 or null ? or maybe I’m confused and the first version is ver 1 ?

You’re expected to initially set this to the version that corresponds to the initial document you gave the state. There is no special ‘before anything was received’ state – you have to start synced with a given version, or the plugin won’t work at all (it only syncs incrementally, never resets to a given full state).

> [@kofifus](#):
>
> what is the version returned by sendableSteps ?

The one from which the new steps _start_, so that the server knows which version they are compatible with.

> [@kofifus](#):
>
> Can we have it so that the third parameter to receiveTransaction can optionally be a single clientID in which case it will apply to all the steps, I keep going through the hustle of bilding a clientIDs array of the same ID

I’m not a fan of complicated special cased parameter types. I guess when you create an array from a single id, that’s your local client id? Would making the parameter optional and defaulting to ‘everything is local’ work for you?

> [@kofifus](#):
>
> I am missing an easy way to call sendableSteps, send them to the server and on success mark those steps as confirmed without going through receiveTransaction

I think going through `receiveTransaction` is simple enough in this case. And see [this thread](https://discuss.prosemirror.net/t/how-to-handle-edge-case-with-collab-module/288) for some background on why things work the way they do.

> [@kofifus](#):
>
> unnecessary rebasing of steps with my own clientID

`receiveTransaction` is written to not do useless rebasing when it doesn’t need to.

> [@kofifus](#):
>
> Is there a way to distinguish transactions that don’t modify the editor content (ie cursor movement) so I can tell collab not to store such items on the server (so to not return them from sendableSteps)

Yes, the `docChanged` property will tell you whether the document changed in a given transaction.

---

<div class="post-metadata">

### Author: ![marijn](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/marijn/32/15_2.png) [@marijn](https://discuss.prosemirror.net/u/marijn)
#### Post date: [January 29, 2017, 9:12am UTC](https://discuss.prosemirror.net/t/some-questions-notes-on-collab/600/3 "2017-01-29T09:12:21Z")

</div>

(Err, hit reply before finishing writing. Continued…)

> [@kofifus](#):
>
> Can there be a way to collapse steps ?

Yes, but not on the collab protocol level. For storing in your database, you can use [`Step.merge`](http://prosemirror.net/ref.html#transform.Step.merge) to simplify the sequence of steps you’re storing. (This is also done by the undo history to preserve memory.)

> [@kofifus](#):
>
> In the case of a simple collab, dispatchTransaction does not change the editor state

The idea is not to dispatch transactions when you’re not changing the editor state. I’m not sure why you’d need this. Could you elaborate?

---

<div class="post-metadata">

### Author: ![kofifus](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/kofifus/32/288_2.png) [@kofifus](https://discuss.prosemirror.net/u/kofifus)
#### Post date: [January 29, 2017, 10:23am UTC](https://discuss.prosemirror.net/t/some-questions-notes-on-collab/600/4 "2017-01-29T10:23:38Z")

</div>

> what is the version returned by sendableSteps ?

> The one from which the new steps start, so that the server knows which version they are compatible with.

would it be a correct the version returned by `sendableSteps` is **always** `getVersion()+1` ?

> Would making the parameter optional and defaulting to ‘everything is local’ work for you?

yes, that would be useful, but in a server that simply stores the result of sendableSteps, all versions will have a single client ID for that version of the client that created them on all steps, so that it will be useful also when receiving non local transactions

> Can there be a way to collapse steps ? Yes, but not on the collab protocol level. For storing in your database, you can use Step.merge to simplify the sequence of steps you’re storing

how do I apply `Step.merge` to an array of consequent steps (ie the one returned from `sendableSteps`) ? perhaps we can have a ‘mergeSteps’ flag to `sendableSteps` ?

> In the case of a simple collab, dispatchTransaction does not change the editor state The idea is not to dispatch transactions when you’re not changing the editor state. I’m not sure why you’d need this. Could you elaborate?

I need a `dispatchTransaction` handler in order to trigger a push to the server (in the same way that the collab demo does), or is there a way for me to get a ‘change’ event other than `dispatchTransaction` ?

thank you

---

<div class="post-metadata">

### Author: ![marijn](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/marijn/32/15_2.png) [@marijn](https://discuss.prosemirror.net/u/marijn)
#### Post date: [January 29, 2017, 8:32pm UTC](https://discuss.prosemirror.net/t/some-questions-notes-on-collab/600/5 "2017-01-29T20:32:56Z")

</div>

> [@kofifus](#):
>
> would it be a correct the version returned by sendableSteps is always getVersion()+1 ?

No, it’s exactly the same version as `getVersion` returns.

> [@kofifus](#):
>
> perhaps we can have a ‘mergeSteps’ flag to sendableSteps ?

No. On the collab protocol level, as things are now, you have to send the individual steps, so this wouldn’t work.

> [@kofifus](#):
>
> I need a dispatchTransaction handler in order to trigger a push to the server (in the same way that the collab demo does)

Yes, so that only needs to happen when there was an actual change to the state. How do transactions that don’t change the state come into this?

---

<div class="post-metadata">

### Author: ![kofifus](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/kofifus/32/288_2.png) [@kofifus](https://discuss.prosemirror.net/u/kofifus)
#### Post date: [January 30, 2017, 1:35am UTC](https://discuss.prosemirror.net/t/some-questions-notes-on-collab/600/6 "2017-01-30T01:35:45Z")

</div>

> perhaps we can have a ‘mergeSteps’ flag to sendableSteps ?

> No. On the collab protocol level, as things are now, you have to send the individual steps, so this wouldn’t work.

thx, I started a new discussion on this

> I need a dispatchTransaction handler in order to trigger a push to the server (in the same way that the collab demo does) Yes, so that only needs to happen when there was an actual change to the state. How do transactions that don’t change the state come into this?

Sorry, I need to clarify. the trasnsaction does change the state of course (ie a key pressed), but my handler (my code in my `dispatchTransaction`) does not. I am only suggesting syntactic sugar, so that in this case it will be enough to do

```
dispatchTransaction: transaction => {
// get steps and send them, does not change editor state 
return true;
}

```

instead of

```
dispatchTransaction: transaction => {
// get steps and send them, does not change editor state 
view.updateState(view.editor.state.apply(transaction));
}

```

that is if `dispatchTransaction` handler returns true, the framework will do `view.updateState(view.editor.state.apply(transaction))` for me
