UNPKG

y-socket.io

Version:

Socket IO Connector for Yjs (Inspired by y-websocket)

146 lines (141 loc) 6.15 kB
#!/usr/bin/env node "use strict"; var C = Object.create; var y = Object.defineProperty; var Y = Object.getOwnPropertyDescriptor; var _ = Object.getOwnPropertyNames; var L = Object.getPrototypeOf, N = Object.prototype.hasOwnProperty; var E = (s, i, e, t) => { if (i && typeof i == "object" || typeof i == "function") for (let n of _(i)) !N.call(s, n) && n !== e && y(s, n, { get: () => i[n], enumerable: !(t = Y(i, n)) || t.enumerable }); return s; }; var p = (s, i, e) => (e = s != null ? C(L(s)) : {}, E( i || !s || !s.__esModule ? y(e, "default", { value: s, enumerable: !0 }) : e, s )); // src/server/server.ts var U = p(require("http")), D = require("socket.io"); // src/server/y-socket-io.ts var o = p(require("yjs")), m = p(require("y-protocols/awareness")), v = require("y-leveldb"); // src/server/document.ts var w = p(require("yjs")), u = p(require("y-protocols/awareness")), O = process.env.GC !== "false" && process.env.GC !== "0", d = class extends w.Doc { constructor(e, t, n) { super({ gc: O }); this.onUpdateDoc = (e) => { var t; if (((t = this.callbacks) == null ? void 0 : t.onUpdate) != null) try { this.callbacks.onUpdate(this, e); } catch (n) { console.warn(n); } this.namespace.emit("sync-update", e); }; this.onUpdateAwareness = ({ added: e, updated: t, removed: n }, a) => { var c; let l = e.concat(t, n), r = u.encodeAwarenessUpdate(this.awareness, l); if (((c = this.callbacks) == null ? void 0 : c.onChangeAwareness) != null) try { this.callbacks.onChangeAwareness(this, r); } catch (P) { console.warn(P); } this.namespace.emit("awareness-update", r); }; this.name = e, this.namespace = t, this.awareness = new u.Awareness(this), this.awareness.setLocalState(null), this.callbacks = n, this.awareness.on("update", this.onUpdateAwareness), this.on("update", this.onUpdateDoc); } async destroy() { var e; if (((e = this.callbacks) == null ? void 0 : e.onDestroy) != null) try { await this.callbacks.onDestroy(this); } catch (t) { console.warn(t); } this.awareness.off("update", this.onUpdateAwareness), this.off("update", this.onUpdateDoc), this.namespace.disconnectSockets(), super.destroy(); } }; // src/server/y-socket-io.ts var S = require("lib0/observable"), h = class extends S.Observable { constructor(e, t) { var n; super(); this._documents = /* @__PURE__ */ new Map(); this._levelPersistenceDir = null; this.persistence = null; this.nsp = null; this.initSyncListeners = (e, t) => { e.on("sync-step-1", (n, a) => { a(o.encodeStateAsUpdate(t, new Uint8Array(n))); }), e.on("sync-update", (n) => { o.applyUpdate(t, n, null); }); }; this.initAwarenessListeners = (e, t) => { e.on("awareness-update", (n) => { m.applyAwarenessUpdate(t.awareness, new Uint8Array(n), e); }); }; this.initSocketListeners = (e, t) => { e.on("disconnect", async () => { (await e.nsp.allSockets()).size === 0 && (this.emit("all-document-connections-closed", [t]), this.persistence != null && (await this.persistence.writeState(t.name, t), await t.destroy())); }); }; this.startSynchronization = (e, t) => { e.emit("sync-step-1", o.encodeStateVector(t), (n) => { o.applyUpdate(t, new Uint8Array(n), this); }), e.emit("awareness-update", m.encodeAwarenessUpdate(t.awareness, Array.from(t.awareness.getStates().keys()))); }; this.io = e, this._levelPersistenceDir = (n = t == null ? void 0 : t.levelPersistenceDir) != null ? n : process.env.YPERSISTENCE, this._levelPersistenceDir != null && this.initLevelDB(this._levelPersistenceDir), this.configuration = t; } initialize() { this.nsp = this.io.of(/^\/yjs\|.*$/), this.nsp.use(async (e, t) => { var n; return ((n = this.configuration) == null ? void 0 : n.authenticate) == null || await this.configuration.authenticate(e.handshake) ? t() : t(new Error("Unauthorized")); }), this.nsp.on("connection", async (e) => { var a; let t = e.nsp.name.replace(/\/yjs\|/, ""), n = await this.initDocument(t, e.nsp, (a = this.configuration) == null ? void 0 : a.gcEnabled); this.initSyncListeners(e, n), this.initAwarenessListeners(e, n), this.initSocketListeners(e, n), this.startSynchronization(e, n); }); } get documents() { return this._documents; } async initDocument(e, t, n = !0) { var l; let a = (l = this._documents.get(e)) != null ? l : new d(e, t, { onUpdate: (r, c) => this.emit("document-update", [r, c]), onChangeAwareness: (r, c) => this.emit("awareness-update", [r, c]), onDestroy: async (r) => { this._documents.delete(r.name), this.emit("document-destroy", [r]); } }); return a.gc = n, this._documents.has(e) || (this.persistence != null && await this.persistence.bindState(e, a), this._documents.set(e, a), this.emit("document-loaded", [a])), a; } initLevelDB(e) { let t = new v.LeveldbPersistence(e); this.persistence = { provider: t, bindState: async (n, a) => { let l = await t.getYDoc(n), r = o.encodeStateAsUpdate(a); await t.storeUpdate(n, r), o.applyUpdate(a, o.encodeStateAsUpdate(l)), a.on("update", async (c) => await t.storeUpdate(n, c)); }, writeState: async (n, a) => { } }; } }; // src/server/server.ts var g, z = (g = process.env.HOST) != null ? g : "localhost", A, f = parseInt(`${(A = process.env.PORT) != null ? A : 1234}`), b = U.default.createServer((s, i) => { i.writeHead(200, { "Content-Type": "application/json" }), i.end(JSON.stringify({ ok: !0 })); }), k = new D.Server(b), x = new h(k, {}); x.initialize(); k.on("connection", (s) => { console.log(`[connection] Connected with user: ${s.id}`), s.on("disconnect", () => { console.log(`[disconnect] Disconnected with user: ${s.id}`); }); }); b.listen(f, z, void 0, () => console.log(`Server running on port ${f}`)); //# sourceMappingURL=server.js.map