import { Project } from "../models/project"; import { usePrevious } from "./use-previous"; import * as jsonpatch from 'fast-json-patch'; import { useEffect, useState } from "preact/hooks"; import { Operation } from "fast-json-patch"; export interface ServerSyncOptions { baseUrl: string } export const defaultOptions = { baseUrl: `ws://${window.location.host}/ws`, } export function useServerSync(project: Project, options: ServerSyncOptions = defaultOptions) { options = Object.assign({}, defaultOptions, options); const [ conn, setConn ] = useState(() => { const conn = new WebSocket(`${options.baseUrl}/${project.id}`); conn.onerror = (evt: Event) => { console.error(evt); }; conn.onopen = (evt: Event) => { console.log('ws connection opened'); }; return conn; }); const [ ops, setOps ] = useState([]); useEffect(() => { return () => { if (!conn) return; console.log('closing ws'); conn.close(); conn.onerror = null; conn.onopen = null; }; }, []); useEffect(() => { conn.send(JSON.stringify(ops)); setOps([]); }, [ops.length > 0]); let previousProject: Project|any = usePrevious(project); if (!previousProject) previousProject = {}; const newOps = jsonpatch.compare(previousProject, project); if (ops.length === 0) return; setOps(ops => [...ops, newOps]); }