jupyter-ydoc 3.3.3__tar.gz → 3.3.4__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.3.3 → jupyter_ydoc-3.3.4}/.github/workflows/auto_author_assign.yml +1 -1
  2. {jupyter_ydoc-3.3.3 → jupyter_ydoc-3.3.4}/.github/workflows/check-release.yml +1 -1
  3. {jupyter_ydoc-3.3.3 → jupyter_ydoc-3.3.4}/.pre-commit-config.yaml +1 -1
  4. {jupyter_ydoc-3.3.3 → jupyter_ydoc-3.3.4}/CHANGELOG.md +25 -2
  5. {jupyter_ydoc-3.3.3 → jupyter_ydoc-3.3.4}/PKG-INFO +1 -1
  6. {jupyter_ydoc-3.3.3 → jupyter_ydoc-3.3.4}/javascript/package.json +1 -1
  7. {jupyter_ydoc-3.3.3 → jupyter_ydoc-3.3.4}/jupyter_ydoc/_version.py +1 -1
  8. {jupyter_ydoc-3.3.3 → jupyter_ydoc-3.3.4}/jupyter_ydoc/ynotebook.py +37 -13
  9. {jupyter_ydoc-3.3.3 → jupyter_ydoc-3.3.4}/.github/dependabot.yml +0 -0
  10. {jupyter_ydoc-3.3.3 → jupyter_ydoc-3.3.4}/.github/workflows/enforce-label.yml +0 -0
  11. {jupyter_ydoc-3.3.3 → jupyter_ydoc-3.3.4}/.github/workflows/license-header.yml +0 -0
  12. {jupyter_ydoc-3.3.3 → jupyter_ydoc-3.3.4}/.github/workflows/prep-release.yml +0 -0
  13. {jupyter_ydoc-3.3.3 → jupyter_ydoc-3.3.4}/.github/workflows/publish-release.yml +0 -0
  14. {jupyter_ydoc-3.3.3 → jupyter_ydoc-3.3.4}/.github/workflows/test.yml +0 -0
  15. {jupyter_ydoc-3.3.3 → jupyter_ydoc-3.3.4}/.gitignore +0 -0
  16. {jupyter_ydoc-3.3.3 → jupyter_ydoc-3.3.4}/.licenserc.yaml +0 -0
  17. {jupyter_ydoc-3.3.3 → jupyter_ydoc-3.3.4}/.yarn/releases/yarn-3.4.1.cjs +0 -0
  18. {jupyter_ydoc-3.3.3 → jupyter_ydoc-3.3.4}/.yarnrc.yml +0 -0
  19. {jupyter_ydoc-3.3.3 → jupyter_ydoc-3.3.4}/LICENSE +0 -0
  20. {jupyter_ydoc-3.3.3 → jupyter_ydoc-3.3.4}/README.md +0 -0
  21. {jupyter_ydoc-3.3.3 → jupyter_ydoc-3.3.4}/docs/Makefile +0 -0
  22. {jupyter_ydoc-3.3.3 → jupyter_ydoc-3.3.4}/docs/make.bat +0 -0
  23. {jupyter_ydoc-3.3.3 → jupyter_ydoc-3.3.4}/docs/source/_static/jupyter_logo.svg +0 -0
  24. {jupyter_ydoc-3.3.3 → jupyter_ydoc-3.3.4}/docs/source/_static/logo-icon.png +0 -0
  25. {jupyter_ydoc-3.3.3 → jupyter_ydoc-3.3.4}/docs/source/conf.py +0 -0
  26. {jupyter_ydoc-3.3.3 → jupyter_ydoc-3.3.4}/docs/source/custom.md +0 -0
  27. {jupyter_ydoc-3.3.3 → jupyter_ydoc-3.3.4}/docs/source/index.md +0 -0
  28. {jupyter_ydoc-3.3.3 → jupyter_ydoc-3.3.4}/docs/source/javascript_api.rst +0 -0
  29. {jupyter_ydoc-3.3.3 → jupyter_ydoc-3.3.4}/docs/source/overview.md +0 -0
  30. {jupyter_ydoc-3.3.3 → jupyter_ydoc-3.3.4}/docs/source/python_api.rst +0 -0
  31. {jupyter_ydoc-3.3.3 → jupyter_ydoc-3.3.4}/docs/source/schema.md +0 -0
  32. {jupyter_ydoc-3.3.3 → jupyter_ydoc-3.3.4}/jupyter_ydoc/__init__.py +0 -0
  33. {jupyter_ydoc-3.3.3 → jupyter_ydoc-3.3.4}/jupyter_ydoc/py.typed +0 -0
  34. {jupyter_ydoc-3.3.3 → jupyter_ydoc-3.3.4}/jupyter_ydoc/utils.py +0 -0
  35. {jupyter_ydoc-3.3.3 → jupyter_ydoc-3.3.4}/jupyter_ydoc/ybasedoc.py +0 -0
  36. {jupyter_ydoc-3.3.3 → jupyter_ydoc-3.3.4}/jupyter_ydoc/yblob.py +0 -0
  37. {jupyter_ydoc-3.3.3 → jupyter_ydoc-3.3.4}/jupyter_ydoc/yfile.py +0 -0
  38. {jupyter_ydoc-3.3.3 → jupyter_ydoc-3.3.4}/jupyter_ydoc/yunicode.py +0 -0
  39. {jupyter_ydoc-3.3.3 → jupyter_ydoc-3.3.4}/lerna.json +0 -0
  40. {jupyter_ydoc-3.3.3 → jupyter_ydoc-3.3.4}/package.json +0 -0
  41. {jupyter_ydoc-3.3.3 → jupyter_ydoc-3.3.4}/pyproject.toml +0 -0
  42. {jupyter_ydoc-3.3.3 → jupyter_ydoc-3.3.4}/pytest.ini +0 -0
  43. {jupyter_ydoc-3.3.3 → jupyter_ydoc-3.3.4}/readthedocs.yml +0 -0
  44. {jupyter_ydoc-3.3.3 → jupyter_ydoc-3.3.4}/yarn.lock +0 -0
