jupyter-server-ydoc 1.0.0b5__tar.gz → 1.0.0b8__tar.gz

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.
Files changed (28) hide show
  1. {jupyter_server_ydoc-1.0.0b5 → jupyter_server_ydoc-1.0.0b8}/PKG-INFO +1 -1
  2. jupyter_server_ydoc-1.0.0b8/jupyter_server_ydoc/_version.py +1 -0
  3. {jupyter_server_ydoc-1.0.0b5 → jupyter_server_ydoc-1.0.0b8}/jupyter_server_ydoc/loaders.py +24 -2
  4. {jupyter_server_ydoc-1.0.0b5 → jupyter_server_ydoc-1.0.0b8}/jupyter_server_ydoc/rooms.py +8 -1
  5. {jupyter_server_ydoc-1.0.0b5 → jupyter_server_ydoc-1.0.0b8}/jupyter_server_ydoc/test_utils.py +3 -0
  6. {jupyter_server_ydoc-1.0.0b5 → jupyter_server_ydoc-1.0.0b8}/tests/test_rooms.py +21 -0
  7. jupyter_server_ydoc-1.0.0b5/jupyter_server_ydoc/_version.py +0 -1
  8. {jupyter_server_ydoc-1.0.0b5 → jupyter_server_ydoc-1.0.0b8}/.gitignore +0 -0
  9. {jupyter_server_ydoc-1.0.0b5 → jupyter_server_ydoc-1.0.0b8}/LICENSE +0 -0
  10. {jupyter_server_ydoc-1.0.0b5 → jupyter_server_ydoc-1.0.0b8}/README.md +0 -0
  11. {jupyter_server_ydoc-1.0.0b5 → jupyter_server_ydoc-1.0.0b8}/jupyter-config/jupyter_server_ydoc.json +0 -0
  12. {jupyter_server_ydoc-1.0.0b5 → jupyter_server_ydoc-1.0.0b8}/jupyter_server_ydoc/__init__.py +0 -0
  13. {jupyter_server_ydoc-1.0.0b5 → jupyter_server_ydoc-1.0.0b8}/jupyter_server_ydoc/app.py +0 -0
  14. {jupyter_server_ydoc-1.0.0b5 → jupyter_server_ydoc-1.0.0b8}/jupyter_server_ydoc/events/awareness.yaml +0 -0
  15. {jupyter_server_ydoc-1.0.0b5 → jupyter_server_ydoc-1.0.0b8}/jupyter_server_ydoc/events/session.yaml +0 -0
  16. {jupyter_server_ydoc-1.0.0b5 → jupyter_server_ydoc-1.0.0b8}/jupyter_server_ydoc/handlers.py +0 -0
  17. {jupyter_server_ydoc-1.0.0b5 → jupyter_server_ydoc-1.0.0b8}/jupyter_server_ydoc/pytest_plugin.py +0 -0
  18. {jupyter_server_ydoc-1.0.0b5 → jupyter_server_ydoc-1.0.0b8}/jupyter_server_ydoc/stores.py +0 -0
  19. {jupyter_server_ydoc-1.0.0b5 → jupyter_server_ydoc-1.0.0b8}/jupyter_server_ydoc/utils.py +0 -0
  20. {jupyter_server_ydoc-1.0.0b5 → jupyter_server_ydoc-1.0.0b8}/jupyter_server_ydoc/websocketserver.py +0 -0
  21. {jupyter_server_ydoc-1.0.0b5 → jupyter_server_ydoc-1.0.0b8}/pyproject.toml +0 -0
  22. {jupyter_server_ydoc-1.0.0b5 → jupyter_server_ydoc-1.0.0b8}/setup.py +0 -0
  23. {jupyter_server_ydoc-1.0.0b5 → jupyter_server_ydoc-1.0.0b8}/tests/__init__.py +0 -0
  24. {jupyter_server_ydoc-1.0.0b5 → jupyter_server_ydoc-1.0.0b8}/tests/conftest.py +0 -0
  25. {jupyter_server_ydoc-1.0.0b5 → jupyter_server_ydoc-1.0.0b8}/tests/test_app.py +0 -0
  26. {jupyter_server_ydoc-1.0.0b5 → jupyter_server_ydoc-1.0.0b8}/tests/test_documents.py +0 -0
  27. {jupyter_server_ydoc-1.0.0b5 → jupyter_server_ydoc-1.0.0b8}/tests/test_handlers.py +0 -0
  28. {jupyter_server_ydoc-1.0.0b5 → jupyter_server_ydoc-1.0.0b8}/tests/test_loaders.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: jupyter-server-ydoc
3
- Version: 1.0.0b5
3
+ Version: 1.0.0b8
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
@@ -0,0 +1 @@
1
+ __version__ = "1.0.0b8"
@@ -39,9 +39,11 @@ class FileLoader:
39
39
 
40
40
  self._log = log or getLogger(__name__)
41
41
  self._subscriptions: dict[str, Callable[[], Coroutine[Any, Any, None]]] = {}
42
+ self._filepath_subscriptions: dict[str, Callable[[], Coroutine[Any, Any, None] | None]] = {}
42
43
 
43
44
  self._watcher = asyncio.create_task(self._watch_file()) if self._poll_interval else None
44
45
  self.last_modified = None
