WEBVTT

00:00.000 --> 00:13.400
Now, I have the pleasure to welcome you, Seth, who was also cognizant of this devroom and

00:13.400 --> 00:14.400
Nick.

00:14.400 --> 00:21.320
They will talk about blocknote, prosmeagall, and YGS version 14, versioning, and track changes.

00:21.720 --> 00:24.120
This way, come then, there's a round of applause.

00:30.120 --> 00:31.720
Nice, thanks.

00:31.720 --> 00:40.000
Welcome, so we're Nick, and I'm YSF, together we work on blocknote, which is like a notion style

00:40.000 --> 00:45.320
of rich text editor that makes it like tries to hide away all the annoying rich text editor

00:45.320 --> 00:49.720
stuff and tries to make it easy to add a modern rich text editor to your app.

00:49.920 --> 00:55.920
For that, we built a lot on top of YGS, well, I don't need to introduce that anymore.

00:57.120 --> 01:02.720
I do need to introduce Kevin, like of course, we all rely on a lot of his work for YGS,

01:02.720 --> 01:09.920
and in this presentation, we'll introduce the work that we've been prototyping in November

01:09.920 --> 01:17.520
and December, together with Kevin, and it's our honor to also share a lot of the work he has been doing.

01:18.520 --> 01:24.920
Unfortunately, for him, he's out on the slope skiing, well, we are having fun at Boston.

01:24.920 --> 01:29.520
So he's certainly could make it, but he definitely says hi.

01:29.520 --> 01:39.520
This work has been sponsored by Zendis and Dinam, so these are respectively initiatives in Germany and France

01:39.520 --> 01:45.520
to advance our digital autonomy, so they're building a product that's called last week's docs,

01:45.520 --> 01:51.520
and they're building it in-house, which is like a new software for public servants to collaborate together

01:51.520 --> 01:56.520
and reduce the dependency on big text software.

01:58.520 --> 02:05.520
Quick overview of what we'll be going through, so I'll explain what we're working on,

02:05.520 --> 02:12.520
there will be a short demo, we'll do an architectural overview, and then Nick will dive deep into,

02:12.520 --> 02:17.520
what does that mean in terms of like the new APIs that we're bringing to YGS,

02:17.520 --> 02:24.520
that unlock all these kind of things and the new things in lock nodes and Y pros mirror as well.

02:28.520 --> 02:29.520
So what are we talking about?

02:29.520 --> 02:34.520
There's two main subjects that we're trying to add to make possible within the new versions.

02:34.520 --> 02:39.520
It's suggestions, track changes, so if you know you're in a doc style document,

02:39.520 --> 02:46.520
and you enable suggestion mode from that on everything that it becomes a suggestion and not an added to the original document,

02:46.520 --> 02:54.520
and attributions and attributions is like metadata with which you can get detailed version history,

02:54.520 --> 03:00.520
so not only compare to versions, but really also see who did what in which version of the document.

03:09.520 --> 03:16.520
It should be a video here, it's not loading, but everybody knows how I'll just walk through it.

03:16.520 --> 03:23.520
So you probably know the Google Docs style track changes suggestions, so once one user proposes a change,

03:23.520 --> 03:27.520
it turns up and green, if you remove some text that turns up and red,

03:27.520 --> 03:34.520
and then the author of the document, for example, can accept and reject certain changes.

03:35.520 --> 03:41.520
You can also hover changes and see who made that change and who did it when.

03:41.520 --> 03:44.520
And the demo was showing it within block node.

03:44.520 --> 03:46.520
We're intended to change.

03:46.520 --> 03:51.520
I'm not sure whether it's not set setting up, but I'm glad we got this screen connected at all,

03:51.520 --> 03:55.520
so I'm not going to be bothered by the diving in further.

03:55.520 --> 04:00.520
So once it's talk a little bit about the architecture of how we want to make this possible,

04:01.520 --> 04:07.520
like a very naive approach might be, okay, you enter suggestion mode, and from then on everything that you type,

04:07.520 --> 04:16.520
we just store as something instead of marking something as bold that you type, we mark it as an insertion that's like pending.

04:16.520 --> 04:21.520
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,

04:21.520 --> 04:28.520
just have, hello, as the original thing, the mark something as deleted and the mark something as inserted.

04:28.520 --> 04:32.520
Now why do we not want to follow that architecture?

04:32.520 --> 04:35.520
First of all, we want to do this in a secure way.

04:35.520 --> 04:41.520
So if you do it like this, the suggesting user, the user who is making changes while suggesting mode,

