jupyter-ydoc 3.0.5__tar.gz → 3.2.0__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 (44) hide show
  1. {jupyter_ydoc-3.0.5 → jupyter_ydoc-3.2.0}/.github/workflows/check-release.yml +2 -2
  2. {jupyter_ydoc-3.0.5 → jupyter_ydoc-3.2.0}/.github/workflows/license-header.yml +1 -1
  3. {jupyter_ydoc-3.0.5 → jupyter_ydoc-3.2.0}/.github/workflows/publish-release.yml +1 -1
  4. {jupyter_ydoc-3.0.5 → jupyter_ydoc-3.2.0}/.github/workflows/test.yml +3 -3
  5. {jupyter_ydoc-3.0.5 → jupyter_ydoc-3.2.0}/.pre-commit-config.yaml +2 -2
  6. {jupyter_ydoc-3.0.5 → jupyter_ydoc-3.2.0}/CHANGELOG.md +41 -2
  7. {jupyter_ydoc-3.0.5 → jupyter_ydoc-3.2.0}/PKG-INFO +2 -2
  8. {jupyter_ydoc-3.0.5 → jupyter_ydoc-3.2.0}/javascript/package.json +12 -12
  9. {jupyter_ydoc-3.0.5 → jupyter_ydoc-3.2.0}/jupyter_ydoc/_version.py +1 -1
  10. {jupyter_ydoc-3.0.5 → jupyter_ydoc-3.2.0}/jupyter_ydoc/ynotebook.py +62 -14
  11. {jupyter_ydoc-3.0.5 → jupyter_ydoc-3.2.0}/jupyter_ydoc/yunicode.py +4 -0
  12. {jupyter_ydoc-3.0.5 → jupyter_ydoc-3.2.0}/pyproject.toml +1 -1
  13. {jupyter_ydoc-3.0.5 → jupyter_ydoc-3.2.0}/yarn.lock +1302 -541
  14. {jupyter_ydoc-3.0.5 → jupyter_ydoc-3.2.0}/.github/dependabot.yml +0 -0
  15. {jupyter_ydoc-3.0.5 → jupyter_ydoc-3.2.0}/.github/workflows/auto_author_assign.yml +0 -0
  16. {jupyter_ydoc-3.0.5 → jupyter_ydoc-3.2.0}/.github/workflows/enforce-label.yml +0 -0
  17. {jupyter_ydoc-3.0.5 → jupyter_ydoc-3.2.0}/.github/workflows/prep-release.yml +0 -0
  18. {jupyter_ydoc-3.0.5 → jupyter_ydoc-3.2.0}/.gitignore +0 -0
  19. {jupyter_ydoc-3.0.5 → jupyter_ydoc-3.2.0}/.licenserc.yaml +0 -0
  20. {jupyter_ydoc-3.0.5 → jupyter_ydoc-3.2.0}/.yarn/releases/yarn-3.4.1.cjs +0 -0
  21. {jupyter_ydoc-3.0.5 → jupyter_ydoc-3.2.0}/.yarnrc.yml +0 -0
  22. {jupyter_ydoc-3.0.5 → jupyter_ydoc-3.2.0}/LICENSE +0 -0
  23. {jupyter_ydoc-3.0.5 → jupyter_ydoc-3.2.0}/README.md +0 -0
  24. {jupyter_ydoc-3.0.5 → jupyter_ydoc-3.2.0}/docs/Makefile +0 -0
  25. {jupyter_ydoc-3.0.5 → jupyter_ydoc-3.2.0}/docs/make.bat +0 -0
  26. {jupyter_ydoc-3.0.5 → jupyter_ydoc-3.2.0}/docs/source/_static/jupyter_logo.svg +0 -0
  27. {jupyter_ydoc-3.0.5 → jupyter_ydoc-3.2.0}/docs/source/_static/logo-icon.png +0 -0
  28. {jupyter_ydoc-3.0.5 → jupyter_ydoc-3.2.0}/docs/source/conf.py +0 -0
  29. {jupyter_ydoc-3.0.5 → jupyter_ydoc-3.2.0}/docs/source/custom.md +0 -0
  30. {jupyter_ydoc-3.0.5 → jupyter_ydoc-3.2.0}/docs/source/index.md +0 -0
  31. {jupyter_ydoc-3.0.5 → jupyter_ydoc-3.2.0}/docs/source/javascript_api.rst +0 -0
  32. {jupyter_ydoc-3.0.5 → jupyter_ydoc-3.2.0}/docs/source/overview.md +0 -0
  33. {jupyter_ydoc-3.0.5 → jupyter_ydoc-3.2.0}/docs/source/python_api.rst +0 -0
  34. {jupyter_ydoc-3.0.5 → jupyter_ydoc-3.2.0}/docs/source/schema.md +0 -0
  35. {jupyter_ydoc-3.0.5 → jupyter_ydoc-3.2.0}/jupyter_ydoc/__init__.py +0 -0
  36. {jupyter_ydoc-3.0.5 → jupyter_ydoc-3.2.0}/jupyter_ydoc/py.typed +0 -0
  37. {jupyter_ydoc-3.0.5 → jupyter_ydoc-3.2.0}/jupyter_ydoc/utils.py +0 -0
  38. {jupyter_ydoc-3.0.5 → jupyter_ydoc-3.2.0}/jupyter_ydoc/ybasedoc.py +0 -0
  39. {jupyter_ydoc-3.0.5 → jupyter_ydoc-3.2.0}/jupyter_ydoc/yblob.py +0 -0
  40. {jupyter_ydoc-3.0.5 → jupyter_ydoc-3.2.0}/jupyter_ydoc/yfile.py +0 -0
  41. {jupyter_ydoc-3.0.5 → jupyter_ydoc-3.2.0}/lerna.json +0 -0
  42. {jupyter_ydoc-3.0.5 → jupyter_ydoc-3.2.0}/package.json +0 -0
  43. {jupyter_ydoc-3.0.5 → jupyter_ydoc-3.2.0}/pytest.ini +0 -0
  44. {jupyter_ydoc-3.0.5 → jupyter_ydoc-3.2.0}/readthedocs.yml +0 -0
