UNPKG

codelabs.y-socket.io

Version:

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

146 lines (141 loc) 6.12 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 = (a, i, t, e) => { if (i && typeof i == "object" || typeof i == "function") for (let n of _(i)) !N.call(a, n) && n !== t && y(a, n, { get: () => i[n], enumerable: !(e = Y(i, n)) || e.enumerable }); return a; }; var p = (a, i, t) => (t = a != null ? C(L(a)) : {}, E( i || !a || !a.__esModule ? y(t, "default", { value: a, enumerable: !0 }) : t, a )); // 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(t, e, n) { super({ gc: O }); this.onUpdateDoc = (t) => { var e; if (((e = this.callbacks) == null ? void 0 : e.onUpdate) != null) try { this.callbacks.onUpdate(this, t); } catch (n) { console.warn(n); } this.namespace.emit("sync-update", t); }; this.onUpdateAwareness = ({ added: t, updated: e, removed: n }, s) => { var l; let c = t.concat(e, n), r = u.encodeAwarenessUpdate(this.awareness, c); if (((l = this.callbacks) == null ? void 0 : l.onChangeAwareness) != null) try { this.callbacks.onChangeAwareness(this, r); } catch (P) { console.warn(P); } this.namespace.emit("awareness-update", r); }; this.name = t, this.namespace = e, 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 t; if (((t = this.callbacks) == null ? void 0 : t.onDestroy) != null) try { await this.callbacks.onDestroy(this); } catch (e) { console.warn(e); } 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(t, e) { var n; super(); this._documents = /* @__PURE__ */ new Map(); this._levelPersistenceDir = null; this.persistence = null; this.initSyncListeners = (t, e) => { t.on("sync-step-1", (n, s) => { s(o.encodeStateAsUpdate(e, new Uint8Array(n))); }), t.on("sync-update", (n) => { o.applyUpdate(e, n, null); }); }; this.initAwarenessListeners = (t, e) => { t.on("awareness-update", (n) => { m.applyAwarenessUpdate(e.awareness, new Uint8Array(n), t); }); }; this.initSocketListeners = (t, e) => { t.on("disconnect", async () => { (await t.nsp.allSockets()).size === 0 && (this.emit("all-document-connections-closed", [e]), this.persistence != null && (await this.persistence.writeState(e.name, e), await e.destroy())); }); }; this.startSynchronization = (t, e) => { t.emit("sync-step-1", o.encodeStateVector(e), (n) => { o.applyUpdate(e, new Uint8Array(n), this); }), t.emit("awareness-update", m.encodeAwarenessUpdate(e.awareness, Array.from(e.awareness.getStates().keys()))); }; this.io = t, this._levelPersistenceDir = (n = e == null ? void 0 : e.levelPersistenceDir) != null ? n : process.env.YPERSISTENCE, this._levelPersistenceDir != null && this.initLevelDB(this._levelPersistenceDir), this.configuration = e; } initialize() { let t = this.io.of(/^\/yjs\|.*$/); t.use(async (e, n) => { var s; return ((s = this.configuration) == null ? void 0 : s.authenticate) == null || await this.configuration.authenticate(e.handshake) ? n() : n(new Error("Unauthorized")); }), t.on("connection", async (e) => { var c; let n = e.nsp.name.replace(/\/yjs\|/, ""), s = await this.initDocument(n, e.nsp, (c = this.configuration) == null ? void 0 : c.gcEnabled); this.initSyncListeners(e, s), this.initAwarenessListeners(e, s), this.initSocketListeners(e, s), this.startSynchronization(e, s); }); } get documents() { return this._documents; } async initDocument(t, e, n = !0) { var c; let s = (c = this._documents.get(t)) != null ? c : new d(t, e, { onUpdate: (r, l) => this.emit("document-update", [r, l]), onChangeAwareness: (r, l) => this.emit("awareness-update", [r, l]), onDestroy: async (r) => { this._documents.delete(r.name), this.emit("document-destroy", [r]); } }); return s.gc = n, this._documents.has(t) || (this.persistence != null && await this.persistence.bindState(t, s), this._documents.set(t, s), this.emit("document-loaded", [s])), s; } initLevelDB(t) { let e = new v.LeveldbPersistence(t); this.persistence = { provider: e, bindState: async (n, s) => { let c = await e.getYDoc(n), r = o.encodeStateAsUpdate(s); await e.storeUpdate(n, r), o.applyUpdate(s, o.encodeStateAsUpdate(c)), s.on("update", async (l) => await e.storeUpdate(n, l)); }, writeState: async (n, s) => { } }; } }; // 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((a, 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", (a) => { console.log(`[connection] Connected with user: ${a.id}`), a.on("disconnect", () => { console.log(`[disconnect] Disconnected with user: ${a.id}`); }); }); b.listen(f, z, void 0, () => console.log(`Server running on port ${f}`)); //# sourceMappingURL=server.js.map