Skip to content

Complete rewrite of valtio-yjs architecture#62

Closed
agcty wants to merge 163 commits intovaltiojs:mainfrom
agcty:main
Closed

Complete rewrite of valtio-yjs architecture#62
agcty wants to merge 163 commits intovaltiojs:mainfrom
agcty:main

Conversation

@agcty
Copy link
Copy Markdown

@agcty agcty commented Oct 3, 2025

This is a complete rewrite of valtio-yjs, took lots of tinkering and quite a bit of research, would love to get feedback and please feel free to challenge the new design, I know there's lots more that can be improved / made more stable but this now feels like a solid based to further build on. Docs are quite extensive and should cover most areas but of course there are a couple of limitations (especially yjs leaf types), maybe someone with more knowledge on valtio internals (@dai-shi 👀) has better solutions.

agcty added 14 commits October 2, 2025 16:19
Removed debug/diagnostic tests that were only needed for troubleshooting:
- ytext-internal-observer.spec.tsx
- ytext-observer-firing.spec.tsx
- ytext-reactivity-debug.spec.tsx
- ytext-snapshot-tracking.spec.tsx
- ytext-valtio-internals-debug.spec.tsx
- ytext-version-counter-debug.spec.tsx
- getter-debug.spec.tsx
- valtio-computed-test.spec.tsx
- valtio-symbol-test.spec.ts

Removed old implementation files:
- leaf-reactivity.ts (replaced by leaf-computed.ts)
- leaf-wrapper.ts (no longer used)

Removed temporary test files:
- examples/06_ytext/test-controlled-input.html
- examples/06_ytext/test-reactivity.html
- valtio-yjs/tests/ytext-reactivity.test.ts

Added production-ready tests:
- ytext-reactivity.spec.tsx (5 comprehensive reactivity tests)
- ytext-typing-sequential.spec.tsx (sequential typing tests)

Added final documentation:
- YTEXT-REACTIVITY-FIXED.md (summary of the fix)
Reverted the reference identity caching that was breaking basic reactivity.
Reference identity is nice-to-have but not essential - what matters is that:
1. Y.Text works correctly
2. React components re-render when Y.Text changes
3. The underlying Y.Text content is correct

Updated test to check for correct behavior rather than strict reference identity:
- Test now verifies both references are Y.Text instances with correct content
- Renamed test to 'Y.Text persists and works correctly after modifications'

All Y.Text reactivity tests now pass ✅
Updated Y.Text collaboration e2e test to verify correct behavior rather than
strict reference identity:
- Changed test name from 'Y.Text reference remains stable across edits' to
  'Y.Text works correctly and syncs across edits'
- Verify Y.Text instances work correctly and have correct content
- Don't require proxy wrapper references to be identical

All 464 tests now pass ✅
…ility

- Extract filterMapOperations() for filtering internal/nested operations
- Extract rollbackArrayChanges() and rollbackMapChanges() for validation rollback
- Extract processYMapEntries() for categorizing Y.Map entries
- Extract defineLeafPropertyOnMap() and setupLeafObserverForMap() for leaf setup
- Extract processYArrayItems() and setupLeafNodesInArray() for Y.Array processing

This improves code organization and makes the bridge logic more maintainable,
especially with the recent leaf reactivity additions.
- Simplify intro with clear value proposition
- Add progressive learning curve (Quick Start → React → Collaboration → Recipes)
- Consolidate advanced topics (Performance, Y.Text, XML) into focused sections
- Streamline Best Practices section with clear Do's and Don'ts
- Reduce verbosity while keeping all important information
- Improve scanability with better section flow
- Inspired by Zustand's README structure
Remove 'alpha' warning and communicate readiness for production use while still welcoming feedback on limitations
@dai-shi
Copy link
Copy Markdown
Member

dai-shi commented Oct 3, 2025

First thing first, the rewrite is welcome, but would you please keep the current test? Otherwise, it can't tell.

