Now, I have the pleasure to welcome you, Seth, who was also cognizant of this devroom and
Nick.
They will talk about blocknote, prosmeagall, and YGS version 14, versioning, and track changes.
This way, come then, there's a round of applause.
Nice, thanks.
Welcome, so we're Nick, and I'm YSF, together we work on blocknote, which is like a notion style
of rich text editor that makes it like tries to hide away all the annoying rich text editor
stuff and tries to make it easy to add a modern rich text editor to your app.
For that, we built a lot on top of YGS, well, I don't need to introduce that anymore.
I do need to introduce Kevin, like of course, we all rely on a lot of his work for YGS,
and in this presentation, we'll introduce the work that we've been prototyping in November
and December, together with Kevin, and it's our honor to also share a lot of the work he has been doing.
Unfortunately, for him, he's out on the slope skiing, well, we are having fun at Boston.
So he's certainly could make it, but he definitely says hi.
This work has been sponsored by Zendis and Dinam, so these are respectively initiatives in Germany and France
to advance our digital autonomy, so they're building a product that's called last week's docs,
and they're building it in-house, which is like a new software for public servants to collaborate together
and reduce the dependency on big text software.
Quick overview of what we'll be going through, so I'll explain what we're working on,
there will be a short demo, we'll do an architectural overview, and then Nick will dive deep into,
what does that mean in terms of like the new APIs that we're bringing to YGS,
that unlock all these kind of things and the new things in lock nodes and Y pros mirror as well.
So what are we talking about?
There's two main subjects that we're trying to add to make possible within the new versions.
It's suggestions, track changes, so if you know you're in a doc style document,
and you enable suggestion mode from that on everything that it becomes a suggestion and not an added to the original document,
and attributions and attributions is like metadata with which you can get detailed version history,
so not only compare to versions, but really also see who did what in which version of the document.
It should be a video here, it's not loading, but everybody knows how I'll just walk through it.
So you probably know the Google Docs style track changes suggestions, so once one user proposes a change,
it turns up and green, if you remove some text that turns up and red,
and then the author of the document, for example, can accept and reject certain changes.
You can also hover changes and see who made that change and who did it when.
And the demo was showing it within block node.
We're intended to change.
I'm not sure whether it's not set setting up, but I'm glad we got this screen connected at all,
so I'm not going to be bothered by the diving in further.
So once it's talk a little bit about the architecture of how we want to make this possible,
like a very naive approach might be, okay, you enter suggestion mode, and from then on everything that you type,
we just store as something instead of marking something as bold that you type, we mark it as an insertion that's like pending.
Now we don't want to do this, so this is like, okay, we consider that a better idea to store it in a document,
just have, hello, as the original thing, the mark something as deleted and the mark something as inserted.
Now why do we not want to follow that architecture?
First of all, we want to do this in a secure way.
So if you do it like this, the suggesting user, the user who is making changes while suggesting mode,
would need to make these changes in the original document.
But maybe you want to add support for suggestion only users, so those are users who only have permissions to make suggestions,
but not the permission to edit the underlying the original document.
So that's an important reason, and the other reason is, in general, we don't think it's a good concept to think that suggestions are part of the original document.
And to really decouple this, it also unlocks a lot of innovative use cases, novel experiences in which users can collaborate.
Maybe also worthwhile to point to some of the research done by InConswitch and Peter Steam.
I think mostly in the patchwork projects.
The authors are right here also, who show, okay, we can think about collaboration in different ways.
But if you want to unlock that, you do need to separate these concerns and really have different versions of these documents,
and then decide how you want to present that to the user.
So, how do we make this possible?
The architecture that we are going for is to model things similarly to get branches.
So suggestions are like get branches, so you can imagine, okay, instead of everybody working in the same documents,
you use the who starts suggesting kind of like branches and new YGS documents and starts making the edits there.
Now there's a couple of changes, if you, differences, if you compare it to get.
When you're in a suggestion mode, you also want to see what happens to the original document.
So it's kind of like the base, the changes from the base are continuously streamed in to the fork that you're working on.
So that's a third one.
Then there's also like different user modes.
So you can have a user that's suggesting changes.
Well, that's fairly easy, you just made all the edits that that user make.
Go to the fork, so to the other new fork YGS document.
If you turn suggestions off, it's also easy, you just, all your edits go to the original YGS document.
So you're working on the base branch, so to say.
It gets a little bit different in the more difficult in the third scenario.
I'll explain that in a bit.
Because now what happens, this is what I just explained.
So okay, changes made, if you're looking at the base document, just go here.
Changes from the base are continuously synced to the branch, because you want to make sure you want to have that live feeling and see also what you're suggesting.
Not on a previous version of the document, but on the actual live latest base document.
But you can also have the edit view where you're making suggestions and you see both at the same time.
Now it will depend if you're the original author.
The system needs to know where should that change go.
Should it go to the base document or to the branch?
If you work in a way that, okay, if you edit in hello, it will commit that to the base branch.
But if you make a change to Brussels, that word actually doesn't exist in the base branch.
So the update will feel there and when it feels, it will actually make it to the suggestion branch.
So that's how we recognize where to make these changes.
And why do you have handles that internally?
Soon.
Then attributions, so hold off on suggestions and instructions for a moment.
So we're also working on attributions.
And this is the reason for this is, okay, we want to go back in time in the document and be able to see who did what went.
And as you might know, in YGS, every character can be uniquely identified.
And attributions basically are a character level metadata.
So, yeah, you can attach metadata to specific ranges of YGS.
YGS IDs.
For this, Kevin has worked on a more efficient data structure to store this kind of these ranges and to map that with your metadata.
So we go set an ID map.
But the metadata itself, it can be application defined.
So it's not tied to author information or timestamps.
If you like, you can, like, I don't know, as a user is typing,
store the current weather information.
And I'm sure if you look at my stuff that I write, my write, write something better when the weather is good.
And maybe I get very depressed.
I don't know, whatever is relevant for your application.
Yeah, now, okay, let's have a look at what makes this possible.
So to make this possible, we've been able and Kevin, and Nick, particularly,
they've collaborated a lot on making this possible in YGS and Y prosumerer.
And Nick will go through the different changes that you can expect in YGS 14.
Yeah, so, as you said, men's in Kevin has done the bulk of this work, obviously,
and it's an honor that I'm able to present it.
So to put this in perspective, YGS 13 was cut six years ago.
And Kevin has anxiety, every single time he pushes the release button,
because it affects millions of applications.
And there's so much impact to this project.
So with YGS 14, there's a number of large updates that have been made.
And so this is an overview that I'll go through as we talked about it.
So one of the changes that we've made with YGS 14 is, as we were working on the code base,
we realized that, and I'll say we, but this is all Kevin, it's just easier to say it.
So we realized that what it turns out is that all of the underlying operations
were operating on the same sort of data structure.
And you can actually represent most of the data structures that YGS supports,
so anything that's basically in a JSON sort of format.
You can map them one to one to some sort of an XML.
So for example, you have this Y text that is just a non-named XML fragment,
that has no attributes, and it has children as plain text content.
And array is just a number of items within that same sort of fragment.
A map is some sort of a key value attribute pair.
And an XML element is the full blown thing.
It has a name, it has attributes and children inside of it.
So it was a huge simplification to the code base.
It was beautiful to see the GitHub PR to see that thousands of lines were deleted,
and only a few hundred added.
So we were able to completely remove all of the other types.
And now there's just one type that is based on this XML structure.
And you can define a schema to your YGS document that will actually differentiate between these types,
so that you still know what's inside of.
So this is, there's a strong schema that defines a YGS document now,
rather than it just being a grab bag of whatever values happened to be set at the time.
So now that we have this one unified Y type,
we need to have a way to describe changes to the type.
As part of the work for suggestions and attributions,
it became clear that we needed a universal way to describe these changes,
and Kevin has always been a fan of the Quill Delta format.
And this is based on that format.
So what, how we can describe a transformation from hello world to hello with the next formation point,
added, is you can describe it as, as though you were, as though you were user interacting with it.
So what you do is you move the cursor five, five characters over,
you delete the world at the end of it,
and then you insert the actual new character.
So you're describing a change as all of the operations that you would do on the document.
So with this ends up being, is that there's a literal array that describes all of the changes.
This is a very similar to OT for those that are familiar with this.
But what ends up happening is that we have a transaction log of all of the changes that have happened to a document.
So you can do a lot of things with this transaction log.
So not only do you can apply this to a Y type to get the output to actually apply,
and do that in a way that is obviously CODT based and using the Y adjust data structure.
But you can also operate exclusively on these operations.
So you can merge several operations together to get one change.
You can re-base operations.
There's a whole bunch of new functionality that we can do.
So getting back to suggestions and attributions here.
This is a little bit about how the attribution manager works.
I didn't want to go into the details of how this is actually represented,
like in the data format using IDSats, ID maps.
So I wanted to just explain this in a way that it's a little bit more palatable for the average developer,
but please ask me more about this later.
So what I did here was explain a YJS update as there's the actual content of what has actually changed within the update.
So for example, this is an addition of hello.
Normally this would be a character level and this describes a range of updates and they're merged together.
But this is a simplification.
And then there's also a number of ID metadata.
So I'm referring to it as a content ID here.
But it's think of it as some sort of a version identifier.
This is the version that was applied to the YJS document.
It can get complicated to explain CRDT things.
So I feel like it was just easier to describe the attribution manager as essentially a map between those versions,
which technically describe multiple changes.
You can describe ranges of changes, mapping those versions to actual arbitrary metadata.
So I have that it's attributed to Nick and some sort of timestamp.
It can be any sort of Json representable metadata.
So then once we have that in the attribution manager, this attribution manager is meant to be stored in a secure way.
So for example, this might be stored on a central server if this is your off model.
It could be some sort of a peer-to-peer system, some sort of trust model, whatever it is.
The point is that it's a separate store of this attribution metadata.
So that you can be sure and confident in what's inside of it.
So you can't have in personation of users or anything like that to say that who made what update at what time.
That's essentially what this store is meant to do.
So once we have that store of data, then there's we have a lot of flexibility on how we actually read out that data.
We can ask for specific ranges of versions.
We can ask for what content is what is attributed to what.
So for example, you could say that like, okay, this range of characters is owned by Nick.
Yes or no, whatever, and you can pull out that data from the store.
So one way of pulling out that data is through this concept of a content renderer.
And this gets more to the level of what I actually got to work on.
So for example here, we have two documents.
Now what we can do is the content renderer's job is to take external sources of data and represent them in a way that it can still.
You can still modify the source documents.
So it's using, for example, you can take the diff between two documents and you can show what was actually changed.
So this would be represented as you get the entire document content as a delta.
And then you dip the two deltas to see what is actually changed.
The content renderer is what is responsible for saying this portion of content was deleted.
This portion of content was added between these two versions.
Another use case for the content renderer is this attribution view.
So what you can do is using the attribution manager that we showed before.
You can take a range of content and figure out who was attributed to this content.
Then on top of that you can do additional things such as dipping and attribution at the same time.
So you are not only able to do a difference between the documents but see what was the attribution for that content.
So this is very important.
This is the core of what a track changes like feature is.
We have separation of the content data sources.
We have a separate store which is the attribution manager to store this all security.
Okay.
So then we have Wi-Pro's mirror which is Wi-Pro's mirror is we have Pro's mirror as a rich text editor for editing documents on the web.
It's an industry standard and is what a document is based on.
Wi-Pro's mirror is a binding between the Wi-JS document.
That's in data and the Pro's mirror document that is in memory.
So Wi-Pro's mirror's job is to then synchronize the changes between these two documents.
So if a change comes in from a remote then that changes the editor state or you make a local change to your document.
That sinks it back to the Wi-JS document and it sinks to other clients.
So this is where everything pretty much comes together.
We have the Delta format for actually being able to describe what those changes are.
You have the content renderer for displaying those changes.
And we have to completely rewrite the Wi-Pro's mirror binding.
And with that there's a number of improvements that we've made.
And one of them is to bring this content renderer functionality into that.
And as part of that you would need to like be able to pause and resume sync because if you're in a dipping mode you don't expect to actually properly edit the document.
If you're looking at like static versions.
So there's a number of improvements that we've made.
Thanks.
I think that though.
Thank you very much.
You said a link.
We will take questions in the room.
Please raise your hand.
All of you now.
No harm any questions.
We have one question.
Two questions.
Three.
No.
I may be not a question but a clarification.
Like most of those features were already possible.
But the way how they were implemented to permanent user data.
This is how this features call it.
VGS is that it's far from ideal starting from the fact that this is all data part of the data is part of the document itself.
But now where the cabinet's work it will be much more powerful.
And it will allow to have more features on top of that basically.
I totally deferred to Bertosh for anything.
Why did you just relate it?
Is that any question in the room?
More questions.
Okay.
So we can wrap it up.
But I'm not sure if you want to add something.
No, yes.
Only that the largest 14 preview is available.
But there's still a lot of this to quite some.
It's like I would say alpha versus so we expected to be available later.
This year.
And then.
Yeah, the then we'll also release the layers on top of it.
So why pros mayor for the binding to raw pros mayor things.
And then block notes our vision is to really provide a high level API.
So really to abstract as much of this away for you and just say okay.
Enter suggestion mode.
And there will be a little bit later.
But also hope to release that somewhere this year.
Okay.
Thank you very much again.
Thank you.
So.