jupyter-server-ydoc 1.0.0b6__py3-none-any.whl → 1.0.0b8__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.
@@ -1 +1 @@
1
- __version__ = "1.0.0b6"
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):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: jupyter-server-ydoc
3
- Version: 1.0.0b6
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
@@ -1,18 +1,18 @@
1
1
  jupyter_server_ydoc/__init__.py,sha256=B8H7XLhzgrTCQD8304Lx91FYXslwabsnV9OuYu4M4Hw,346
2
- jupyter_server_ydoc/_version.py,sha256=ajvVBO3s82jFaWgmuxKgMBKuik170Y7v3eDsSfXF7-o,24
2
+ jupyter_server_ydoc/_version.py,sha256=FINJxficj37iURkarZ-YupPPH4azy-E4XBpiEqZ9uDU,24
3
3
  jupyter_server_ydoc/app.py,sha256=8vOKWLYa4OKu8Pw24TLWtbgs2SfH0_R64dPrErdWyQM,7739
4
4
  jupyter_server_ydoc/handlers.py,sha256=delGUrN9pslVmkxgDEolbemLvOGHW4Sb8m41IOuQBZA,23816
5
- jupyter_server_ydoc/loaders.py,sha256=3k2xiXNyzhC9CXAW0gkgac-8YTFwEuSa1QdmI_xHoYc,9733
5
+ jupyter_server_ydoc/loaders.py,sha256=TijilImdgYk9K91cXEIP_DzkOr6phSddwQFpLI5l_RA,10564
6
6
  jupyter_server_ydoc/pytest_plugin.py,sha256=pSw5KGHid4qRgu1PqQ-GiNOH7IBSWudXQX21J43cB3o,6805
7
- jupyter_server_ydoc/rooms.py,sha256=aqiF-6wGMsgwvT5toos6ax2b__h1B0WY-uVf6O_FXas,12009
7
+ jupyter_server_ydoc/rooms.py,sha256=lv1VIIOv26_K1lMEHB3ocyjLWP4Pk05-h3mO97uYiS4,12238
8
8
  jupyter_server_ydoc/stores.py,sha256=_5J6eNs3R5Tv88PCc-GGuszxQstfvNoBCYABqzBzJXA,1004
9
- jupyter_server_ydoc/test_utils.py,sha256=QEtV4d_ZNe9g-EOTsoMoqT1qCbGEu2qMlPmPxliog80,1451
9
+ jupyter_server_ydoc/test_utils.py,sha256=IFXUPf1efHd4DgC1GT7ZMJMhKryKlB0Lx4vU2-mhz4Q,1540
10
10
  jupyter_server_ydoc/utils.py,sha256=yQC-uRdLyFDYbt2Zms_hA1HyjlwznMK4yQ3_FUwTlnQ,2013
11
11
  jupyter_server_ydoc/websocketserver.py,sha256=7fLPJcWczD-4R_-LXtfvNxM_pUXFasZWDmT4RIrOQHE,5150
12
12
  jupyter_server_ydoc/events/awareness.yaml,sha256=9isoK58uue7lqMnlHqyfQt29z16Otkh14oRe1k5vbKM,753
13
13
  jupyter_server_ydoc/events/session.yaml,sha256=A7Wt7czyx38MXp5fpDbH7HLS0QNkeOqaEhHdP2x-0Mo,1594
14
- jupyter_server_ydoc-1.0.0b6.data/data/etc/jupyter/jupyter_server_config.d/jupyter_collaboration.json,sha256=0thh2hJUxAKkZSmneJMG0U6QJRjdM6zGlwrTedEt-Jk,94
15
- jupyter_server_ydoc-1.0.0b6.dist-info/METADATA,sha256=8-iKo3w7Y0tCmVzBOllbS9Wys_eSzlCTIHt-hmgh0Mc,5012
16
- jupyter_server_ydoc-1.0.0b6.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
17
- jupyter_server_ydoc-1.0.0b6.dist-info/licenses/LICENSE,sha256=mhO0ZW9EiWOPg0dUgB-lNbJ0CGwRmTdbeAg_se1SOnY,2833
18
- jupyter_server_ydoc-1.0.0b6.dist-info/RECORD,,
14
+ jupyter_server_ydoc-1.0.0b8.data/data/etc/jupyter/jupyter_server_config.d/jupyter_collaboration.json,sha256=0thh2hJUxAKkZSmneJMG0U6QJRjdM6zGlwrTedEt-Jk,94
15
+ jupyter_server_ydoc-1.0.0b8.dist-info/METADATA,sha256=fae7vmqLAiIHfFyMxv0DMQkh1cyN1HcmkI1LkIZCFmk,5012
16
+ jupyter_server_ydoc-1.0.0b8.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
17
+ jupyter_server_ydoc-1.0.0b8.dist-info/licenses/LICENSE,sha256=mhO0ZW9EiWOPg0dUgB-lNbJ0CGwRmTdbeAg_se1SOnY,2833
18
+ jupyter_server_ydoc-1.0.0b8.dist-info/RECORD,,