Trouble with Svelte
mlaass opened this issue · comments
I'm trying to get the svelte examples to work on my local machine
So far I have removed the yjs
dependency from the package because it would trigger an error/warning and added items = items
in the submit function, which leads to the item list being re-rendered.
It then shows, that items have been submitted before.
What is missing though, is that the when new items are added from other windows, or when the window loads, no rendering is triggered.
I'm not quite sure how to go about this. But I'm guessing there is something not quite right in this function in @syncedstore/svelte
:
export function svelteSyncedStore<T>(syncedObject: T) {
let set: any;
const observer = new Observer(() => {
if (set) {
set(store);
}
});
const store = reactive(syncedObject, observer);
const readableStore = readable(store, (newSet) => {
set = newSet;
return () => {
set = undefined;
};
});
return {
subscribe: readableStore.subscribe,
set: () => {}
}
}
Any help in making this work would be appreciated. I'm happy to do a PR once I get this to work.
@mlaass - To ensure that the rendering is triggered when new items are added or when the window loads, you can modify the svelteSyncedStore
function as follows:
export function svelteSyncedStore<T>(syncedObject: T) {
let set: any;
const observer = new Observer(() => {
if (set) {
set(store);
}
});
const store = reactive(syncedObject, observer);
const readableStore = readable(store, (newSet) => {
set = newSet;
set(store); // Trigger initial rendering
return () => {
set = undefined;
};
});
return {
subscribe: readableStore.subscribe,
set: (newValue) => {
store = newValue; // Update the store value
if (set) {
set(store); // Trigger rendering
}
}
}
}
In this modified version, I've made a couple of changes:
- I added
set(store)
in thereadableStore
callback to trigger the initial rendering when the store is subscribed to. - I modified the
set
function to accept anewValue
parameter and update the store value accordingly. After updating the store value, it triggers the rendering by callingset(store)
if it exists.
With these modifications, the rendering should be triggered when new items are added from other windows or when the window loads.
in the example I found out that in order for it to work you have to see to that webrtc is not used on the server side, so i added this, and now it works perfectly.
store.ts
import { syncedStore, getYjsDoc } from "@syncedstore/core";
import type { WebrtcProvider } from "y-webrtc";
import { svelteSyncedStore } from "@syncedstore/svelte";
// Create your SyncedStore store
export const store = syncedStore({ todos: [] });
export const svelteStore = svelteSyncedStore(store);
let webrtcProvider:WebrtcProvider;
console.log(import.meta.env.MODE);
//prevent server side
if (typeof window !== 'undefined') {
const { WebrtcProvider } = await import('y-webrtc');
// Create a document that syncs automatically using Y-WebRTC
const doc = getYjsDoc(store);
webrtcProvider = new WebrtcProvider("syncedstore-todos", doc);
}
export const disconnect = () => webrtcProvider.disconnect();
export const connect = () => webrtcProvider.connect();
It should be noted that the code I'm working with was sourced from the webpage and the example provided is a bit different from the current code in the repository.