y-op-sqlite
Version:
<p align="center"> <img src="https://cdn.malts.me/6Wu0Fj.svg" /> </p>
121 lines (120 loc) • 3.63 kB
JavaScript
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