agcty added 4 commits October 4, 2025 12:52
- Added clear documentation that direct array.length manipulation is not supported
- Explained why: CRDT semantics, collaborative conflicts, JSON serialization
- Provided splice() alternatives in README and detailed docs
- Removed commented-out isLengthSetOp function from array-ops-planner.ts
- Design decision: this is a collaborative sync library, not a JS array emulator
…bering

- Renamed tests/old -> tests/basic (these are basic feature demonstrations, not 'old' tests)
- Renumbered test files sequentially (01-06) after removing deprecated tests
- Improved file names for clarity:
  - 05_maparray -> 03_maparray
  - 07_nested_map -> 04_nested_map
  - 08_arrayitemmove -> 05_array_move
  - 10_length_mutation -> 06_array_length
- Updated vitest.config.ts to reflect new path
- All tests passing (37 passed, 1 skipped)
Added 07_showcase.spec.ts to demonstrate advanced features:

1. Identity Preservation - Objects maintain identity across updates (React-friendly)
2. Lazy Materialization + Deep Reconciliation - Syncs deep changes without materializing
3. Complex Nested Deletion - Handles nested structures with children correctly
4. Concurrent Editing Without Conflicts - Multiple users editing simultaneously
5. Reusing Child References - Advanced pattern for preserving child proxies
6. Collaborative Text Editing - Y.Text integration with Valtio reactivity
7. Automatic Transaction Batching - 100 mutations become 1 transaction

These capabilities showcase what makes the new architecture more powerful and
production-ready compared to the old bind() approach.
@agcty
Copy link
Copy Markdown
Author

agcty commented Oct 4, 2025

Ah you're right, re-added the tests under tests/basic/. Note that it's a totally different architecture though so it's really not comparable 1:1, it's much more complex but with with lots of improvements that wouldn't work any other way. It now uses a reconciler pattern similar to react in a way which allows for batching, optimizations etc. Best would be to look into the examples to get a feel for how it works. It's so different in fact that I don't even know if a PR like this makes sense, maybe it should be its own project? Idk but we needed it internally and wouldn't make sense to not open source, gather feedback etc.

@dai-shi
Copy link
Copy Markdown
Member

dai-shi commented Oct 26, 2025

(sorry for the delay, being busy still)

@dai-shi
Copy link
Copy Markdown
Member

dai-shi commented Oct 31, 2025

Note that it's a totally different architecture though so it's really not comparable 1:1

I see. It's not a compatible rewrite, but a complete rearchitecture.

It now uses a reconciler pattern similar to react in a way which allows for batching, optimizations etc.

Looking at the code and hearing that, my suggestion is to create a new package.

I can invite you @agcty to https://github.com/valtiojs to create a repo. Let me know if you would like it. Alternatively, you can create a repo under your profile.

@dai-shi dai-shi closed this Oct 31, 2025
@agcty
Copy link
Copy Markdown
Author

agcty commented Oct 31, 2025

@dai-shi i think it would make more sense for this to be available in valtiojs than in our company's account. I would rename it valtio-y for now or do you have a better name?

@dai-shi
Copy link
Copy Markdown
Member

dai-shi commented Oct 31, 2025

@agcty valtio-y sounds good! Sent an invitation.

@agcty
Copy link
Copy Markdown
Author

agcty commented Nov 1, 2025

@dai-shi thanks! created a new private repo and am currently working on better readme/docs/guides, should be finished in the next couple of days. Also set up ci/cd but the npm publish token is missing, are you using one account wide token or should i create a specific one?

@agcty
Copy link
Copy Markdown
Author

agcty commented Nov 1, 2025

@dai-shi actually made a couple of changes to the docs now, will add the rest later, especially around providers etc. but other than that i think it's pretty ready aside from the publishing side

@dai-shi
Copy link
Copy Markdown
Member

dai-shi commented Nov 1, 2025

@agcty

are you using one account wide token or should i create a specific one?

It has an org-wide token, which should be accessible for public repo, but the token isn't configured for valtio-y anyway, so please create a repo-wide token and use it for now. Later, if you give me a permission for the package, I'll renew the org-wide token.

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