Refactor the database logic for the apps into it's own mixin for reuse

This commit is contained in:
Oliver 2026-01-17 23:14:05 -07:00
parent ffa2162fbd
commit 63f985aa0e
4 changed files with 125 additions and 75 deletions

View file

@ -0,0 +1,89 @@
import { getFile, lastModifiedAt } from "../../utils/fs.mjs";
import { __ID__ } from "../../consts.mjs";
export function DBConnectorMixin(HandlebarsApp) {
class DBConnectorApp extends HandlebarsApp {
// #region Instance Data
#lastModified = null;
#connected = false;
_docID;
_doc;
static dbType = `Unknown`;
static dbPath;
constructor({ docID, ...opts } = {}) {
super(opts);
if (this.constructor.dbPath == null) {
throw `dbPath must be defined on a DB-connected app`;
};
this._docID = docID;
};
get dbPath() {
return this.constructor.dbPath;
};
get dbType() {
return this.constructor.dbType;
};
// #endregion Instance Data
// #region Lifecycle
/**
* Ensures that the app is in a state where it is allowed to render
* before actually letting it render at all.
*/
async render(options, ...args) {
const allowed = await this.#connectToDB();
if (!allowed) { return this };
return super.render(options, ...args);
};
/**
* This fetches the DB data that we care about for the purposes of being able
* to create/edit entries in the Artists DB
*/
async #connectToDB() {
if (this.#connected) { return true };
this.#lastModified ??= await lastModifiedAt(this.dbPath);
if (this._docID) {
const documents = await getFile(this.dbPath);
if (documents[this._docID] == null) {
ui.notifications.error(_loc(
`TB.notifs.error.document-ID-404`,
{ id: this._docID, dbType: this.dbType },
));
return false;
};
Object.assign(this._doc, documents[this._docID]);
};
this.#connected = true;
return true;
};
async isAbleToSave() {
if (!this._docID) { return true };
const newLastModified = await lastModifiedAt(this.dbPath);
if (newLastModified !== this.#lastModified) {
ui.notifications.error(
`TB.notifs.error.db-out-of-date`,
{ localize: true },
);
return false;
};
return true;
};
// #endregion Lifecycle
};
return DBConnectorApp;
};