46
+ self._current_path = self.path
45
47
 
46
48
  @property
47
49
  def file_id(self) -> str:
@@ -79,7 +81,12 @@ class FileLoader:
79
81
  except asyncio.CancelledError:
80
82
  self._log.info(f"file watcher for '{self.file_id}' is cancelled now")
81
83
 
82
- def observe(self, id: str, callback: Callable[[], Coroutine[Any, Any, None]]) -> None:
84
+ def observe(
85
+ self,
86
+ id: str,
87
+ callback: Callable[[], Coroutine[Any, Any, None]],
88
+ filepath_callback: Callable[[], Coroutine[Any, Any, None] | None] | None = None,
89
+ ) -> None:
83
90
  """
84
91
  Subscribe to the file to get notified about out-of-band file changes.
85
92
 
@@ -88,6 +95,8 @@ class FileLoader:
88
95
  callback (Callable): Callback for notifying the room.
89
96
  """
90
97
  self._subscriptions[id] = callback
98
+ if filepath_callback is not None:
99
+ self._filepath_subscriptions[id] = filepath_callback
91
100
 
92
101
  def unobserve(self, id: str) -> None:
93
102
  """
@@ -97,6 +106,8 @@ class FileLoader:
97
106
  id (str): Room ID
98
107
  """
99
108
  del self._subscriptions[id]
109
+ if id in self._filepath_subscriptions.keys():
110
+ del self._filepath_subscriptions[id]
100
111
 
101
112
  async def load_content(self, format: str, file_type: str) -> dict[str, Any]:
102
113
  """
@@ -204,15 +215,26 @@ class FileLoader:
204
215
  Notifies subscribed rooms about out-of-band file changes.
205
216
  """
206
217
  do_notify = False
218
+ filepath_change = False
207
219
  async with self._lock:
220
+ path = self.path
221
+ if self._current_path != path:
222
+ self._current_path = path
223
+ filepath_change = True
224
+
208
225
  # Get model metadata; format and type are not need
209
- model = await ensure_async(self._contents_manager.get(self.path, content=False))
226
+ model = await ensure_async(self._contents_manager.get(path, content=False))
210
227
 
211
228
  if self.last_modified is not None and self.last_modified < model["last_modified"]:
212
229
  do_notify = True
213
230
 
214
231
  self.last_modified = model["last_modified"]
215
232
 
233
+ if filepath_change:
234
+ # Notify filepath change
235
+ for callback in self._filepath_subscriptions.values():
236
+ await ensure_async(callback())
237
+
216
238
  if do_notify:
217
239
  # Notify out-of-band change
218
240
  # callbacks will load the file content, thus release the lock before calling them
@@ -42,6 +42,7 @@ class DocumentRoom(YRoom):
42
42
  self._file_type: str = file_type
43
43
  self._file: FileLoader = file
44
44
  self._document = YDOCS.get(self._file_type, YFILE)(self.ydoc)
45
+ self._document.path = self._file.path
45
46
 
46
47
  self._logger = logger
47
48
  self._save_delay = save_delay
@@ -54,7 +55,7 @@ class DocumentRoom(YRoom):
54
55
 
55
56
  # Listen for document changes
56
57
  self._document.observe(self._on_document_change)
57
- self._file.observe(self.room_id, self._on_outofband_change)
58
+ self._file.observe(self.room_id, self._on_outofband_change, self._on_filepath_change)
58
59
 
59
60
  @property
60
61
  def file_format(self) -> str:
@@ -225,6 +226,12 @@ class DocumentRoom(YRoom):
225
226
  self._document.source = model["content"]
226
227
  self._document.dirty = False
227
228
 
229
+ def _on_filepath_change(self) -> None:
230
+ """
231
+ Update the document path property.
232
+ """
233
+ self._document.path = self._file.path
234
+
228
235
  def _on_document_change(self, target: str, event: Any) -> None:
229
236
  """
230
237
  Called when the shared document changes.
@@ -16,6 +16,9 @@ class FakeFileIDManager:
16
16
  def get_path(self, id: str) -> str:
17
17
  return self.mapping[id]
18
18
 
19
+ def move(self, id: str, new_path: str) -> None:
20
+ self.mapping[id] = new_path
21
+
19
22
 
20
23
  class FakeContentsManager:
21
24
  def __init__(self, model: dict):
@@ -75,3 +75,24 @@ async def test_undefined_save_delay_should_not_save_content_after_document_chang
75
75
  await asyncio.sleep(0.15)
76
76
 
77
77
  assert "save" not in cm.actions
78
+
79
+
80
+ # The following test should be restored when package versions are fixed.
81
+
82
+ # async def test_document_path(rtc_create_mock_document_room):
83
+ # id = "test-id"
84
+ # path = "test.txt"
85
+ # new_path = "test2.txt"
86
+
87
+ # _, loader, room = rtc_create_mock_document_room(id, path, "")
88
+
89
+ # await room.initialize()
90
+ # assert room._document.path == path
91
+
92
+ # # Update the path
93
+ # loader._file_id_manager.move(id, new_path)
94
+
95
+ # # Wait for a bit more than the poll_interval
96
+ # await asyncio.sleep(0.15)
97
+
98
+ # assert room._document.path == new_path
@@ -1 +0,0 @@
1
- __version__ = "1.0.0b5"