export class NoteSocket { constructor({ workspaceSlug, noteSlug, password, onStatus, onAuthenticated, onDocument, onError }) { Object.assign(this, { workspaceSlug, noteSlug, password, onStatus, onAuthenticated, onDocument, onError }); this.socket = null; this.timer = null; this.closed = false; } connect() { clearTimeout(this.timer); this.onStatus?.("connecting"); const protocol = location.protocol === "https:" ? "wss:" : "ws:"; this.socket = new WebSocket(`${protocol}//${location.host}/ws/${encodeURIComponent(this.workspaceSlug)}/${encodeURIComponent(this.noteSlug)}`); this.socket.addEventListener("open", () => this.socket.send(JSON.stringify({ type: "authenticate", password: this.password || null }))); this.socket.addEventListener("message", (event) => { const message = JSON.parse(event.data); if (message.type === "error") { this.onError?.(message.message); this.closed = true; this.socket.close(); } if (message.type === "authenticated") { this.onStatus?.("online"); this.onAuthenticated?.(message); } if (message.type === "document") this.onDocument?.(message); }); this.socket.addEventListener("close", () => { if (!this.closed) { this.onStatus?.("offline"); this.timer = setTimeout(() => this.connect(), 1500); } }); this.socket.addEventListener("error", () => this.socket.close()); } update(content) { if (this.socket?.readyState === WebSocket.OPEN) this.socket.send(JSON.stringify({ type: "update", content })); } stop() { this.closed = true; clearTimeout(this.timer); this.socket?.close(); } } export class PadSocket { constructor({ slug, password, onStatus, onAuthenticated, onDocument, onError }) { Object.assign(this, { slug, password, onStatus, onAuthenticated, onDocument, onError }); this.socket = null; this.timer = null; this.closed = false; } connect() { clearTimeout(this.timer); this.closed = false; this.onStatus?.("connecting"); const protocol = location.protocol === "https:" ? "wss:" : "ws:"; this.socket = new WebSocket(`${protocol}//${location.host}/ws/p/${encodeURIComponent(this.slug)}`); this.socket.addEventListener("open", () => this.socket.send(JSON.stringify({ type: "authenticate", password: this.password || null }))); this.socket.addEventListener("message", (event) => { const message = JSON.parse(event.data); if (message.type === "error") { this.onError?.(message.message); this.closed = true; this.socket.close(); } if (message.type === "authenticated") { this.onStatus?.("online"); this.onAuthenticated?.(message); } if (message.type === "document") this.onDocument?.(message); }); this.socket.addEventListener("close", () => { if (!this.closed) { this.onStatus?.("offline"); this.timer = setTimeout(() => this.connect(), 1500); } }); this.socket.addEventListener("error", () => this.socket.close()); } update(content) { if (this.socket?.readyState === WebSocket.OPEN) this.socket.send(JSON.stringify({ type: "update", content })); } stop() { this.closed = true; clearTimeout(this.timer); this.socket?.close(); } }