UNPKG

y-cap-sqlite

Version:

y-cap-sqlite is a persistence provider for [Yjs](https://github.com/yjs/yjs) that uses [@capacitor-community/sqlite](https://github.com/capacitor-community/sqlite) to store document changes in a SQLite database. This is useful for Capacitor projects that

85 lines (84 loc) 2.79 kB
// src/index.ts import * as Y from "yjs"; import * as promise from "lib0/promise"; import { ObservableV2 } from "lib0/observable"; import { Buffer } from "buffer"; var DB_PREFIX = "cap-sqlite-persistence-"; var CapSQLitePersistence = class _CapSQLitePersistence extends ObservableV2 { doc; config; whenSynced; name; db; con; synced = false; _dbref = 0; _dbsize = 0; _destroyed = false; constructor(config, doc, name, sqlite) { super(); this.doc = doc; this.config = config; this.name = name; this.con = sqlite; this.whenSynced = promise.create( (resolve) => this.on("synced", () => resolve(this)) ); this.destroy = this.destroy.bind(this); this._storeUpdate.bind(this); doc.on("update", this._storeUpdate.bind(this)); doc.on("destroy", this.destroy.bind(this)); } async initDb() { try { const dbName = DB_PREFIX + this.name; console.log((await this.con.isConnection(dbName, this.config.readonly ?? false)).result); if ((await this.con.isConnection(dbName, this.config.readonly ?? false)).result) { this.db = await this.con.retrieveConnection(dbName, this.config.readonly ?? false); } else { this.db = await this.con.createConnection(dbName, this.config.encrypted ?? false, this.config.mode ?? "", this.config.version ?? 1, this.config.readonly ?? false); } await this.db.open(); await this.db.execute("CREATE TABLE IF NOT EXISTS updates (id INTEGER PRIMARY KEY, content BLOB)"); const s = Y.encodeStateAsUpdate(this.doc); if (s.length > 0) { this._storeUpdate(s, null); } const { values } = await this.db.query("SELECT content FROM updates"); if (values != void 0) { for (const row of values) { Y.applyUpdate(this.doc, new Uint8Array(row.content)); } } this.synced = true; this.emit("synced", [this]); console.log("initialisation finished"); } catch (e) { console.log("error loading update", e); throw e; } } static async create(config, doc, name, sqlite) { const c = new _CapSQLitePersistence(config, doc, name, sqlite); await c.initDb(); return c; } _storeUpdate(update, origin) { if (!this.db || origin == this) { !this.db && console.error("trying to store update without db"); return; } return this.db.run(`INSERT INTO updates (content) VALUES (?)`, [Buffer.from(update)]).catch((e) => console.error("error storing update", e)); } destroy() { this.doc.off("update", this._storeUpdate); this.doc.off("destroy", this.destroy); this._destroyed = true; return this.db?.close().catch((e) => { console.log("can't close", e); }); } }; export { CapSQLitePersistence };