Some questions/notes on collab

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) ?

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 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 ?

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)

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 ?

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 !

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).

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

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?

I think going through receiveTransaction is simple enough in this case. And see this thread for some background on why things work the way they do.

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

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

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

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. (This is also done by the undo history to preserve memory.)

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?

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

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

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

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?

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