04:41.520 --> 04:44.520
would need to make these changes in the original document.

04:44.520 --> 04:51.520
But maybe you want to add support for suggestion only users, so those are users who only have permissions to make suggestions,

04:51.520 --> 04:57.520
but not the permission to edit the underlying the original document.

04:57.520 --> 05:09.520
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.

05:09.520 --> 05:19.520
And to really decouple this, it also unlocks a lot of innovative use cases, novel experiences in which users can collaborate.

05:20.520 --> 05:26.520
Maybe also worthwhile to point to some of the research done by InConswitch and Peter Steam.

05:26.520 --> 05:31.520
I think mostly in the patchwork projects.

05:31.520 --> 05:37.520
The authors are right here also, who show, okay, we can think about collaboration in different ways.

05:37.520 --> 05:44.520
But if you want to unlock that, you do need to separate these concerns and really have different versions of these documents,

05:44.520 --> 05:52.520
and then decide how you want to present that to the user.

05:52.520 --> 05:55.520
So, how do we make this possible?

05:55.520 --> 06:01.520
The architecture that we are going for is to model things similarly to get branches.

06:01.520 --> 06:08.520
So suggestions are like get branches, so you can imagine, okay, instead of everybody working in the same documents,

06:08.520 --> 06:16.520
you use the who starts suggesting kind of like branches and new YGS documents and starts making the edits there.

06:16.520 --> 06:22.520
Now there's a couple of changes, if you, differences, if you compare it to get.

06:22.520 --> 06:28.520
When you're in a suggestion mode, you also want to see what happens to the original document.

06:28.520 --> 06:35.520
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.

06:35.520 --> 06:37.520
So that's a third one.

06:37.520 --> 06:40.520
Then there's also like different user modes.

06:40.520 --> 06:43.520
So you can have a user that's suggesting changes.

06:43.520 --> 06:48.520
Well, that's fairly easy, you just made all the edits that that user make.

06:48.520 --> 06:54.520
Go to the fork, so to the other new fork YGS document.

06:54.520 --> 07:01.520
If you turn suggestions off, it's also easy, you just, all your edits go to the original YGS document.

07:01.520 --> 07:05.520
So you're working on the base branch, so to say.

07:05.520 --> 07:09.520
It gets a little bit different in the more difficult in the third scenario.

07:09.520 --> 07:11.520
I'll explain that in a bit.

07:11.520 --> 07:15.520
Because now what happens, this is what I just explained.

07:15.520 --> 07:20.520
So okay, changes made, if you're looking at the base document, just go here.

07:20.520 --> 07:29.520
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.

07:29.520 --> 07:38.520
Not on a previous version of the document, but on the actual live latest base document.

07:38.520 --> 07:45.520
But you can also have the edit view where you're making suggestions and you see both at the same time.

07:45.520 --> 07:50.520
Now it will depend if you're the original author.

07:50.520 --> 07:54.520
The system needs to know where should that change go.

07:54.520 --> 07:56.520
Should it go to the base document or to the branch?

07:56.520 --> 08:02.520
If you work in a way that, okay, if you edit in hello, it will commit that to the base branch.

08:02.520 --> 08:06.520
But if you make a change to Brussels, that word actually doesn't exist in the base branch.

08:06.520 --> 08:11.520
So the update will feel there and when it feels, it will actually make it to the suggestion branch.

08:11.520 --> 08:14.520
So that's how we recognize where to make these changes.

08:14.520 --> 08:17.520
And why do you have handles that internally?

08:17.520 --> 08:21.520
Soon.

08:22.520 --> 08:28.520
Then attributions, so hold off on suggestions and instructions for a moment.

08:28.520 --> 08:30.520
So we're also working on attributions.

08:30.520 --> 08:37.520
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.

08:37.520 --> 08:42.520
And as you might know, in YGS, every character can be uniquely identified.

08:42.520 --> 08:47.520
And attributions basically are a character level metadata.

08:47.520 --> 08:54.520
So, yeah, you can attach metadata to specific ranges of YGS.

08:54.520 --> 08:56.520
YGS IDs.

08:56.520 --> 09:03.520
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.

09:03.520 --> 09:06.520
So we go set an ID map.

09:06.520 --> 09:09.520
But the metadata itself, it can be application defined.

09:09.520 --> 09:12.520
So it's not tied to author information or timestamps.

09:13.520 --> 09:17.520
If you like, you can, like, I don't know, as a user is typing,

09:17.520 --> 09:19.520
store the current weather information.

09:19.520 --> 09:26.520
And I'm sure if you look at my stuff that I write, my write, write something better when the weather is good.