@@ -12,4 +12,4 @@ jobs:
12
12
  assign-author:
13
13
  runs-on: ubuntu-latest
14
14
  steps:
15
- - uses: toshimaru/auto-author-assign@v2.1.1
15
+ - uses: toshimaru/auto-author-assign@v3.0.1
@@ -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@v5
40
+ uses: actions/upload-artifact@v6
41
41
  with:
42
42
  name: jupyter-releaser-dist-${{ github.run_number }}
43
43
  path: .jupyter_releaser_checkout/dist
@@ -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.14.8
20
+ rev: v0.14.10
21
21
  hooks:
22
22
  - id: ruff
23
23
  args: [--fix, --show-fixes]
@@ -2,6 +2,31 @@
2
2
 
3
3
  <!-- <START NEW CHANGELOG ENTRY> -->
4
4
 
5
+ ## 3.3.4
6
+
7
+ ([Full Changelog](https://github.com/jupyter-server/jupyter_ydoc/compare/@jupyter/ydoc@3.3.3...654e8f80f619c7820dd82dfbe3c6d985b6a69e28))
8
+
9
+ ### Bugs fixed
10
+
11
+ - Fix cell duplication when YStore diverges from disk [#376](https://github.com/jupyter-server/jupyter_ydoc/pull/376) ([@jordanhboxer](https://github.com/jordanhboxer), [@davidbrochart](https://github.com/davidbrochart), [@dmonad](https://github.com/dmonad), [@krassowski](https://github.com/krassowski))
12
+
13
+ ### Maintenance and upkeep improvements
14
+
15
+ - Bump toshimaru/auto-author-assign from 3.0.0 to 3.0.1 [#375](https://github.com/jupyter-server/jupyter_ydoc/pull/375) ([@davidbrochart](https://github.com/davidbrochart))
16
+ - Bump toshimaru/auto-author-assign from 2.1.1 to 3.0.0 [#373](https://github.com/jupyter-server/jupyter_ydoc/pull/373) ([@davidbrochart](https://github.com/davidbrochart))
17
+ - Bump actions/upload-artifact from 5 to 6 [#371](https://github.com/jupyter-server/jupyter_ydoc/pull/371) ([@davidbrochart](https://github.com/davidbrochart))
18
+
19
+ ### Contributors to this release
20
+
21
+ The following people contributed discussions, new ideas, code and documentation contributions, and review.
22
+ See [our definition of contributors](https://github-activity.readthedocs.io/en/latest/#how-does-this-tool-define-contributions-in-the-reports).
23
+
24
+ ([GitHub contributors page for this release](https://github.com/jupyter-server/jupyter_ydoc/graphs/contributors?from=2025-12-10&to=2026-01-09&type=c))
25
+
26
+ @davidbrochart ([activity](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_ydoc+involves%3Adavidbrochart+updated%3A2025-12-10..2026-01-09&type=Issues)) | @dmonad ([activity](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_ydoc+involves%3Admonad+updated%3A2025-12-10..2026-01-09&type=Issues)) | @jordanhboxer ([activity](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_ydoc+involves%3Ajordanhboxer+updated%3A2025-12-10..2026-01-09&type=Issues)) | @krassowski ([activity](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_ydoc+involves%3Akrassowski+updated%3A2025-12-10..2026-01-09&type=Issues))
27
+
28
+ <!-- <END NEW CHANGELOG ENTRY> -->
29
+
5
30
  ## 3.3.3
6
31
 
7
32
  ([Full Changelog](https://github.com/jupyter-server/jupyter_ydoc/compare/@jupyter/ydoc@3.3.2...3900efdeefef21eb6e117fdd30827ee4c9149ff3))
@@ -18,8 +43,6 @@
18
43
 
19
44
  [@krassowski](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_ydoc+involves%3Akrassowski+updated%3A2025-12-01..2025-12-10&type=Issues) | [@pre-commit-ci](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_ydoc+involves%3Apre-commit-ci+updated%3A2025-12-01..2025-12-10&type=Issues)
20
45
 
21
- <!-- <END NEW CHANGELOG ENTRY> -->
22
-
23
46
  ## 3.3.2
24
47
 
25
48
  ([Full Changelog](https://github.com/jupyter-server/jupyter_ydoc/compare/@jupyter/ydoc@3.3.1...87e205209dbfed2d367424e6913c88916e77d98e))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: jupyter-ydoc
3
- Version: 3.3.3
3
+ Version: 3.3.4
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jupyter/ydoc",
3
- "version": "3.3.3",
3
+ "version": "3.3.4",
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",
@@ -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.3.3'
4
+ __version__ = VERSION = '3.3.4'
@@ -251,7 +251,13 @@ class YNotebook(YBaseDoc):
251
251
  "id": str(uuid4()),
252
252
  }
253
253
  ]
254
- old_ycells_by_id: dict[str, Map] = {ycell["id"]: ycell for ycell in self._ycells}
254
+ # Build dict of old cells by ID, keeping only the first occurrence of each ID
255
+ # to handle the case where the stored doc already has duplicate IDs.
256
+ old_ycells_by_id: dict[str, Map] = {}
257
+ for ycell in self._ycells:
258
+ cell_id = ycell.get("id")
259
+ if cell_id is not None and cell_id not in old_ycells_by_id:
260
+ old_ycells_by_id[cell_id] = ycell
255
261
 
256
262
  with self._ydoc.transaction():
257
263
  new_cell_list: list[dict] = []
@@ -267,34 +273,52 @@ class YNotebook(YBaseDoc):
267
273
  )
268
274
 
269
275
  if updated_granularly:
270
- new_cell_list.append(old_cell)
276
+ new_cell_list.append(new_cell)
271
277
  retained_cells.add(cell_id)
272
278
  continue
273
279
  # New or changed cell
274
280
  new_cell_list.append(new_cell)
275
281
 
276
- # First delete all non-retained cells
282
+ # First delete all non-retained cells and duplicates
277
283
  if not retained_cells:
278
284
  # fast path if no cells were retained
279
285
  self._ycells.clear()
280
286
  else:
281
287
  index = 0
288
+ seen: set[str] = set()
282
289
  for old_ycell in list(self._ycells):
283
- if old_ycell["id"] not in retained_cells:
290
+ cell_id = old_ycell.get("id")
291
+ if cell_id is None or cell_id not in retained_cells or cell_id in seen:
284
292
  self._ycells.pop(index)
285
293
  else:
294
+ seen.add(cell_id)
286
295
  index += 1
287
296
 
288
- # Now add new cells
289
- index = 0
290
- for new_cell in new_cell_list:
291
- if len(self._ycells) > index:
292
- if self._ycells[index]["id"] == new_cell.get("id"):
293
- # retained cell
294
- index += 1
295
- continue
297
+ # Now reorder/insert cells to match new_cell_list
298
+ for index, new_cell in enumerate(new_cell_list):
299
+ new_id = new_cell.get("id")
300
+
301
+ # Fast path: correct cell already at this position
302
+ if len(self._ycells) > index and self._ycells[index].get("id") == new_id:
303
+ continue
304
+
305
+ # Retained cell: find and move it into position
306
+ if new_id is not None and new_id in retained_cells:
307
+ # Linear scan to find the cell (O(n) per retained cell)
308
+ for cur in range(index + 1, len(self._ycells)):
309
+ if self._ycells[cur].get("id") == new_id:
310
+ # Use delete+recreate instead of move() for yjs 13.x compatibility
311
+ # (yjs 13.x doesn't support the move operation that pycrdt generates)
312
+ del self._ycells[cur]
313
+ self._ycells.insert(index, self.create_ycell(new_cell))
314
+ break
315
+ continue
316
+
317
+ # New cell: insert at position
296
318
  self._ycells.insert(index, self.create_ycell(new_cell))
297
- index += 1
319
+
320
+ # Remove any extra cells at the end
321
+ del self._ycells[len(new_cell_list) :]
298
322
 
299
323
  for key in [
300
324
  k for k in self._ystate.keys() if k not in ("dirty", "path", "document_id")
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes