UNPKG

y-op-sqlite

Version:

<p align="center"> <img src="https://cdn.malts.me/6Wu0Fj.svg" /> </p>

121 lines (120 loc) 3.63 kB
var h = Object.defineProperty; var a = (o, e, t) => e in o ? h(o, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : o[e] = t; var n = (o, e, t) => (a(o, typeof e != "symbol" ? e + "" : e, t), t); import * as d from "yjs"; import { open as f } from "@op-engineering/op-sqlite"; const u = (o) => ( /** @type {Promise<T>} */ new Promise(o) ); Promise.all.bind(Promise); const i = () => /* @__PURE__ */ new Map(), b = (o, e, t) => { let s = o.get(e); return s === void 0 && o.set(e, s = t()), s; }, p = () => /* @__PURE__ */ new Set(), y = Array.from; class l { constructor() { this._observers = i(); } /** * @template {keyof EVENTS & string} NAME * @param {NAME} name * @param {EVENTS[NAME]} f */ on(e, t) { return b( this._observers, /** @type {string} */ e, p ).add(t), t; } /** * @template {keyof EVENTS & string} NAME * @param {NAME} name * @param {EVENTS[NAME]} f */ once(e, t) { const s = (...r) => { this.off( e, /** @type {any} */ s ), t(...r); }; this.on( e, /** @type {any} */ s ); } /** * @template {keyof EVENTS & string} NAME * @param {NAME} name * @param {EVENTS[NAME]} f */ off(e, t) { const s = this._observers.get(e); s !== void 0 && (s.delete(t), s.size === 0 && this._observers.delete(e)); } /** * Emit a named event. All registered event listeners that listen to the * specified name will receive the event. * * @todo This should catch exceptions * * @template {keyof EVENTS & string} NAME * @param {NAME} name The event name. * @param {Parameters<EVENTS[NAME]>} args The arguments that are applied to the event listener. */ emit(e, t) { return y((this._observers.get(e) || i()).values()).forEach((s) => s(...t)); } destroy() { this._observers = i(); } } const R = 500, _ = "opssqlite-persistence-"; class S extends l { constructor(t, s) { super(); n(this, "doc"); n(this, "name"); n(this, "whenSynced"); n(this, "db"); n(this, "synced", !1); n(this, "_dbref", 0); n(this, "_dbsize", 0); n(this, "_destroyed", !1); this.doc = s, this.name = t, this.whenSynced = u( (r) => this.on("synced", () => r(this)) ), this.db = f({ name: _ + t + ".sqlite" }), this.db.executeAsync( "CREATE TABLE IF NOT EXISTS updates (id INTEGER PRIMARY KEY, content BLOB)" ).then(() => { const r = d.encodeStateAsUpdate(s); r.length > 0 && this._storeUpdate(r, null); }).then( () => this.db.executeAsync("SELECT content FROM updates").catch((r) => console.error("error loading updates", r)) ).then((r) => { if (r != null && r.rows != null) for (const c of r.rows._array) d.applyUpdate(s, new Uint8Array(c.content)); this.synced = !0, this.emit("synced", [this]); }), this.destroy = this.destroy.bind(this), this._storeUpdate.bind(this), s.on("update", this._storeUpdate.bind(this)), s.on("destroy", this.destroy.bind(this)); } _storeUpdate(t, s) { if (!this.db || s == this) { !this.db && console.error("trying to store update without db"); return; } return this.db.executeAsync("INSERT INTO updates (content) VALUES (?)", [t]).catch((r) => console.error("error storing update", r)); } destroy() { return this.doc.off("update", this._storeUpdate), this.doc.off("destroy", this.destroy), this._destroyed = !0, this.db.close(); } } export { S as OPSQLitePersistence, R as PREFERRED_TRIM_SIZE }; //# sourceMappingURL=y-op-sqlite.mjs.map