09:26.520 --> 09:28.520
And maybe I get very depressed.

09:28.520 --> 09:36.520
I don't know, whatever is relevant for your application.

09:36.520 --> 09:40.520
Yeah, now, okay, let's have a look at what makes this possible.

09:40.520 --> 09:45.520
So to make this possible, we've been able and Kevin, and Nick, particularly,

09:45.520 --> 09:51.520
they've collaborated a lot on making this possible in YGS and Y prosumerer.

09:51.520 --> 09:57.520
And Nick will go through the different changes that you can expect in YGS 14.

09:57.520 --> 10:05.520
Yeah, so, as you said, men's in Kevin has done the bulk of this work, obviously,

10:05.520 --> 10:09.520
and it's an honor that I'm able to present it.

10:09.520 --> 10:15.520
So to put this in perspective, YGS 13 was cut six years ago.

10:15.520 --> 10:20.520
And Kevin has anxiety, every single time he pushes the release button,

10:20.520 --> 10:25.520
because it affects millions of applications.

10:25.520 --> 10:28.520
And there's so much impact to this project.

10:28.520 --> 10:35.520
So with YGS 14, there's a number of large updates that have been made.

10:35.520 --> 10:44.520
And so this is an overview that I'll go through as we talked about it.

10:44.520 --> 10:55.520
So one of the changes that we've made with YGS 14 is, as we were working on the code base,

10:55.520 --> 11:04.520
we realized that, and I'll say we, but this is all Kevin, it's just easier to say it.

11:04.520 --> 11:11.520
So we realized that what it turns out is that all of the underlying operations

11:11.520 --> 11:15.520
were operating on the same sort of data structure.

11:15.520 --> 11:20.520
And you can actually represent most of the data structures that YGS supports,

11:20.520 --> 11:24.520
so anything that's basically in a JSON sort of format.

11:24.520 --> 11:29.520
You can map them one to one to some sort of an XML.

11:29.520 --> 11:35.520
So for example, you have this Y text that is just a non-named XML fragment,

11:35.520 --> 11:40.520
that has no attributes, and it has children as plain text content.

11:40.520 --> 11:45.520
And array is just a number of items within that same sort of fragment.

11:45.520 --> 11:50.520
A map is some sort of a key value attribute pair.

11:50.520 --> 11:54.520
And an XML element is the full blown thing.

11:54.520 --> 11:58.520
It has a name, it has attributes and children inside of it.

11:58.520 --> 12:02.520
So it was a huge simplification to the code base.

12:02.520 --> 12:08.520
It was beautiful to see the GitHub PR to see that thousands of lines were deleted,

12:08.520 --> 12:10.520
and only a few hundred added.

12:10.520 --> 12:15.520
So we were able to completely remove all of the other types.

12:15.520 --> 12:21.520
And now there's just one type that is based on this XML structure.

12:21.520 --> 12:28.520
And you can define a schema to your YGS document that will actually differentiate between these types,

12:28.520 --> 12:30.520
so that you still know what's inside of.

12:30.520 --> 12:35.520
So this is, there's a strong schema that defines a YGS document now,

12:35.520 --> 12:43.520
rather than it just being a grab bag of whatever values happened to be set at the time.

12:43.520 --> 12:48.520
So now that we have this one unified Y type,

12:48.520 --> 12:53.520
we need to have a way to describe changes to the type.

12:53.520 --> 12:57.520
As part of the work for suggestions and attributions,

12:57.520 --> 13:04.520
it became clear that we needed a universal way to describe these changes,

13:04.520 --> 13:09.520
and Kevin has always been a fan of the Quill Delta format.

13:09.520 --> 13:13.520
And this is based on that format.

13:13.520 --> 13:19.520
So what, how we can describe a transformation from hello world to hello with the next formation point,

13:19.520 --> 13:30.520
added, is you can describe it as, as though you were, as though you were user interacting with it.

13:30.520 --> 13:35.520
So what you do is you move the cursor five, five characters over,

13:35.520 --> 13:38.520
you delete the world at the end of it,

13:38.520 --> 13:41.520
and then you insert the actual new character.

13:41.520 --> 13:48.520
So you're describing a change as all of the operations that you would do on the document.

13:48.520 --> 13:54.520
So with this ends up being, is that there's a literal array that describes all of the changes.

13:54.520 --> 14:01.520
This is a very similar to OT for those that are familiar with this.

14:01.520 --> 14:09.520
But what ends up happening is that we have a transaction log of all of the changes that have happened to a document.

