Skip to content

Commit 334a8ad

Browse files
authored
Docs (#102)
* Overview * Schema * Custom documents * Improves overview * Review * Review * Review
1 parent 87d00f2 commit 334a8ad

File tree

3 files changed

+165
-4
lines changed

3 files changed

+165
-4
lines changed

docs/source/custom.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,20 @@
11
# Custom documents
22

3-
Coming soon!
3+
Writing an application for a new kind of collaborative document requires the definition of a custom YDoc.
4+
5+
This section will focus on extending documents to use in JupyterLab. In JupyterLab, the front-end conforms to the `ISharedDocument` interface and expects a `YDocument`, both present in the [`@jupyter/ydoc`](./overview.md#jupyter-ydoc) package. In contrast, the back-end conforms to the `YBaseDoc` class in [`jupyter_ydoc`](./overview.md#jupyterydoc).
6+
7+
On a few occasions, we can extend the front-end model and reuse the back-end counterpart without extending it. Extending only the front-end will prevent JupyterLab from saving the new attributes to disk since those new attributes will not be exported by the back-end model when requesting the document's content. This could be the case, for example, when creating a commenting extension where we want to sync the comments through different clients, but we do not want to save them to disk, or at least not within the document.
8+
9+
Once we implement our new models, it is time to export them to be consumed by JupyterLab. In JupyterLab, we register new file types or new document models for existing file types from the front-end. For this reason, the wording that we will use from now on is highly tight to JupyterLab development, and we highly recommend reading JupyterLab's documentation or at least [the section about documents](https://jupyterlab.readthedocs.io/en/stable/extension/documents.html) before continuing reading.
10+
11+
The front-end's models are more complicated because JupyterLab wraps the shared models (that is how we name Jupyter YDoc in the JupyterLab source code) inside the old document's models from JupyterLab. In addition, JupyterLab's document models expose the shared models as a single property, and registering new documents involves more knowledge of the document system. For this reason, we recommend following JupyterLab's documentation, [the section about documents](https://jupyterlab.readthedocs.io/en/stable/extension/documents.html) to register new documents on the front-end side.
12+
13+
On the other side, to export a back-end model, we have to use the entry points provided by Python. We can export our new models by adding them to the configuration file of our Python project using the entry point `jupyter_ydoc`. For example, using a `pyproject.toml` configuration file, we will export our custom model for a `my_document` type as follows:
14+
15+
```toml
16+
[project.entry-points.jupyter_ydoc]
17+
my_document = "my_module.my_file:YCustomDocument"
18+
```
19+
20+
You can find an example of a custom document in the [JupyterCAD extension](https://github.com/QuantStack/jupytercad). With an implementation of a new document model [here](https://github.com/QuantStack/jupytercad/blob/main/jupytercad/jcad_ydoc.py) and registering it [here](https://github.com/QuantStack/jupytercad/blob/main/setup.cfg).

docs/source/overview.md

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,28 @@
11
# Overview
22

3-
Coming soon!
3+
The `jupyter_ydoc` repository includes various models that JupyterLab uses for collaborative editing. These models use a specific implementation of a CRDT, the Y-CRDTs. To be more precise, the JavaScript package uses [yjs](https://github.com/yjs/yjs), while the Python package uses [y_py](https://github.com/y-crdt/ypy).
4+
5+
Jupyter YDoc was designed to centralize the data structures used for composing a document in a single class, hide the complicated edge cases of CRDTs, and prevent users from inserting invalid data or adding new attributes to the document that are not part of the schema.
6+
7+
This repository holds a JavaScript package and its Python counterpart. In the JupyterLab context, the JavaScript package, or from now on, `@jupyter/ydoc`, contains the front-end models used to keep the documents in the client's memory. In contrast, the Python package contains the models used in the back-end to serve documents to each client.
8+
9+
10+
## `@jupyter/ydoc`
11+
Built on top of [yjs](https://github.com/yjs/yjs), `@jupyter/ydoc` is a JavaScript package that includes the models used in the JupyterLab front-end for real-time collaboration. This package contains two main classes, `YFile` used for plain text documents and `YNotebook` used for the Notebook format. In the JupyterLab context, we call the models exported by this package, shared models. In addition, this package contains the `IShared` interfaces used to abstract out the implementation of the shared models in JupyterLab to make it easier to replace the CRDT implementation (Yjs) for something else if needed.
12+
13+
**Source Code:** [GitHub](https://github.com/jupyter-server/jupyter_ydoc/tree/main/javascript)
14+
15+
**Package:** [NPM](https://www.npmjs.com/package/@jupyter/ydoc)
16+
17+
**API documentation:**: [JavaScript API](javascript_api.rst)
18+
19+
20+
21+
## `jupyter-ydoc`
22+
Built on top of [y_py](https://github.com/y-crdt/ypy), `jupyter-ydoc` is a Python package that includes the models used in the JupyterLab back-end for representing collaborative documents.
23+
24+
**Source Code:** [GitHub](https://github.com/jupyter-server/jupyter_ydoc/tree/main/jupyter_ydoc)
25+
26+
**Package:** [PyPI](https://pypi.org/project/jupyter-ydoc)
27+
28+
**API documentation:**: [Python API](python_api.rst)

docs/source/schema.md

Lines changed: 121 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,129 @@
11
# Schemas
22

3+
Yjs is untyped. We must know what each attribute contains at build-time and cast its values when accessing them. It is essential to ensure both models use the same schema, to prevent errors at run-time because of a wrong cast. For this purpose, in the following sections, we can find the description of the schema used by each model in case we want to extend them to create a custom model.
4+
35
## YFile
46

5-
Coming soon!
7+
```typescript
8+
{
9+
/**
10+
* Contains the state of the document.
11+
* At the moment the only mandatory attributes are path and dirty.
12+
*/
13+
"state": YMap<string, any>,
14+
/**
15+
* Contains the content of the document.
16+
*/
17+
"source": YText
18+
19+
}
20+
```
621

22+
### state:
23+
```typescript
24+
{
25+
/**
26+
* Whether the document is dirty.
27+
*/
28+
"dirty": bool,
29+
/**
30+
* Document's path.
31+
*/
32+
"path": str
33+
}
34+
```
735

836
## YNotebook
937

10-
Coming soon!
38+
```typescript
39+
{
40+
/**
41+
* Contains the state of the document.
42+
* At the moment the only mandatory attributes are path and dirty.
43+
*/
44+
"state": YMap<string, any>,
45+
/**
46+
* Contains document's metadata.
47+
*
48+
* Note: Do not confuse it with the notebook's metadata attribute,
49+
* "meta" has `nbformat`, `nbformat_minor`, and `metadata`
50+
*/
51+
"meta": YMap<string, any>,
52+
/**
53+
* The list of YMap that stores the data of each cell.
54+
*/
55+
"cells": YArray<YMap<string, any>>
56+
}
57+
```
58+
59+
### state:
60+
```typescript
61+
{
62+
/**
63+
* Whether the document is dirty.
64+
*/
65+
"dirty": bool,
66+
/**
67+
* Document's path.
68+
*/
69+
"path": str
70+
}
71+
```
72+
73+
### meta:
74+
```typescript
75+
{
76+
/**
77+
* The version of the notebook format supported by the schema.
78+
*/
79+
"nbformat": number,
80+
/**
81+
* The minor version of the notebook format.
82+
*/
83+
"nbformat_minor": number,
84+
/**
85+
* Notebook's metadata.
86+
*/
87+
"metadata": YMap<string, any>
88+
}
89+
```
90+
91+
### cells
92+
```typescript
93+
[
94+
/**
95+
* The following JSON object is actually a YMap that contains
96+
* the described attributes.
97+
*/
98+
{
99+
/**
100+
* Cell's id.
101+
*/
102+
"id": str,
103+
/**
104+
* Cell type.
105+
*/
106+
"cell_type": str,
107+
/**
108+
* The content of the cell (the code).
109+
*/
110+
"source": YText,
111+
/**
112+
* Cell's metadata.
113+
*/
114+
"metadata": YMap<string, any>,
115+
/**
116+
* The execution count.
117+
*/
118+
"execution_count": Int | None,
119+
/**
120+
* Cell's outputs.
121+
*/
122+
"outputs": [] | None,
123+
/**
124+
* Cell's attachments.
125+
*/
126+
"attachments": {} | None
127+
}
128+
]
129+
```

0 commit comments

Comments
 (0)