@@ -19,7 +19,7 @@ jobs:
19
19
  node-version: ["14.x"]
20
20
  steps:
21
21
  - name: Checkout
22
- uses: actions/checkout@v4
22
+ uses: actions/checkout@v5
23
23
  - name: Base Setup
24
24
  uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
25
25
  - name: Install Dependencies
@@ -37,7 +37,7 @@ jobs:
37
37
  token: ${{ secrets.GITHUB_TOKEN }}
38
38
  - name: Upload Distributions
39
39
  if: ${{ matrix.group == 'check_release' }}
40
- uses: actions/upload-artifact@v4
40
+ uses: actions/upload-artifact@v5
41
41
  with:
42
42
  name: jupyter-releaser-dist-${{ github.run_number }}
43
43
  path: .jupyter_releaser_checkout/dist
@@ -13,7 +13,7 @@ jobs:
13
13
 
14
14
  steps:
15
15
  - name: Checkout
16
- uses: actions/checkout@v4
16
+ uses: actions/checkout@v5
17
17
  with:
18
18
  token: ${{ secrets.GITHUB_TOKEN }}
19
19
 
@@ -21,7 +21,7 @@ jobs:
21
21
  steps:
22
22
  - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
23
23
 
24
- - uses: actions/create-github-app-token@v1
24
+ - uses: actions/create-github-app-token@v2
25
25
  id: app-token
26
26
  with:
27
27
  app-id: ${{ vars.APP_ID }}
@@ -11,8 +11,8 @@ jobs:
11
11
  name: pre-commit
12
12
  runs-on: ubuntu-latest
13
13
  steps:
14
- - uses: actions/checkout@v4
15
- - uses: actions/setup-python@v5
14
+ - uses: actions/checkout@v5
15
+ - uses: actions/setup-python@v6
16
16
  - uses: pre-commit/action@v3.0.1
17
17
  with:
18
18
  extra_args: --all-files --hook-stage=manual
@@ -40,7 +40,7 @@ jobs:
40
40
  shell: bash -l {0}
41
41
  steps:
42
42
  - name: Checkout repository
43
- uses: actions/checkout@v4
43
+ uses: actions/checkout@v5
44
44
  - name: Install mamba
45
45
  uses: mamba-org/setup-micromamba@v2
46
46
  with:
@@ -1,6 +1,6 @@
1
1
  repos:
2
2
  - repo: https://github.com/pre-commit/pre-commit-hooks
3
- rev: v5.0.0
3
+ rev: v6.0.0
4
4
  hooks:
5
5
  - id: end-of-file-fixer
6
6
  - id: check-case-conflict
@@ -17,7 +17,7 @@ repos:
17
17
  exclude: ^\.yarn
18
18
 
19
19
  - repo: https://github.com/astral-sh/ruff-pre-commit
20
- rev: v0.11.8
20
+ rev: v0.14.4
21
21
  hooks:
22
22
  - id: ruff
23
23
  args: [--fix, --show-fixes]
@@ -2,6 +2,47 @@
2
2
 
3
3
  <!-- <START NEW CHANGELOG ENTRY> -->
4
4
 
5
+ ## 3.2.0
6
+
7
+ ([Full Changelog](https://github.com/jupyter-server/jupyter_ydoc/compare/@jupyter/ydoc@3.1.0...85206ea5cadcb7fc0419edc98fb47b765f3050b5))
8
+
9
+ ### Bugs fixed
10
+
11
+ - Improve reloading of documents to avoid spurious side-effects [#355](https://github.com/jupyter-server/jupyter_ydoc/pull/355) ([@krassowski](https://github.com/krassowski))
12
+ - Preserve `document_id` state when setting notebook source [#338](https://github.com/jupyter-server/jupyter_ydoc/pull/338) ([@apeng-stripe](https://github.com/apeng-stripe))
13
+
14
+ ### Maintenance and upkeep improvements
15
+
16
+ - Bump actions/upload-artifact from 4 to 5 [#349](https://github.com/jupyter-server/jupyter_ydoc/pull/349) ([@dependabot](https://github.com/dependabot))
17
+ - Bump actions/setup-python from 5 to 6 [#340](https://github.com/jupyter-server/jupyter_ydoc/pull/340) ([@dependabot](https://github.com/dependabot))
18
+ - Test against `pycrdt-websocket` `v0.16.0` & update dev dependencies [#339](https://github.com/jupyter-server/jupyter_ydoc/pull/339) ([@krassowski](https://github.com/krassowski))
19
+ - Bump actions/checkout from 4 to 5 [#337](https://github.com/jupyter-server/jupyter_ydoc/pull/337) ([@dependabot](https://github.com/dependabot))
20
+ - Bump actions/create-github-app-token from 1 to 2 [#318](https://github.com/jupyter-server/jupyter_ydoc/pull/318) ([@dependabot](https://github.com/dependabot))
21
+
22
+ ### Contributors to this release
23
+
24
+ ([GitHub contributors page for this release](https://github.com/jupyter-server/jupyter_ydoc/graphs/contributors?from=2025-07-01&to=2025-11-17&type=c))
25
+
26
+ [@apeng-stripe](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_ydoc+involves%3Aapeng-stripe+updated%3A2025-07-01..2025-11-17&type=Issues) | [@dependabot](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_ydoc+involves%3Adependabot+updated%3A2025-07-01..2025-11-17&type=Issues) | [@krassowski](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_ydoc+involves%3Akrassowski+updated%3A2025-07-01..2025-11-17&type=Issues) | [@pre-commit-ci](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_ydoc+involves%3Apre-commit-ci+updated%3A2025-07-01..2025-11-17&type=Issues)
27
+
28
+ <!-- <END NEW CHANGELOG ENTRY> -->
29
+
30
+ ## 3.1.0
31
+
32
+ ([Full Changelog](https://github.com/jupyter-server/jupyter_ydoc/compare/@jupyter/ydoc@3.0.5...280e6e33c0d283456e5519607186db08bccfaa5b))
33
+
34
+ ### Enhancements made
35
+
36
+ - Add `clearOutputs()` method to `ISharedCodeCell` [#330](https://github.com/jupyter-server/jupyter_ydoc/pull/330) ([@Darshan808](https://github.com/Darshan808))
37
+
38
+ ### Maintenance and upkeep improvements
39
+
40
+ ### Contributors to this release
41
+
42
+ ([GitHub contributors page for this release](https://github.com/jupyter-server/jupyter_ydoc/graphs/contributors?from=2025-05-07&to=2025-07-01&type=c))
43
+
44
+ [@Darshan808](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_ydoc+involves%3ADarshan808+updated%3A2025-05-07..2025-07-01&type=Issues) | [@pre-commit-ci](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_ydoc+involves%3Apre-commit-ci+updated%3A2025-05-07..2025-07-01&type=Issues)
45
+
5
46
  ## 3.0.5
6
47
 
7
48
  ([Full Changelog](https://github.com/jupyter-server/jupyter_ydoc/compare/@jupyter/ydoc@3.0.4...9a28796415aeb19ffaf0ca7f5fab2bf39ee04755))
@@ -16,8 +57,6 @@
16
57
 
17
58
  [@dlqqq](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_ydoc+involves%3Adlqqq+updated%3A2025-04-18..2025-05-07&type=Issues) | [@pre-commit-ci](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_ydoc+involves%3Apre-commit-ci+updated%3A2025-04-18..2025-05-07&type=Issues)
18
59
 
19
- <!-- <END NEW CHANGELOG ENTRY> -->
20
-
21
60
  ## 3.0.4
22
61
 
23
62
  ([Full Changelog](https://github.com/jupyter-server/jupyter_ydoc/compare/@jupyter/ydoc@3.0.3...accc3139a8bf5b5c7492a37af50309ffb810f7fd))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: jupyter-ydoc
3
- Version: 3.0.5
3
+ Version: 3.2.0
4
4
  Summary: Document structures for collaborative editing using Ypy
5
5
  Project-URL: Homepage, https://jupyter.org
6
6
  Project-URL: Source, https://github.com/jupyter-server/jupyter_ydoc
@@ -23,7 +23,7 @@ Provides-Extra: test
23
23
  Requires-Dist: httpx-ws>=0.5.2; extra == 'test'
24
24
  Requires-Dist: hypercorn>=0.16.0; extra == 'test'
25
25
  Requires-Dist: pre-commit; extra == 'test'
26
- Requires-Dist: pycrdt-websocket<0.16.0,>=0.15.0; extra == 'test'
26
+ Requires-Dist: pycrdt-websocket<0.17.0,>=0.16.0; extra == 'test'
27
27
  Requires-Dist: pytest; extra == 'test'
28
28
  Requires-Dist: pytest-asyncio; extra == 'test'
29
29
  Description-Content-Type: text/markdown
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jupyter/ydoc",
3
- "version": "3.0.5",
3
+ "version": "3.2.0",
4
4
  "type": "module",
5
5
  "description": "Jupyter document structures for collaborative editing using YJS",
6
6
  "homepage": "https://github.com/jupyter-server/jupyter_ydoc",
@@ -49,19 +49,19 @@
49
49
  "yjs": "^13.5.40"
50
50
  },
51
51
  "devDependencies": {
52
- "@types/jest": "^29.0.0",
53
- "@typescript-eslint/eslint-plugin": "^5.36.0",
54
- "@typescript-eslint/parser": "^5.36.0",
55
- "eslint": "^8.17.0",
56
- "eslint-config-prettier": "^8.5.0",
57
- "eslint-plugin-jest": "^27.0.0",
58
- "eslint-plugin-prettier": "^4.0.0",
59
- "jest": "^29.0.0",
60
- "prettier": "^2.8.4",
61
- "rimraf": "^4.4.0",
52
+ "@types/jest": "^29.2.0",
53
+ "@typescript-eslint/eslint-plugin": "^6.1.0",
54
+ "@typescript-eslint/parser": "^6.1.0",
55
+ "eslint": "^8.36.0",
56
+ "eslint-config-prettier": "^8.8.0",
57
+ "eslint-plugin-jest": "^27.6.0",
58
+ "eslint-plugin-prettier": "^5.0.0",
59
+ "jest": "^29.2.0",
60
+ "prettier": "^3.0.0",
61
+ "rimraf": "^5.0.1",
62
62
  "tsc-esm-fix": "^2.20.0",
63
63
  "typedoc": "^0.23.21",
64
- "typescript": "^4.9.5"
64
+ "typescript": "~5.8.0"
65
65
  },
66
66
  "publishConfig": {
67
67
  "access": "public"
@@ -1,4 +1,4 @@
1
1
  # This file is auto-generated by Hatchling. As such, do not:
2
2
  # - modify
3
3
  # - track in version control e.g. be sure to add to .gitignore
4
- __version__ = VERSION = '3.0.5'
4
+ __version__ = VERSION = '3.2.0'
@@ -3,7 +3,7 @@
3
3
 
4
4
  import copy
5
5
  from functools import partial
6
- from typing import Any, Callable, Dict, Optional
6
+ from typing import Any, Callable, Dict, List, Optional
7
7
  from uuid import uuid4
8
8
 
9
9
  from pycrdt import Array, Awareness, Doc, Map, Text
@@ -102,8 +102,11 @@ class YNotebook(YBaseDoc):
102
102
  :return: A cell.
103
103
  :rtype: Dict[str, Any]
104
104
  """
105
+ return self._cell_to_py(self._ycells[index])
106
+
107
+ def _cell_to_py(self, ycell: Map) -> Dict[str, Any]:
105
108
  meta = self._ymeta.to_py()
106
- cell = self._ycells[index].to_py()
109
+ cell = ycell.to_py()
107
110
  cell.pop("execution_state", None)
108
111
  cast_all(cell, float, int) # cells coming from Yjs have e.g. execution_count as float
109
112
  if "id" in cell and meta["nbformat"] == 4 and meta["nbformat_minor"] <= 4:
@@ -234,7 +237,7 @@ class YNotebook(YBaseDoc):
234
237
  nb_without_cells = {key: value[key] for key in value.keys() if key != "cells"}
235
238
  nb = copy.deepcopy(nb_without_cells)
236
239
  cast_all(nb, int, float) # Yjs expects numbers to be floating numbers
237
- cells = value["cells"] or [
240
+ new_cells = value["cells"] or [
238
241
  {
239
242
  "cell_type": "code",
240
243
  "execution_count": None,
@@ -245,24 +248,69 @@ class YNotebook(YBaseDoc):
245
248
  "id": str(uuid4()),
246
249
  }
247
250
  ]
251
+ old_ycells_by_id = {ycell["id"]: ycell for ycell in self._ycells}
248
252
 
249
253
  with self._ydoc.transaction():
250
- # clear document
251
- self._ymeta.clear()
252
- self._ycells.clear()
253
- for key in [k for k in self._ystate.keys() if k not in ("dirty", "path")]:
254
+ new_cell_list: List[dict] = []
255
+ retained_cells = set()
256
+
257
+ # Determine cells to be retained
258
+ for new_cell in new_cells:
259
+ cell_id = new_cell.get("id")
260
+ if cell_id and (old_ycell := old_ycells_by_id.get(cell_id)):
261
+ old_cell = self._cell_to_py(old_ycell)
262
+ if old_cell == new_cell:
263
+ new_cell_list.append(old_cell)
264
+ retained_cells.add(cell_id)
265
+ continue
266
+ # New or changed cell
267
+ new_cell_list.append(new_cell)
268
+
269
+ # First delete all non-retained cells
270
+ if not retained_cells:
271
+ # fast path if no cells were retained
272
+ self._ycells.clear()
273
+ else:
274
+ index = 0
275
+ for old_ycell in list(self._ycells):
276
+ if old_ycell["id"] not in retained_cells:
277
+ self._ycells.pop(index)
278
+ else:
279
+ index += 1
280
+
281
+ # Now add new cells
282
+ index = 0
283
+ for new_cell in new_cell_list:
284
+ if len(self._ycells) > index:
285
+ if self._ycells[index]["id"] == new_cell.get("id"):
286
+ # retained cell
287
+ index += 1
288
+ continue
289
+ self._ycells.insert(index, self.create_ycell(new_cell))
290
+ index += 1
291
+
292
+ for key in [
293
+ k for k in self._ystate.keys() if k not in ("dirty", "path", "document_id")
294
+ ]:
254
295
  del self._ystate[key]
255
296
 
256
- # initialize document
257
- self._ycells.extend([self.create_ycell(cell) for cell in cells])
258
- self._ymeta["nbformat"] = nb.get("nbformat", NBFORMAT_MAJOR_VERSION)
259
- self._ymeta["nbformat_minor"] = nb.get("nbformat_minor", NBFORMAT_MINOR_VERSION)
297
+ nbformat_major = nb.get("nbformat", NBFORMAT_MAJOR_VERSION)
298
+ nbformat_minor = nb.get("nbformat_minor", NBFORMAT_MINOR_VERSION)
299
+
300
+ if self._ymeta.get("nbformat") != nbformat_major:
301
+ self._ymeta["nbformat"] = nbformat_major
302
+
303
+ if self._ymeta.get("nbformat_minor") != nbformat_minor:
304
+ self._ymeta["nbformat_minor"] = nbformat_minor
260
305
 
306
+ old_y_metadata = self._ymeta.get("metadata")
307
+ old_metadata = old_y_metadata.to_py() if old_y_metadata else {}
261
308
  metadata = nb.get("metadata", {})
262
- metadata.setdefault("language_info", {"name": ""})
263
- metadata.setdefault("kernelspec", {"name": "", "display_name": ""})
264
309
 
265
- self._ymeta["metadata"] = Map(metadata)
310
+ if metadata != old_metadata:
311
+ metadata.setdefault("language_info", {"name": ""})
312
+ metadata.setdefault("kernelspec", {"name": "", "display_name": ""})
313
+ self._ymeta["metadata"] = Map(metadata)
266
314
 
267
315
  def observe(self, callback: Callable[[str, Any], None]) -> None:
268
316
  """
@@ -63,6 +63,10 @@ class YUnicode(YBaseDoc):
63
63
  :param value: The content of the document.
64
64
  :type value: str
65
65
  """
66
+ if self.get() == value:
67
+ # no-op if the values are already the same,
68
+ # to avoid side-effects such as cursor jumping to the top
69
+ return
66
70
  with self._ydoc.transaction():
67
71
  # clear document
68
72
  self._ysource.clear()
@@ -32,7 +32,7 @@ test = [
32
32
  "pytest-asyncio",
33
33
  "httpx-ws >=0.5.2",
34
34
  "hypercorn >=0.16.0",
35
- "pycrdt-websocket >=0.15.0,<0.16.0",
35
+ "pycrdt-websocket >=0.16.0,<0.17.0",
36
36
  ]
37
37
  docs = [
38
38
  "sphinx",