14:09.520 --> 14:13.520
So you can do a lot of things with this transaction log.

14:13.520 --> 14:21.520
So not only do you can apply this to a Y type to get the output to actually apply,

14:21.520 --> 14:27.520
and do that in a way that is obviously CODT based and using the Y adjust data structure.

14:27.520 --> 14:32.520
But you can also operate exclusively on these operations.

14:32.520 --> 14:38.520
So you can merge several operations together to get one change.

14:38.520 --> 14:40.520
You can re-base operations.

14:40.520 --> 14:46.520
There's a whole bunch of new functionality that we can do.

14:46.520 --> 14:51.520
So getting back to suggestions and attributions here.

14:51.520 --> 14:56.520
This is a little bit about how the attribution manager works.

14:56.520 --> 15:02.520
I didn't want to go into the details of how this is actually represented,

15:02.520 --> 15:07.520
like in the data format using IDSats, ID maps.

15:07.520 --> 15:14.520
So I wanted to just explain this in a way that it's a little bit more palatable for the average developer,

15:14.520 --> 15:17.520
but please ask me more about this later.

15:17.520 --> 15:31.520
So what I did here was explain a YJS update as there's the actual content of what has actually changed within the update.

15:31.520 --> 15:36.520
So for example, this is an addition of hello.

15:36.520 --> 15:41.520
Normally this would be a character level and this describes a range of updates and they're merged together.

15:41.520 --> 15:44.520
But this is a simplification.

15:44.520 --> 15:47.520
And then there's also a number of ID metadata.

15:47.520 --> 15:50.520
So I'm referring to it as a content ID here.

15:50.520 --> 15:54.520
But it's think of it as some sort of a version identifier.

15:54.520 --> 15:59.520
This is the version that was applied to the YJS document.

15:59.520 --> 16:03.520
It can get complicated to explain CRDT things.

16:03.520 --> 16:10.520
So I feel like it was just easier to describe the attribution manager as essentially a map between those versions,

16:10.520 --> 16:15.520
which technically describe multiple changes.

16:15.520 --> 16:23.520
You can describe ranges of changes, mapping those versions to actual arbitrary metadata.

16:23.520 --> 16:29.520
So I have that it's attributed to Nick and some sort of timestamp.

16:29.520 --> 16:34.520
It can be any sort of Json representable metadata.

16:35.520 --> 16:45.520
So then once we have that in the attribution manager, this attribution manager is meant to be stored in a secure way.

16:45.520 --> 16:52.520
So for example, this might be stored on a central server if this is your off model.

16:52.520 --> 16:58.520
It could be some sort of a peer-to-peer system, some sort of trust model, whatever it is.

16:58.520 --> 17:03.520
The point is that it's a separate store of this attribution metadata.

17:03.520 --> 17:08.520
So that you can be sure and confident in what's inside of it.

17:08.520 --> 17:17.520
So you can't have in personation of users or anything like that to say that who made what update at what time.

17:17.520 --> 17:20.520
That's essentially what this store is meant to do.

17:20.520 --> 17:27.520
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.

17:27.520 --> 17:29.520
We can ask for specific ranges of versions.

17:29.520 --> 17:36.520
We can ask for what content is what is attributed to what.

17:36.520 --> 17:42.520
So for example, you could say that like, okay, this range of characters is owned by Nick.

17:42.520 --> 17:48.520
Yes or no, whatever, and you can pull out that data from the store.

17:48.520 --> 17:55.520
So one way of pulling out that data is through this concept of a content renderer.

17:55.520 --> 18:02.520
And this gets more to the level of what I actually got to work on.

18:02.520 --> 18:06.520
So for example here, we have two documents.

18:06.520 --> 18:22.520
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.

18:22.520 --> 18:25.520
You can still modify the source documents.

18:25.520 --> 18:34.520
So it's using, for example, you can take the diff between two documents and you can show what was actually changed.

18:34.520 --> 18:40.520
So this would be represented as you get the entire document content as a delta.

18:40.520 --> 18:43.520
And then you dip the two deltas to see what is actually changed.

18:43.520 --> 18:50.520
The content renderer is what is responsible for saying this portion of content was deleted.

18:50.520 --> 18:57.520
This portion of content was added between these two versions.

18:57.520 --> 19:02.520
Another use case for the content renderer is this attribution view.

19:02.520 --> 19:07.520
So what you can do is using the attribution manager that we showed before.

19:07.520 --> 19:15.520
You can take a range of content and figure out who was attributed to this content.

19:15.520 --> 19:23.520
Then on top of that you can do additional things such as dipping and attribution at the same time.

