Skip to content

feat: support insert_embed shared types in Text - #408

Merged
davidbrochart merged 4 commits into
y-crdt:mainfrom
samuelstecher:feat/text-insert-embed-shared-types
Jul 23, 2026
Merged

feat: support insert_embed shared types in Text#408
davidbrochart merged 4 commits into
y-crdt:mainfrom
samuelstecher:feat/text-insert-embed-shared-types

Conversation

@samuelstecher

@samuelstecher samuelstecher commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Summary

Support embedding shared types (Array, Map, Text) in a Text via insert_embed(), returning a live, mutable handle to the integrated child.

This brings Text to parity with XmlText, whose insert_embed already integrates shared types (added in #390, released in v0.13.1). Text.insert_embed still hardcoded the immutable-JSON path (py_to_any) and discarded the integrated reference returned by yrs.

The underlying yrs library already returns the integrated ArrayRef/MapRef/TextRef from Text::insert_embed for preliminary types, so this simply exposes the existing capability through the pyo3 bindings, reusing the same _do_and_integrate path already used by Map/Array/XmlText.

Motivation

Enables inline, mutable nested structures inside a single collaborative Text avoiding expensive re-inserts.

Changes

  • src/text.rs: Add insert_array_prelim, insert_map_prelim, insert_text_prelim to Text (mirror the existing XmlText equivalents).
  • python/pycrdt/_text.py: Dispatch BaseType embeds through _do_and_integrate (same pattern as XmlText.insert_embed); primitives keep the existing path.
  • tests/test_text.py: Add test_insert_embed_shared_types (integration + mutability + attrs + diff() types).
  • CHANGELOG.md: Add entry.

Tests

> python -m pytest tests/test_text.py -v
============================= test session starts ==============================
platform darwin -- Python 3.12.12, pytest-9.1.1, pluggy-1.6.0
collected 14 items

tests/test_text.py::test_iterate PASSED                                  [  7%]
tests/test_text.py::test_str PASSED                                      [ 14%]
tests/test_text.py::test_api PASSED                                      [ 21%]
tests/test_text.py::test_to_py PASSED                                    [ 28%]
tests/test_text.py::test_prelim PASSED                                   [ 35%]
tests/test_text.py::test_slice PASSED                                    [ 42%]
tests/test_text.py::test_formatting PASSED                               [ 50%]
tests/test_text.py::test_insert_embed_shared_types PASSED                [ 57%]
tests/test_text.py::test_observe PASSED                                  [ 64%]
tests/test_text.py::test_iterate_events[asyncio] PASSED                  [ 71%]
tests/test_text.py::test_iterate_events[trio] PASSED                     [ 78%]
tests/test_text.py::test_sticky_index[to_json] PASSED                    [ 85%]
tests/test_text.py::test_sticky_index[encode] PASSED                     [ 92%]
tests/test_text.py::test_sticky_index_transaction PASSED                 [100%]

============================== 14 passed in 0.15s ==============================

The full suite passes (238 passed) with 100% coverage maintained; mypy python and ruff/ruff-format are clean.

Made with Cursor

Allow embedding Array, Map and Text shared types in a Text via
insert_embed(), returning a live, integrated handle that can be mutated
afterwards. This brings Text to parity with XmlText, which already
supported embedding shared types.

The underlying yrs library already returns the integrated reference from
Text::insert_embed for preliminary types, so this simply exposes the
existing capability through the pyo3 bindings, reusing the same
_do_and_integrate path used by Map/Array/XmlText.

Co-authored-by: Cursor <cursoragent@cursor.com>
Comment thread tests/test_text.py Outdated
Comment thread CHANGELOG.md Outdated
samuelstecher and others added 2 commits July 23, 2026 12:07
Co-authored-by: David Brochart <david.brochart@gmail.com>
Co-authored-by: David Brochart <david.brochart@gmail.com>
@davidbrochart

Copy link
Copy Markdown
Collaborator

Sorry @samuelstecher, my suggestion in the test was wrong. The types are not the Python types but the integrated types indeed (e.g. not Text but _pycrdt.Text), which raises the question whether they should be the former instead of the latter?

@samuelstecher

Copy link
Copy Markdown
Contributor Author

@davidbrochart its a good point. I originally submitted it like this because these assertions match the test suite of XmlText.insert_embed (see test_xml.py L149-151 in def test_text())

I agree that it would be more convenient if Text.diff() returned the python types instead of the integrated ones. I'll see what that entails for both Text and XmlText.

This would be a breaking change though right?

Wrap embedded shared types returned by Text.diff() and XmlText.diff() in
their pycrdt type (Array/Map/Text/XmlText) via _maybe_as_type_or_doc,
instead of leaking the raw _pycrdt objects. This matches how Map and
Array already return values from __getitem__. Primitive embeds (bytes,
str) are unchanged.

Co-authored-by: Cursor <cursoragent@cursor.com>
@davidbrochart

Copy link
Copy Markdown
Collaborator

@davidbrochart its a good point. I originally submitted it like this because these assertions match the test suite of XmlText.insert_embed (see test_xml.py L149-151 in def test_text())

Indeed, I didn't remember I wrote that.

This would be a breaking change though right?

Unfortunately yes, but I think it's better like that since as you said "this matches how Map and
Array already return values from __getitem__".

@samuelstecher

Copy link
Copy Markdown
Contributor Author

@davidbrochart I pushed the changes that align both Text and XmlText.
Please review and let me know if there's anything more you need from me to land this PR :)

@davidbrochart davidbrochart left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @samuelstecher, that looks good to me.
I don't think this can be considered a breaking change, I rather see it as a fix since previously the returned integrated types were pretty useless, and I doubt anyone ever used them.

@davidbrochart
davidbrochart merged commit 013b0a2 into y-crdt:main Jul 23, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants