Live Y::Map handles: read and edit shared maps from Ruby - #33
Open
jpcamara wants to merge 6 commits into
Open
Conversation
This was referenced Jul 1, 2026
Owner
Author
|
Rebased onto |
This was referenced Jul 1, 2026
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
jpcamara
force-pushed
the
feat/live-maps
branch
2 times, most recently
from
August 4, 2026 05:21
96d2709 to
a81b296
Compare
Expose the first actual yrs shared type for building/editing state from Ruby. `Doc#get_map(name)` returns a live `Y::Map` handle: reads reflect the current document, writes mutate the CRDT (so changes sync to every peer). Supports `map[key]`, `map[key] = value`, `get`/`set`, `delete`, `clear`, `keys`, `size`/`length`, `key?`/`has_key?`, `to_h`, and `each`. Values round-trip primitives, arrays, and nested hashes; a nested hash becomes a real nested `Y.Map`, and `map.get_map(key)` returns a live handle to it so mutating the child mutates the document. Symbol keys stringify. Thread safety mirrors `Y::Doc` exactly: every operation opens its own transaction inside `nogvl` (GVL released) and holds no lock across the GVL boundary. Ruby values are read/built only with the GVL held, before/after the closure, which works purely on `Send` data (an `InValue` intermediate). A handle is addressed by root name plus a path of keys and re-resolves per operation, so it never caches a raw yrs branch pointer that could dangle when the tree is mutated (possibly on another thread) -- a nested handle keeps working even as sibling keys change around it. `Y::Map` is asserted `Send + Sync` at compile time alongside `Doc`. Covered by test/map_test.rb (round-trips, nested live maps, sync propagation, concurrent access) and Rust unit tests for the pure Send-side helpers. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017TeaovH2jyHARHJSyQ8Afo
jpcamara
force-pushed
the
feat/live-maps
branch
from
August 5, 2026 18:59
a81b296 to
08de5ac
Compare
# Conflicts: # CHANGELOG.md
The README examples now execute in the test suite; a literal ... in the each block is not valid Ruby.
# Conflicts: # README.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Exposes the first yrs shared type for building and editing state from Ruby, not just opaque CRDT sync.
Doc#get_map(name)returns a liveY::Maphandle: reads reflect the current document and writes mutate the CRDT, so changes sync to every peer.Full surface:
[]/get,[]=/set,get_map,delete,clear,keys,size/length,key?/has_key?,to_h,each. Values round-trip primitives, arrays, and nested hashes (a nested hash becomes a real nestedY.Map). Symbol keys stringify. This complements the read-onlyread_text/read_xml/read_mapsnapshots.Thread safety mirrors
Y::Doc:nogvl(GVL released) and holds no lock across the GVL boundary.Senddata via anInValueintermediate, so no Ruby calls happen off-GVL.Y::Mapis assertedSend + Syncat compile time alongsideDoc.Tests:
test/map_test.rb(29 tests) covers round-trips, assignment-returns-value, nested live maps, deep nesting,get_mapon non-map/missing, live-handle-survives-reassignment, sync propagation to a peer, and an 8-thread concurrent read/write stress test. Rust unit tests cover the pureSend-side helpers (resolve,to_in,invalue_to_any). Full suite green: 201 Ruby runs, 38 Rust tests, clippy/rustfmt/rubocop clean. No version bump; the entry sits in the Unreleased section.