UNPKG

@ocap/statedb-fs

Version:
108 lines (106 loc) 3.39 kB
import { name } from "../package.mjs"; import { StateDBTable } from "@ocap/statedb"; import path from "node:path"; import omit from "lodash/omit.js"; import Lokijs from "lokijs"; import FsAdapter from "lokijs/src/loki-fs-structured-adapter.js"; import Debug from "debug"; //#region src/table/base.ts const debug = Debug(name); /** * 文件系统表基类 * 使用 LokiJS + FSAdapter 作为底层存储 */ var FsTable = class FsTable extends StateDBTable { constructor({ name: name$1, dataDir, uniqIndex, balanceTable, syncBalance = false }) { super(uniqIndex); this.name = name$1; this.dataDir = dataDir; this.collection = null; this.balanceTable = balanceTable; this.syncBalance = syncBalance; if (this.syncBalance && !this.balanceTable) throw new Error("balanceTable is required when syncBalance is true"); const adapter = new FsAdapter(); const db = new Lokijs(path.join(dataDir, `${name$1}.db`), { adapter, autoload: true, autosave: true, autosaveInterval: 1e3, autoloadCallback: () => { this.collection = db.getCollection(name$1); if (this.collection === null) this.collection = db.addCollection(name$1, { unique: [this.primaryKey], clone: true }); this.markReady(); } }); } async _create(key, attrs = {}, _context) { const id = this.generatePrimaryKey(key); if (await FsTable.prototype._get.call(this, id)) throw new Error(`${this.name} already exists: ${key}`); debug(`insert ${this.name}`, attrs); const insertAttrs = { ...attrs }; if (this.syncBalance) delete insertAttrs.tokens; const result = await this.collection.insert({ [this.primaryKey]: id, ...insertAttrs }); if (this.syncBalance && attrs.tokens) { debug(`update balance for ${this.name}`, attrs); result.tokens = await this.balanceTable.updateBalance({ address: attrs.address, tokens: attrs.tokens, context: attrs.context }); } return result; } async _get(key, _context) { if (!key) return null; const id = this.generatePrimaryKey(key); const result = await this.collection.by(this.primaryKey, id); if (result && this.syncBalance) { const balance = await this.balanceTable.getBalance(result.address); result.tokens = { ...result.tokens || {}, ...balance }; } return result; } _history(_key, _context) { return []; } async _update(key, updates, _context) { const id = this.generatePrimaryKey(key); const doc = await FsTable.prototype._get.call(this, id); if (!doc) throw new Error(`${this.name} does not exists: ${key}`); Object.assign(doc, updates); const updateAttrs = { ...doc }; if (this.syncBalance) delete updateAttrs.tokens; await this.collection.update(updateAttrs); if (this.syncBalance && doc.tokens) { debug(`update balance for ${this.name}`, doc); doc.tokens = await this.balanceTable.updateBalance({ address: doc.address, tokens: doc.tokens, context: doc.context }); } return doc; } updateOrCreate(exist, state, ctx) { const id = this.generatePrimaryKey(state); const attrs = omit(state, this.primaryKey); if (!id) throw new Error("Cannot update or create without uniq index"); if (exist) return this.update(id, attrs, ctx); return this.create(id, attrs, ctx); } _reset(_context) { this.collection.removeWhere({}); } }; var base_default = FsTable; //#endregion export { base_default as default };