Fix node resolution and Vue reactivity in useReplicatedModels for composite models#2222
Draft
Fix node resolution and Vue reactivity in useReplicatedModels for composite models#2222
Conversation
Co-authored-by: abstraktor <569215+abstraktor@users.noreply.github.com>
Co-authored-by: abstraktor <569215+abstraktor@users.noreply.github.com>
Co-authored-by: abstraktor <569215+abstraktor@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Fix critical bugs in useReplicatedModels implementation
Fix node resolution and Vue reactivity in useReplicatedModels for composite models
Dec 11, 2025
Contributor
Collaborator
|
@copilot fix the test and make sure it is indeed verifying this misbehavior to be gone. consider testing it in MutableModelTreeJsTest |
Added comprehensive tests to verify: - Nodes from multiple models can be resolved correctly - Change listeners work across all models in composite - Consistent node wrappers are returned for same node reference These tests directly verify the bug fix at the Kotlin layer, ensuring that the CompositeModel-based node resolution works correctly when multiple models are used together. Co-authored-by: abstraktor <569215+abstraktor@users.noreply.github.com>
Author
Added comprehensive Kotlin tests in MutableModelTreeJsTest (commit 99f3cbc) that directly verify the bug fix:
These tests verify the actual behavior at the Kotlin layer where the fix was applied, ensuring the CompositeModel-based node resolution works correctly. Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
e09fa3d to
8d26c35
Compare
3f62921 to
7836e0f
Compare
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.
When using multiple models, each tree's
ChangeListenerwas resolving nodes only from its own tree and wrapping them inconsistently, causing "node not found" errors and breaking Vue's reactivity cache.Changes
Modified
ChangeListenerinMutableModelTreeJsImpl.ktCompositeModelparameter to resolve nodes across all treesmodel.tryResolveNode(nodeId)instead ofNodeInMutableModel(tree, nodeId)AutoTransactionsNode(node, model)to maintain cache identityAdded Kotlin tests in
MutableModelTreeJsTest.ktAdded TypeScript regression tests in
useReplicatedModels.test.tsTechnical Detail
Before:
After:
This ensures the same node reference always produces the same wrapper object, which Vue's cache requires for reactivity tracking.
Testing
The fix is verified at both layers:
MutableModelTreeJsTest.kt): Tests the core node resolution and change listener behavior with real composite modelsuseReplicatedModels.test.ts): Tests the Vue.js integration and reactivity behaviorOriginal prompt
Problem
The
useReplicatedModelsimplementation has critical bugs causing:Root Cause
In
MutableModelTreeJsImpl.kt, when multiple trees are used, each tree gets its ownChangeListenerthat wraps nodes using only that specific tree:The problem: When a change occurs in one tree, the
ChangeListenertries to resolve the node reference using only its own tree. But in a composite model, nodes might belong to different trees, causing:ChangeListenerprocesses it. Vue's cache uses node references as keys, butNodeInMutableModel(treeA, nodeId)andNodeInMutableModel(treeB, nodeId)are different objects with different identities, breaking cache lookups.Additionally, even with a single model, the backwards-compatibility wrapper in
useReplicatedModelgoes through the composite model path, which changes how nodes are wrapped compared to the old implementation.Required Fixes
1. Fix ChangeListener to use CompositeModel for node resolution
File:
model-client/src/jsMain/kotlin/org/modelix/model/client2/MutableModelTreeJsImpl.ktModify
ChangeListenerto accept and use theCompositeModelfor node resolution:And update the initialization in
MutableModelTreeJsImpl:2. Add regression tests
File:
vue-model-api/src/useReplicatedModels.test.tsAdd comprehensive tests to verify: