References kept to objects within the synced store become empty on their own
douira opened this issue · 7 comments
An error occurs in the following reproduction sandbox (adapted from the one in the documentation for syncedstore and vue). There are two input fields, the first one uses the reactive object contained within the store for getting the model property. The second one uses the full reference path to the store. The first input field errors when it's touched by the user (the value changed) since the object becomes empty because SyncedStore modifies it in a weird way.
https://codesandbox.io/s/sandpack-project-forked-p3fkw6?file=/src/App.vue
<template>
<main id="app">
baz.title.foo.content
<input
autocomplete="off"
v-model="baz.title.foo.content"
/>
store.documents.baz.title.foo.content
<input
autocomplete="off"
v-model="store.documents.baz.title.foo.content"
/>
</main>
</template>
<script>
import { store } from "./store";
import { ref } from "vue";
import * as Vue from "vue";
import { enableVueBindings } from "@syncedstore/core";
// make SyncedStore use Vuejs internally
enableVueBindings(Vue);
export default {
name: "App",
setup() {
store.documents.baz = {
completed: false,
title: {
foo: {
content: "foo",
user: null
}
}
};
const baz = store.documents.baz;
return {
store, // Put the store on the data() of the component
baz
};
}
};
</script>
...
import { syncedStore, getYjsValue } from "@syncedstore/core";
import { WebrtcProvider } from "y-webrtc";
type Todo = {
completed: boolean
title: {
foo: {
content: string,
user: null
}
}
}
export const store = syncedStore({
documents: {} as Record<string, Todo>
})
...
I tried reproducing it, but it worked fine in this sandbox:
https://codesandbox.io/s/sandpack-project-forked-tr1bjc?file=/src/store.ts
I've passed a clean roomname "vue-issue-debug" to WebrtcProvider
, perhaps the data was syncing with another project that corrupted the store?
I tried reproducing it, but it worked fine in this sandbox:
https://codesandbox.io/s/sandpack-project-forked-tr1bjc?file=/src/store.ts
I've passed a clean roomname "vue-issue-debug" to
WebrtcProvider
, perhaps the data was syncing with another project that corrupted the store?
It appears that syncing is causing the problem for me. I've used a random clean roomname and the issue is happening. It only happens if there are actually two browser tabs open with the same roomname so that syncing does happen. Then entering any character into the input field results in Cannot read properties of undefined (reading 'foo')
. If you'd like I can record a video of the exact reproduction steps.
Got it. The issue here is that you store a local value using const baz = store.documents.baz;
However, when syncing across clients, store.documents can be overwritten by a sync. This means baz
is no longer valid. You should therefor reference your object from store
directly
I'll have to work with functions that access the properties or computed getters or sth then. Thanks for the clarification!
Maybe a hint about this behavior could be added to the documentation? It's not immediately obvious that the library behaves in this way since by default, reactive references in Vue don't suddenly become invalidated.
I think this would go wrong in native Vue as well to be honest. It might not give an error, but if you'd overwrite store.documents.baz
from somewhere else, then the dereferenced "baz" should be outdated
You're right, that would break it too.