19:23.520 --> 19:33.520
So you are not only able to do a difference between the documents but see what was the attribution for that content.

19:33.520 --> 19:35.520
So this is very important.

19:35.520 --> 19:38.520
This is the core of what a track changes like feature is.

19:38.520 --> 19:42.520
We have separation of the content data sources.

19:42.520 --> 19:48.520
We have a separate store which is the attribution manager to store this all security.

19:48.520 --> 19:51.520
Okay.

19:51.520 --> 20:02.520
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.

20:02.520 --> 20:07.520
It's an industry standard and is what a document is based on.

20:08.520 --> 20:12.520
Wi-Pro's mirror is a binding between the Wi-JS document.

20:12.520 --> 20:18.520
That's in data and the Pro's mirror document that is in memory.

20:18.520 --> 20:24.520
So Wi-Pro's mirror's job is to then synchronize the changes between these two documents.

20:24.520 --> 20:33.520
So if a change comes in from a remote then that changes the editor state or you make a local change to your document.

20:33.520 --> 20:38.520
That sinks it back to the Wi-JS document and it sinks to other clients.

20:38.520 --> 20:41.520
So this is where everything pretty much comes together.

20:41.520 --> 20:48.520
We have the Delta format for actually being able to describe what those changes are.

20:48.520 --> 20:52.520
You have the content renderer for displaying those changes.

20:52.520 --> 20:57.520
And we have to completely rewrite the Wi-Pro's mirror binding.

20:57.520 --> 21:01.520
And with that there's a number of improvements that we've made.

21:02.520 --> 21:08.520
And one of them is to bring this content renderer functionality into that.

21:08.520 --> 21:16.520
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.

21:16.520 --> 21:19.520
If you're looking at like static versions.

21:19.520 --> 21:25.520
So there's a number of improvements that we've made.

21:25.520 --> 21:26.520
Thanks.

21:26.520 --> 21:27.520
I think that though.

21:33.520 --> 21:35.520
Thank you very much.

21:35.520 --> 21:36.520
You said a link.

21:36.520 --> 21:38.520
We will take questions in the room.

21:38.520 --> 21:39.520
Please raise your hand.

21:39.520 --> 21:40.520
All of you now.

21:40.520 --> 21:41.520
No harm any questions.

21:41.520 --> 21:43.520
We have one question.

21:43.520 --> 21:44.520
Two questions.

21:44.520 --> 21:45.520
Three.

21:45.520 --> 21:46.520
No.

21:46.520 --> 21:49.520
I may be not a question but a clarification.

21:49.520 --> 21:52.520
Like most of those features were already possible.

21:52.520 --> 21:56.520
But the way how they were implemented to permanent user data.

21:56.520 --> 21:58.520
This is how this features call it.

21:58.520 --> 22:11.520
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.

22:11.520 --> 22:15.520
But now where the cabinet's work it will be much more powerful.

22:15.520 --> 22:20.520
And it will allow to have more features on top of that basically.

22:21.520 --> 22:25.520
I totally deferred to Bertosh for anything.

22:25.520 --> 22:26.520
Why did you just relate it?

22:26.520 --> 22:28.520
Is that any question in the room?

22:28.520 --> 22:30.520
More questions.

22:34.520 --> 22:35.520
Okay.

22:35.520 --> 22:36.520
So we can wrap it up.

22:36.520 --> 22:39.520
But I'm not sure if you want to add something.

22:39.520 --> 22:40.520
No, yes.

22:40.520 --> 22:45.520
Only that the largest 14 preview is available.

22:45.520 --> 22:48.520
But there's still a lot of this to quite some.

22:48.520 --> 22:54.520
It's like I would say alpha versus so we expected to be available later.

22:54.520 --> 22:55.520
This year.

22:55.520 --> 22:57.520
And then.

22:57.520 --> 23:01.520
Yeah, the then we'll also release the layers on top of it.

23:01.520 --> 23:04.520
So why pros mayor for the binding to raw pros mayor things.

23:04.520 --> 23:08.520
And then block notes our vision is to really provide a high level API.

23:08.520 --> 23:13.520
So really to abstract as much of this away for you and just say okay.

23:13.520 --> 23:15.520
Enter suggestion mode.

23:15.520 --> 23:17.520
And there will be a little bit later.

23:17.520 --> 23:21.520
But also hope to release that somewhere this year.

23:21.520 --> 23:23.520
Okay.

23:23.520 --> 23:25.520
Thank you very much again.

23:25.520 --> 23:27.520
Thank you.

23:27.520 --> 23:31.520
So.

