80 lines
2.2 KiB
TypeScript
80 lines
2.2 KiB
TypeScript
import { IndexeddbPersistence } from "y-indexeddb";
|
|
import { WebrtcProvider } from "y-webrtc";
|
|
import * as Y from "yjs";
|
|
|
|
import type { ConnectionStatus, OptionRecord } from "./state";
|
|
|
|
export interface AppSync {
|
|
doc: Y.Doc;
|
|
yTitle: Y.Text;
|
|
options: Y.Map<OptionRecord>;
|
|
votes: Y.Map<string>;
|
|
deadlineMap: Y.Map<unknown>;
|
|
provider: WebrtcProvider;
|
|
persistence: IndexeddbPersistence;
|
|
getConnectionStatus: () => ConnectionStatus;
|
|
getPeerCount: () => number;
|
|
destroy: () => void;
|
|
}
|
|
|
|
export function initSync(roomId: string): AppSync {
|
|
const doc = new Y.Doc();
|
|
const yTitle = doc.getText("poll-title");
|
|
const options = doc.getMap<OptionRecord>("poll-options");
|
|
const votes = doc.getMap<string>("poll-votes");
|
|
const deadlineMap = doc.getMap<unknown>("poll-deadline");
|
|
|
|
let connectionStatus: ConnectionStatus = navigator.onLine
|
|
? "connecting"
|
|
: "offline";
|
|
|
|
const provider = new WebrtcProvider(roomId, doc,{
|
|
signaling: ["ws://localhost:4444", "ws://lynxpi.ddns.net:4444"]
|
|
});
|
|
const persistence = new IndexeddbPersistence(roomId, doc);
|
|
|
|
const syncConnectionStatus = (status: ConnectionStatus) => {
|
|
connectionStatus = navigator.onLine ? status : "offline";
|
|
};
|
|
|
|
const handleOnline = () => {
|
|
syncConnectionStatus(provider.connected ? "connected" : "connecting");
|
|
};
|
|
const handleOffline = () => {
|
|
connectionStatus = "offline";
|
|
};
|
|
|
|
provider.on("status", (event: { connected: boolean }) => {
|
|
syncConnectionStatus(event.connected ? "connected" : "connecting");
|
|
});
|
|
|
|
provider.on("synced", ({ synced }: { synced: boolean }) => {
|
|
if (synced) syncConnectionStatus("connected");
|
|
});
|
|
|
|
window.addEventListener("online", handleOnline);
|
|
window.addEventListener("offline", handleOffline);
|
|
|
|
return {
|
|
doc,
|
|
yTitle,
|
|
options,
|
|
votes,
|
|
deadlineMap,
|
|
provider,
|
|
persistence,
|
|
getConnectionStatus: () => connectionStatus,
|
|
getPeerCount: () => {
|
|
const total = provider.awareness.getStates().size;
|
|
return Math.max(0, total - 1);
|
|
},
|
|
destroy: () => {
|
|
window.removeEventListener("online", handleOnline);
|
|
window.removeEventListener("offline", handleOffline);
|
|
persistence.destroy();
|
|
provider.destroy();
|
|
doc.destroy();
|
|
},
|
|
};
|
|
}
|