jupyter-server-ydoc 1.0.1__py3-none-any.whl → 1.1.0b0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- jupyter_server_ydoc/_version.py +1 -1
- jupyter_server_ydoc/app.py +10 -0
- jupyter_server_ydoc/events/fork.yaml +56 -0
- jupyter_server_ydoc/handlers.py +100 -0
- jupyter_server_ydoc/pytest_plugin.py +59 -0
- jupyter_server_ydoc/utils.py +2 -0
- {jupyter_server_ydoc-1.0.1.dist-info → jupyter_server_ydoc-1.1.0b0.dist-info}/METADATA +3 -2
- jupyter_server_ydoc-1.1.0b0.dist-info/RECORD +19 -0
- jupyter_server_ydoc-1.0.1.dist-info/RECORD +0 -18
- {jupyter_server_ydoc-1.0.1.data → jupyter_server_ydoc-1.1.0b0.data}/data/etc/jupyter/jupyter_server_config.d/jupyter_collaboration.json +0 -0
- {jupyter_server_ydoc-1.0.1.dist-info → jupyter_server_ydoc-1.1.0b0.dist-info}/WHEEL +0 -0
- {jupyter_server_ydoc-1.0.1.dist-info → jupyter_server_ydoc-1.1.0b0.dist-info}/licenses/LICENSE +0 -0
jupyter_server_ydoc/_version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "1.
|
|
1
|
+
__version__ = "1.1.0b0"
|
jupyter_server_ydoc/app.py
CHANGED
|
@@ -14,6 +14,7 @@ from pycrdt_websocket.ystore import BaseYStore
|
|
|
14
14
|
from traitlets import Bool, Float, Type
|
|
15
15
|
|
|
16
16
|
from .handlers import (
|
|
17
|
+
DocForkHandler,
|
|
17
18
|
DocSessionHandler,
|
|
18
19
|
TimelineHandler,
|
|
19
20
|
UndoRedoHandler,
|
|
@@ -25,6 +26,7 @@ from .stores import SQLiteYStore
|
|
|
25
26
|
from .utils import (
|
|
26
27
|
AWARENESS_EVENTS_SCHEMA_PATH,
|
|
27
28
|
EVENTS_SCHEMA_PATH,
|
|
29
|
+
FORK_EVENTS_SCHEMA_PATH,
|
|
28
30
|
encode_file_path,
|
|
29
31
|
room_id_from_encoded_path,
|
|
30
32
|
)
|
|
@@ -85,6 +87,7 @@ class YDocExtension(ExtensionApp):
|
|
|
85
87
|
super().initialize()
|
|
86
88
|
self.serverapp.event_logger.register_event_schema(EVENTS_SCHEMA_PATH)
|
|
87
89
|
self.serverapp.event_logger.register_event_schema(AWARENESS_EVENTS_SCHEMA_PATH)
|
|
90
|
+
self.serverapp.event_logger.register_event_schema(FORK_EVENTS_SCHEMA_PATH)
|
|
88
91
|
|
|
89
92
|
def initialize_settings(self):
|
|
90
93
|
self.settings.update(
|
|
@@ -123,6 +126,13 @@ class YDocExtension(ExtensionApp):
|
|
|
123
126
|
|
|
124
127
|
self.handlers.extend(
|
|
125
128
|
[
|
|
129
|
+
(
|
|
130
|
+
r"/api/collaboration/fork/(.*)",
|
|
131
|
+
DocForkHandler,
|
|
132
|
+
{
|
|
133
|
+
"ywebsocket_server": self.ywebsocket_server,
|
|
134
|
+
},
|
|
135
|
+
),
|
|
126
136
|
(
|
|
127
137
|
r"/api/collaboration/room/(.*)",
|
|
128
138
|
YDocWebSocketHandler,
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"$id": https://schema.jupyter.org/jupyter_collaboration/fork/v1
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema"
|
|
3
|
+
version: 1
|
|
4
|
+
title: Collaborative fork events
|
|
5
|
+
personal-data: true
|
|
6
|
+
description: |
|
|
7
|
+
Fork events emitted from server-side during a collaborative session.
|
|
8
|
+
type: object
|
|
9
|
+
required:
|
|
10
|
+
- fork_roomid
|
|
11
|
+
- fork_info
|
|
12
|
+
- username
|
|
13
|
+
- action
|
|
14
|
+
properties:
|
|
15
|
+
fork_roomid:
|
|
16
|
+
type: string
|
|
17
|
+
description: |
|
|
18
|
+
Fork root room ID.
|
|
19
|
+
fork_info:
|
|
20
|
+
type: object
|
|
21
|
+
description: |
|
|
22
|
+
Fork root room information.
|
|
23
|
+
required:
|
|
24
|
+
- root_roomid
|
|
25
|
+
- synchronize
|
|
26
|
+
- title
|
|
27
|
+
- description
|
|
28
|
+
properties:
|
|
29
|
+
root_roomid:
|
|
30
|
+
type: string
|
|
31
|
+
description: |
|
|
32
|
+
Root room ID. Usually composed by the file type, format and ID.
|
|
33
|
+
synchronize:
|
|
34
|
+
type: boolean
|
|
35
|
+
description: |
|
|
36
|
+
Whether the fork is kept in sync with the root.
|
|
37
|
+
title:
|
|
38
|
+
type: string
|
|
39
|
+
description: |
|
|
40
|
+
The title of the fork.
|
|
41
|
+
description:
|
|
42
|
+
type: string
|
|
43
|
+
description: |
|
|
44
|
+
The description of the fork.
|
|
45
|
+
username:
|
|
46
|
+
type: string
|
|
47
|
+
description: |
|
|
48
|
+
The name of the user who created or deleted the fork.
|
|
49
|
+
action:
|
|
50
|
+
enum:
|
|
51
|
+
- create
|
|
52
|
+
- delete
|
|
53
|
+
description: |
|
|
54
|
+
Possible values:
|
|
55
|
+
1. create
|
|
56
|
+
2. delete
|
jupyter_server_ydoc/handlers.py
CHANGED
|
@@ -26,6 +26,7 @@ from .rooms import DocumentRoom, TransientRoom
|
|
|
26
26
|
from .utils import (
|
|
27
27
|
JUPYTER_COLLABORATION_AWARENESS_EVENTS_URI,
|
|
28
28
|
JUPYTER_COLLABORATION_EVENTS_URI,
|
|
29
|
+
JUPYTER_COLLABORATION_FORK_EVENTS_URI,
|
|
29
30
|
LogLevel,
|
|
30
31
|
MessageType,
|
|
31
32
|
decode_file_path,
|
|
@@ -39,6 +40,7 @@ YFILE = YDOCS["file"]
|
|
|
39
40
|
|
|
40
41
|
SERVER_SESSION = str(uuid.uuid4())
|
|
41
42
|
FORK_DOCUMENTS = {}
|
|
43
|
+
FORK_ROOMS: dict[str, dict[str, str]] = {}
|
|
42
44
|
|
|
43
45
|
|
|
44
46
|
class YDocWebSocketHandler(WebSocketHandler, JupyterHandler):
|
|
@@ -600,3 +602,101 @@ class UndoRedoHandler(APIHandler):
|
|
|
600
602
|
if room_id in FORK_DOCUMENTS:
|
|
601
603
|
del FORK_DOCUMENTS[room_id]
|
|
602
604
|
self.log.info(f"Fork Document for {room_id} has been removed.")
|
|
605
|
+
|
|
606
|
+
|
|
607
|
+
class DocForkHandler(APIHandler):
|
|
608
|
+
"""
|
|
609
|
+
Jupyter Server handler to:
|
|
610
|
+
- create a fork of a root document (optionally synchronizing with the root document),
|
|
611
|
+
- delete a fork of a root document (optionally merging back in the root document).
|
|
612
|
+
- get fork IDs of a root document.
|
|
613
|
+
"""
|
|
614
|
+
|
|
615
|
+
auth_resource = "contents"
|
|
616
|
+
|
|
617
|
+
def initialize(
|
|
618
|
+
self,
|
|
619
|
+
ywebsocket_server: JupyterWebsocketServer,
|
|
620
|
+
) -> None:
|
|
621
|
+
self._websocket_server = ywebsocket_server
|
|
622
|
+
|
|
623
|
+
@web.authenticated
|
|
624
|
+
@authorized
|
|
625
|
+
async def get(self, root_roomid):
|
|
626
|
+
"""
|
|
627
|
+
Returns a dictionary of fork room ID to fork room information for the given root room ID.
|
|
628
|
+
"""
|
|
629
|
+
self.write(
|
|
630
|
+
{
|
|
631
|
+
fork_roomid: fork_info
|
|
632
|
+
for fork_roomid, fork_info in FORK_ROOMS.items()
|
|
633
|
+
if fork_info["root_roomid"] == root_roomid
|
|
634
|
+
}
|
|
635
|
+
)
|
|
636
|
+
|
|
637
|
+
@web.authenticated
|
|
638
|
+
@authorized
|
|
639
|
+
async def put(self, root_roomid):
|
|
640
|
+
"""
|
|
641
|
+
Creates a fork of a root document and returns its ID.
|
|
642
|
+
Optionally keeps the fork in sync with the root.
|
|
643
|
+
"""
|
|
644
|
+
fork_roomid = uuid4().hex
|
|
645
|
+
root_room = await self._websocket_server.get_room(root_roomid)
|
|
646
|
+
update = root_room.ydoc.get_update()
|
|
647
|
+
fork_ydoc = Doc()
|
|
648
|
+
fork_ydoc.apply_update(update)
|
|
649
|
+
model = self.get_json_body()
|
|
650
|
+
synchronize = model.get("synchronize", False)
|
|
651
|
+
if synchronize:
|
|
652
|
+
root_room.ydoc.observe(lambda event: fork_ydoc.apply_update(event.update))
|
|
653
|
+
FORK_ROOMS[fork_roomid] = fork_info = {
|
|
654
|
+
"root_roomid": root_roomid,
|
|
655
|
+
"synchronize": synchronize,
|
|
656
|
+
"title": model.get("title", ""),
|
|
657
|
+
"description": model.get("description", ""),
|
|
658
|
+
}
|
|
659
|
+
fork_room = YRoom(ydoc=fork_ydoc)
|
|
660
|
+
self._websocket_server.rooms[fork_roomid] = fork_room
|
|
661
|
+
await self._websocket_server.start_room(fork_room)
|
|
662
|
+
self._emit_fork_event(self.current_user.username, fork_roomid, fork_info, "create")
|
|
663
|
+
data = json.dumps(
|
|
664
|
+
{
|
|
665
|
+
"sessionId": SERVER_SESSION,
|
|
666
|
+
"fork_roomid": fork_roomid,
|
|
667
|
+
"fork_info": fork_info,
|
|
668
|
+
}
|
|
669
|
+
)
|
|
670
|
+
self.set_status(201)
|
|
671
|
+
return self.finish(data)
|
|
672
|
+
|
|
673
|
+
@web.authenticated
|
|
674
|
+
@authorized
|
|
675
|
+
async def delete(self, fork_roomid):
|
|
676
|
+
"""
|
|
677
|
+
Deletes a forked document, and optionally merges it back in the root document.
|
|
678
|
+
"""
|
|
679
|
+
fork_info = FORK_ROOMS[fork_roomid]
|
|
680
|
+
root_roomid = fork_info["root_roomid"]
|
|
681
|
+
del FORK_ROOMS[fork_roomid]
|
|
682
|
+
if self.get_query_argument("merge") == "true":
|
|
683
|
+
root_room = await self._websocket_server.get_room(root_roomid)
|
|
684
|
+
root_ydoc = root_room.ydoc
|
|
685
|
+
fork_room = await self._websocket_server.get_room(fork_roomid)
|
|
686
|
+
fork_ydoc = fork_room.ydoc
|
|
687
|
+
fork_update = fork_ydoc.get_update()
|
|
688
|
+
root_ydoc.apply_update(fork_update)
|
|
689
|
+
await self._websocket_server.delete_room(name=fork_roomid)
|
|
690
|
+
self._emit_fork_event(self.current_user.username, fork_roomid, fork_info, "delete")
|
|
691
|
+
self.set_status(200)
|
|
692
|
+
|
|
693
|
+
def _emit_fork_event(
|
|
694
|
+
self, username: str, fork_roomid: str, fork_info: dict[str, str], action: str
|
|
695
|
+
) -> None:
|
|
696
|
+
data = {
|
|
697
|
+
"username": username,
|
|
698
|
+
"fork_roomid": fork_roomid,
|
|
699
|
+
"fork_info": fork_info,
|
|
700
|
+
"action": action,
|
|
701
|
+
}
|
|
702
|
+
self.event_logger.emit(schema_id=JUPYTER_COLLABORATION_FORK_EVENTS_URI, data=data)
|
|
@@ -154,6 +154,65 @@ def rtc_connect_doc_client(jp_http_port, jp_base_url, rtc_fetch_session):
|
|
|
154
154
|
return _inner
|
|
155
155
|
|
|
156
156
|
|
|
157
|
+
@pytest.fixture
|
|
158
|
+
def rtc_connect_fork_client(jp_http_port, jp_base_url, rtc_fetch_session):
|
|
159
|
+
async def _inner(room_id: str) -> Any:
|
|
160
|
+
return aconnect_ws(
|
|
161
|
+
f"http://127.0.0.1:{jp_http_port}{jp_base_url}api/collaboration/room/{room_id}"
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
return _inner
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
@pytest.fixture
|
|
168
|
+
def rtc_get_forks_client(jp_fetch):
|
|
169
|
+
async def _inner(root_roomid: str) -> Any:
|
|
170
|
+
return await jp_fetch(
|
|
171
|
+
"/api/collaboration/fork",
|
|
172
|
+
root_roomid,
|
|
173
|
+
method="GET",
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
return _inner
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
@pytest.fixture
|
|
180
|
+
def rtc_create_fork_client(jp_fetch):
|
|
181
|
+
async def _inner(
|
|
182
|
+
root_roomid: str,
|
|
183
|
+
synchronize: bool,
|
|
184
|
+
title: str | None = None,
|
|
185
|
+
description: str | None = None,
|
|
186
|
+
) -> Any:
|
|
187
|
+
return await jp_fetch(
|
|
188
|
+
"/api/collaboration/fork",
|
|
189
|
+
root_roomid,
|
|
190
|
+
method="PUT",
|
|
191
|
+
body=json.dumps(
|
|
192
|
+
{
|
|
193
|
+
"synchronize": synchronize,
|
|
194
|
+
"title": title,
|
|
195
|
+
"description": description,
|
|
196
|
+
}
|
|
197
|
+
),
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
return _inner
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
@pytest.fixture
|
|
204
|
+
def rtc_delete_fork_client(jp_fetch):
|
|
205
|
+
async def _inner(fork_roomid: str, merge: bool) -> Any:
|
|
206
|
+
return await jp_fetch(
|
|
207
|
+
"/api/collaboration/fork",
|
|
208
|
+
fork_roomid,
|
|
209
|
+
method="DELETE",
|
|
210
|
+
params={"merge": str(merge).lower()},
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
return _inner
|
|
214
|
+
|
|
215
|
+
|
|
157
216
|
@pytest.fixture
|
|
158
217
|
def rtc_add_doc_to_store(rtc_connect_doc_client):
|
|
159
218
|
event = Event()
|
jupyter_server_ydoc/utils.py
CHANGED
|
@@ -11,7 +11,9 @@ EVENTS_SCHEMA_PATH = EVENTS_FOLDER_PATH / "session.yaml"
|
|
|
11
11
|
JUPYTER_COLLABORATION_AWARENESS_EVENTS_URI = (
|
|
12
12
|
"https://schema.jupyter.org/jupyter_collaboration/awareness/v1"
|
|
13
13
|
)
|
|
14
|
+
JUPYTER_COLLABORATION_FORK_EVENTS_URI = "https://schema.jupyter.org/jupyter_collaboration/fork/v1"
|
|
14
15
|
AWARENESS_EVENTS_SCHEMA_PATH = EVENTS_FOLDER_PATH / "awareness.yaml"
|
|
16
|
+
FORK_EVENTS_SCHEMA_PATH = EVENTS_FOLDER_PATH / "fork.yaml"
|
|
15
17
|
|
|
16
18
|
|
|
17
19
|
class MessageType(IntEnum):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: jupyter-server-ydoc
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.1.0b0
|
|
4
4
|
Summary: jupyter-server extension integrating collaborative shared models.
|
|
5
5
|
Author-email: Jupyter Development Team <jupyter@googlegroups.com>
|
|
6
6
|
License: # Licensing terms
|
|
@@ -78,12 +78,13 @@ Requires-Dist: jsonschema>=4.18.0
|
|
|
78
78
|
Requires-Dist: jupyter-events>=0.10.0
|
|
79
79
|
Requires-Dist: jupyter-server-fileid<1,>=0.7.0
|
|
80
80
|
Requires-Dist: jupyter-server<3.0.0,>=2.11.1
|
|
81
|
-
Requires-Dist: jupyter-ydoc
|
|
81
|
+
Requires-Dist: jupyter-ydoc!=3.0.0,!=3.0.1,<4.0.0,>=2.1.2
|
|
82
82
|
Requires-Dist: pycrdt
|
|
83
83
|
Requires-Dist: pycrdt-websocket<0.16.0,>=0.15.0
|
|
84
84
|
Provides-Extra: test
|
|
85
85
|
Requires-Dist: anyio; extra == 'test'
|
|
86
86
|
Requires-Dist: coverage; extra == 'test'
|
|
87
|
+
Requires-Dist: dirty-equals; extra == 'test'
|
|
87
88
|
Requires-Dist: httpx-ws>=0.5.2; extra == 'test'
|
|
88
89
|
Requires-Dist: importlib-metadata>=4.8.3; (python_version < '3.10') and extra == 'test'
|
|
89
90
|
Requires-Dist: jupyter-server-fileid[test]; extra == 'test'
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
jupyter_server_ydoc/__init__.py,sha256=B8H7XLhzgrTCQD8304Lx91FYXslwabsnV9OuYu4M4Hw,346
|
|
2
|
+
jupyter_server_ydoc/_version.py,sha256=b6vLdn9cgD2bkUNWeCjb_HpTXZvQwK1i9Nf-Ity73Oo,24
|
|
3
|
+
jupyter_server_ydoc/app.py,sha256=JqkpijoPdo_qum0CKqbG-I6W8fpC3-v2cFA3kFxK3mg,8111
|
|
4
|
+
jupyter_server_ydoc/handlers.py,sha256=5ywD2yuwXNQPnEFO_bkogxk_jPxuCZ-LhyzrkAFRmpE,27668
|
|
5
|
+
jupyter_server_ydoc/loaders.py,sha256=TijilImdgYk9K91cXEIP_DzkOr6phSddwQFpLI5l_RA,10564
|
|
6
|
+
jupyter_server_ydoc/pytest_plugin.py,sha256=1Y-iNZnEyhajx4HU-40aZ9iRVWcC5ikC5Y8JJHCH0So,8419
|
|
7
|
+
jupyter_server_ydoc/rooms.py,sha256=szOAfMldhQIrmVpqoF75O0_KXY54X_TrzJz6vpjR6kE,12254
|
|
8
|
+
jupyter_server_ydoc/stores.py,sha256=_5J6eNs3R5Tv88PCc-GGuszxQstfvNoBCYABqzBzJXA,1004
|
|
9
|
+
jupyter_server_ydoc/test_utils.py,sha256=utUwB5FThc_SCQshhUbLNih9GUa5qBcmMgU6-jx0ZnA,2275
|
|
10
|
+
jupyter_server_ydoc/utils.py,sha256=EgKC15js8VOS8-5jGMs4pfHQfV9drnNT2Gew5UlyXZc,2171
|
|
11
|
+
jupyter_server_ydoc/websocketserver.py,sha256=7fLPJcWczD-4R_-LXtfvNxM_pUXFasZWDmT4RIrOQHE,5150
|
|
12
|
+
jupyter_server_ydoc/events/awareness.yaml,sha256=9isoK58uue7lqMnlHqyfQt29z16Otkh14oRe1k5vbKM,753
|
|
13
|
+
jupyter_server_ydoc/events/fork.yaml,sha256=v7WQX2tkD6Zoh9a9qiJpq6wsU4UVnhdZfZSxdnukk_4,1301
|
|
14
|
+
jupyter_server_ydoc/events/session.yaml,sha256=A7Wt7czyx38MXp5fpDbH7HLS0QNkeOqaEhHdP2x-0Mo,1594
|
|
15
|
+
jupyter_server_ydoc-1.1.0b0.data/data/etc/jupyter/jupyter_server_config.d/jupyter_collaboration.json,sha256=0thh2hJUxAKkZSmneJMG0U6QJRjdM6zGlwrTedEt-Jk,94
|
|
16
|
+
jupyter_server_ydoc-1.1.0b0.dist-info/METADATA,sha256=cpODdDvlMrRP0LOl-WNDX_odczyPlGS3M6lkkzJXyUA,5094
|
|
17
|
+
jupyter_server_ydoc-1.1.0b0.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
|
|
18
|
+
jupyter_server_ydoc-1.1.0b0.dist-info/licenses/LICENSE,sha256=mhO0ZW9EiWOPg0dUgB-lNbJ0CGwRmTdbeAg_se1SOnY,2833
|
|
19
|
+
jupyter_server_ydoc-1.1.0b0.dist-info/RECORD,,
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
jupyter_server_ydoc/__init__.py,sha256=B8H7XLhzgrTCQD8304Lx91FYXslwabsnV9OuYu4M4Hw,346
|
|
2
|
-
jupyter_server_ydoc/_version.py,sha256=d4QHYmS_30j0hPN8NmNPnQ_Z0TphDRbu4MtQj9cT9e8,22
|
|
3
|
-
jupyter_server_ydoc/app.py,sha256=8vOKWLYa4OKu8Pw24TLWtbgs2SfH0_R64dPrErdWyQM,7739
|
|
4
|
-
jupyter_server_ydoc/handlers.py,sha256=xfcTzrOV08wJVIwxHhp9DdVH3ogEY5E_ktLpzBXV5qE,24016
|
|
5
|
-
jupyter_server_ydoc/loaders.py,sha256=TijilImdgYk9K91cXEIP_DzkOr6phSddwQFpLI5l_RA,10564
|
|
6
|
-
jupyter_server_ydoc/pytest_plugin.py,sha256=eWAleH6Plh7Aiqv_Res8b0aFmd6C0n-D1j4p1KuE0PA,6983
|
|
7
|
-
jupyter_server_ydoc/rooms.py,sha256=szOAfMldhQIrmVpqoF75O0_KXY54X_TrzJz6vpjR6kE,12254
|
|
8
|
-
jupyter_server_ydoc/stores.py,sha256=_5J6eNs3R5Tv88PCc-GGuszxQstfvNoBCYABqzBzJXA,1004
|
|
9
|
-
jupyter_server_ydoc/test_utils.py,sha256=utUwB5FThc_SCQshhUbLNih9GUa5qBcmMgU6-jx0ZnA,2275
|
|
10
|
-
jupyter_server_ydoc/utils.py,sha256=yQC-uRdLyFDYbt2Zms_hA1HyjlwznMK4yQ3_FUwTlnQ,2013
|
|
11
|
-
jupyter_server_ydoc/websocketserver.py,sha256=7fLPJcWczD-4R_-LXtfvNxM_pUXFasZWDmT4RIrOQHE,5150
|
|
12
|
-
jupyter_server_ydoc/events/awareness.yaml,sha256=9isoK58uue7lqMnlHqyfQt29z16Otkh14oRe1k5vbKM,753
|
|
13
|
-
jupyter_server_ydoc/events/session.yaml,sha256=A7Wt7czyx38MXp5fpDbH7HLS0QNkeOqaEhHdP2x-0Mo,1594
|
|
14
|
-
jupyter_server_ydoc-1.0.1.data/data/etc/jupyter/jupyter_server_config.d/jupyter_collaboration.json,sha256=0thh2hJUxAKkZSmneJMG0U6QJRjdM6zGlwrTedEt-Jk,94
|
|
15
|
-
jupyter_server_ydoc-1.0.1.dist-info/METADATA,sha256=cKECBcDzWlzL8RGeLp405E61wVBiW4UfxWEb6zwp_i0,5031
|
|
16
|
-
jupyter_server_ydoc-1.0.1.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
|
|
17
|
-
jupyter_server_ydoc-1.0.1.dist-info/licenses/LICENSE,sha256=mhO0ZW9EiWOPg0dUgB-lNbJ0CGwRmTdbeAg_se1SOnY,2833
|
|
18
|
-
jupyter_server_ydoc-1.0.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
{jupyter_server_ydoc-1.0.1.dist-info → jupyter_server_ydoc-1.1.0b0.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|