jupyter-server-ydoc 2.2.0a0__py3-none-any.whl → 2.2.1__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__ = "2.2.0.a0"
1
+ __version__ = "2.2.1"
@@ -86,7 +86,7 @@ class FileLoader:
86
86
  try:
87
87
  await self._watcher
88
88
  except asyncio.CancelledError:
89
- self._log.info(f"file watcher for '{self.file_id}' is cancelled now")
89
+ self._log.info(f"File watcher for '{self.file_id}' was cancelled")
90
90
 
91
91
  def observe(
92
92
  self,
@@ -30,7 +30,14 @@ def rtc_document_save_delay():
30
30
 
31
31
 
32
32
  @pytest.fixture
33
- def jp_server_config(jp_root_dir, jp_server_config, rtc_document_save_delay):
33
+ def rtc_document_cleanup_delay():
34
+ return 60
35
+
36
+
37
+ @pytest.fixture
38
+ def jp_server_config(
39
+ jp_root_dir, jp_server_config, rtc_document_save_delay, rtc_document_cleanup_delay
40
+ ):
34
41
  return {
35
42
  "ServerApp": {
36
43
  "jpserver_extensions": {
@@ -47,7 +54,10 @@ def jp_server_config(jp_root_dir, jp_server_config, rtc_document_save_delay):
47
54
  "db_path": str(jp_root_dir.joinpath(".fid_test.db")),
48
55
  "db_journal_mode": "OFF",
49
56
  },
50
- "YDocExtension": {"document_save_delay": rtc_document_save_delay},
57
+ "YDocExtension": {
58
+ "document_save_delay": rtc_document_save_delay,
59
+ "document_cleanup_delay": rtc_document_cleanup_delay,
60
+ },
51
61
  }
52
62
 
53
63
 
@@ -278,20 +278,28 @@ class DocumentRoom(YRoom):
278
278
  return
279
279
 
280
280
  self._saving_document = asyncio.create_task(
281
- self._maybe_save_document(self._saving_document)
281
+ self._maybe_save_document(self._saving_document, save_now=True)
282
282
  )
283
283
  return self._saving_document
284
284
 
285
- async def _maybe_save_document(self, saving_document: asyncio.Task | None) -> None:
285
+ async def _maybe_save_document(
286
+ self, saving_document: asyncio.Task | None, save_now: bool = False
287
+ ) -> None:
286
288
  """
287
289
  Saves the content of the document to disk.
288
290
 
289
291
  ### Note:
290
292
  There is a save delay to debounce the save since we could receive a high
291
293
  amount of changes in a short period of time. This way we can cancel the
292
- previous save.
294
+ previous save. When save_now is True, the delay is skipped and the save
295
+ executes immediately.
296
+
297
+ Parameters:
298
+ saving_document: The previous saving task to cancel if needed.
299
+ save_now: If True, skip the debounce delay, and save immediately.
300
+ This is used when manually saving.
293
301
  """
294
- if self._save_delay is None:
302
+ if self._save_delay is None and not save_now:
295
303
  return
296
304
  if saving_document is not None and not saving_document.done():
297
305
  # the document is being saved, cancel that
@@ -301,8 +309,10 @@ class DocumentRoom(YRoom):
301
309
  # because this coroutine is run in a cancellable task and cancellation is handled here
302
310
 
303
311
  try:
304
- # save after X seconds of inactivity
305
- await asyncio.sleep(self._save_delay)
312
+ # When save_now is False, wait X seconds of inactivity before saving (auto-save).
313
+ # When save_now is True, save immediately without debounce delay (manual save).
314
+ if not save_now and self._save_delay is not None:
315
+ await asyncio.sleep(self._save_delay)
306
316
 
307
317
  self.log.info("Saving the content from room %s", self._room_id)
308
318
  saved_model = await self._file.maybe_save_content(
@@ -27,10 +27,17 @@ class SQLiteYStore(LoggingConfigurable, _SQLiteYStore, metaclass=SQLiteYStoreMet
27
27
  directory.""",
28
28
  )
29
29
 
30
- document_ttl = Int(
30
+ squash_after_inactivity_of = Int(
31
31
  None,
32
32
  allow_none=True,
33
33
  config=True,
34
34
  help="""The document time-to-live in seconds. Defaults to None (document history is never
35
35
  cleared).""",
36
36
  )
37
+ document_ttl = Int(
38
+ None,
39
+ allow_none=True,
40
+ config=True,
41
+ help="""The document time-to-live in seconds. Deprecated in favor of 'squash_after_inactivity_of'.
42
+ Defaults to None (document history is never cleared).""",
43
+ )
@@ -33,13 +33,19 @@ class FakeContentsManager:
33
33
  "mimetype": None,
34
34
  "size": 0,
35
35
  "writable": False,
36
+ "hash": "fake_hash",
36
37
  }
37
38
  self.model.update(model)
38
39
 
39
40
  self.actions: list[str] = []
40
41
 
41
42
  def get(
42
- self, path: str, content: bool = True, format: str | None = None, type: str | None = None
43
+ self,
44
+ path: str,
45
+ content: bool = True,
46
+ format: str | None = None,
47
+ type: str | None = None,
48
+ require_hash: bool | None = None,
43
49
  ) -> dict:
44
50
  if not self.model:
45
51
  raise HTTPError(404, f"File not found: {path}")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: jupyter-server-ydoc
3
- Version: 2.2.0a0
3
+ Version: 2.2.1
4
4
  Summary: jupyter-server extension integrating collaborative shared models.
5
5
  Project-URL: Documentation, https://jupyterlab-realtime-collaboration.readthedocs.io/
6
6
  Project-URL: Repository, https://github.com/jupyterlab/jupyter-collaboration
@@ -0,0 +1,19 @@
1
+ jupyter_server_ydoc/__init__.py,sha256=B8H7XLhzgrTCQD8304Lx91FYXslwabsnV9OuYu4M4Hw,346
2
+ jupyter_server_ydoc/_version.py,sha256=4dqvKTDgbqeyzbWj6hYiNdzxsI8j1YOKSLM8vF6a0j4,22
3
+ jupyter_server_ydoc/app.py,sha256=hDqOeb-CBr48ck0WGlJvjzUH_5JvKFw0Eu5FTcW_IqU,8543
4
+ jupyter_server_ydoc/handlers.py,sha256=1ZCdwtrlqY2Q9d_A-HV2RL7-bmzcgKvF4H_6PoYoOpQ,28794
5
+ jupyter_server_ydoc/loaders.py,sha256=M4QBLwC3RadPiVO582jNmYSspoXulEP-QjAw8fYJ358,13606
6
+ jupyter_server_ydoc/pytest_plugin.py,sha256=cg8J0sDsJ4sfQDl_Uh73zz2sNecSY67udifXGtjYVt0,8935
7
+ jupyter_server_ydoc/rooms.py,sha256=s8ydZk5GaCQE9tQI37mURbgqWSimbMGESwNwLhIni_0,13697
8
+ jupyter_server_ydoc/stores.py,sha256=XW4U_8bDVjT_5ZLEtcTuINLusUeJmTTl4IuhUXDshEM,1423
9
+ jupyter_server_ydoc/test_utils.py,sha256=fcBtZdIQ2apBh85iC1tX9dXHJkfid5-7j9xGc-BzVQQ,1769
10
+ jupyter_server_ydoc/utils.py,sha256=_wI4CFOEZK4MSMYCZe2moSbggUTRdGxY4qTzSDEFzdE,2183
11
+ jupyter_server_ydoc/websocketserver.py,sha256=4Pxl4EIVIz5TxzNWlSDF6KNzZVkzy5SsgvwJx0PoGtY,5099
12
+ jupyter_server_ydoc/events/awareness.yaml,sha256=2FrCci5rZIaU4rn8pIPZJkd132YAZdzKjSNSwjOY7Dk,755
13
+ jupyter_server_ydoc/events/fork.yaml,sha256=3OrhQjhVyLjlBJWMiffbnZodL3GzFafLwEmSBFrK33o,1303
14
+ jupyter_server_ydoc/events/session.yaml,sha256=PS0MxowpRwY5QFYm-LJvHUxKHnsictV8_6VEwfhYxcQ,1596
15
+ jupyter_server_ydoc-2.2.1.data/data/etc/jupyter/jupyter_server_config.d/jupyter_collaboration.json,sha256=0thh2hJUxAKkZSmneJMG0U6QJRjdM6zGlwrTedEt-Jk,94
16
+ jupyter_server_ydoc-2.2.1.dist-info/METADATA,sha256=Sli3YMDmuSY-D3G1WcQp10sKTY9uab7PzBLQbq1nZqc,5571
17
+ jupyter_server_ydoc-2.2.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
18
+ jupyter_server_ydoc-2.2.1.dist-info/licenses/LICENSE,sha256=mhO0ZW9EiWOPg0dUgB-lNbJ0CGwRmTdbeAg_se1SOnY,2833
19
+ jupyter_server_ydoc-2.2.1.dist-info/RECORD,,
@@ -1,19 +0,0 @@
1
- jupyter_server_ydoc/__init__.py,sha256=B8H7XLhzgrTCQD8304Lx91FYXslwabsnV9OuYu4M4Hw,346
2
- jupyter_server_ydoc/_version.py,sha256=28LaRmloQfDtv6jpyB8JFhGWnl0P7q_winpQ_MJXoTw,25
3
- jupyter_server_ydoc/app.py,sha256=hDqOeb-CBr48ck0WGlJvjzUH_5JvKFw0Eu5FTcW_IqU,8543
4
- jupyter_server_ydoc/handlers.py,sha256=1ZCdwtrlqY2Q9d_A-HV2RL7-bmzcgKvF4H_6PoYoOpQ,28794
5
- jupyter_server_ydoc/loaders.py,sha256=fnlxbj-TowKUsB0zAwgnz3S999pjuy-K-Au5u9oespM,13609
6
- jupyter_server_ydoc/pytest_plugin.py,sha256=wpRsCss-TxgCeo8zqJru-YsKflfCGG-T2dbhcfQtMeY,8746
7
- jupyter_server_ydoc/rooms.py,sha256=dKronZ09LeXS7B5zLQwT6JMbsat75C22-MTg1tjbIq4,13086
8
- jupyter_server_ydoc/stores.py,sha256=9gI37OttJT17waClyDWssm7jtxCAXIcUHY7rc154OTk,1146
9
- jupyter_server_ydoc/test_utils.py,sha256=pD4gP44O7le-PSis7qQoVAKRJvutDOmav-wHRiHs4_U,1661
10
- jupyter_server_ydoc/utils.py,sha256=_wI4CFOEZK4MSMYCZe2moSbggUTRdGxY4qTzSDEFzdE,2183
11
- jupyter_server_ydoc/websocketserver.py,sha256=4Pxl4EIVIz5TxzNWlSDF6KNzZVkzy5SsgvwJx0PoGtY,5099
12
- jupyter_server_ydoc/events/awareness.yaml,sha256=2FrCci5rZIaU4rn8pIPZJkd132YAZdzKjSNSwjOY7Dk,755
13
- jupyter_server_ydoc/events/fork.yaml,sha256=3OrhQjhVyLjlBJWMiffbnZodL3GzFafLwEmSBFrK33o,1303
14
- jupyter_server_ydoc/events/session.yaml,sha256=PS0MxowpRwY5QFYm-LJvHUxKHnsictV8_6VEwfhYxcQ,1596
15
- jupyter_server_ydoc-2.2.0a0.data/data/etc/jupyter/jupyter_server_config.d/jupyter_collaboration.json,sha256=0thh2hJUxAKkZSmneJMG0U6QJRjdM6zGlwrTedEt-Jk,94
16
- jupyter_server_ydoc-2.2.0a0.dist-info/METADATA,sha256=wUgQm7OktX0JPiLodZ4OVK_IbU3ka-wROip6ddSyMuE,5573
17
- jupyter_server_ydoc-2.2.0a0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
18
- jupyter_server_ydoc-2.2.0a0.dist-info/licenses/LICENSE,sha256=mhO0ZW9EiWOPg0dUgB-lNbJ0CGwRmTdbeAg_se1SOnY,2833
19
- jupyter_server_ydoc-2.2.0a0.dist-info/RECORD,,