Make all of the DB methods async, and update the dependencies in order to make them work with the async DBs

This commit is contained in:
Oliver-Akins 2025-05-11 22:47:23 -06:00
parent 8a2d946b63
commit 606d6e14ea
11 changed files with 179 additions and 165 deletions

View file

@ -1,4 +1,5 @@
/* eslint-disable no-unused-vars */
import { validateBucketConfig } from "../buckets.mjs";
/*
NOTE:
@ -24,9 +25,11 @@ Default Subtables:
tables that are parents to other tables.
*/
const { deleteProperty, diffObject, expandObject, mergeObject } = foundry.utils;
export class Database {
// MARK: Table Ops
static createTable(tableConfig) {
static async createTable(tableConfig) {
if (!game.user.isGM) {
ui.notifications.error(`You do not have the required permission to create a new table`);
return false;
@ -52,23 +55,61 @@ export class Database {
tables[name] = tableConfig;
game.settings.set(__ID__, `tables`, tables);
this.render();
this.render({ tags: [`table`] });
return true;
};
/** @returns {Array<Table>} */
static getTables() {
static async getTables() {
const tables = game.settings.get(__ID__, `tables`);
return Object.values(tables) ?? [];
};
static getTable(tableID) {
static async getTable(tableID) {
const tables = game.settings.get(__ID__, `tables`);
if (!tables[tableID]) { return };
return tables[tableID];
};
static deleteTable(tableID) {
static async updateTable(tableID, changes) {
const table = this.getTable(tableID);
if (!tables[tableID]) {
ui.notifications.error(`Cannot update table that doesn't exist`);
return false;
};
// Bucket coercion in case called via the API
deleteProperty(changes, `name`);
deleteProperty(changes, `buckets.type`);
const diff = diffObject(
table,
expandObject(changes),
{ inner: true, deletionKeys: true },
);
if (Object.keys(diff).length === 0) { return false };
const updated = mergeObject(
table,
diff,
{ inplace: false, performDeletions: true },
);
try {
updated.buckets = validateBucketConfig(updated.buckets);
} catch (e) {
ui.notifications.error(e);
return false;
};
const tables = game.settings.get(__ID__, `tables`);
tables[tableID] = updated;
game.settings.set(__ID__, `tables`, tables);
this.render({ tags: [`table`] });
return true;
};
static async deleteTable(tableID) {
if (!game.user.isGM) {
ui.notifications.error(`You do not have the required permission to delete a table`);
return false;
@ -86,23 +127,23 @@ export class Database {
};
// MARK: Row Ops
static createRow(table, userID, row, opts) {
static async createRow(table, userID, row, opts) {
throw new Error(`createRow() must be implemented`);
};
static createRows(table, userID, rows, opts) {
static async createRows(table, userID, rows, opts) {
throw new Error(`createRows() must be implemented`);
};
static getRows(tableID, userIDs, privacy = `none`) {
static async getRows(tableID, userIDs, privacy = `none`) {
throw new Error(`getRows() must be implemented`);
};
static updateRow(table, userID, rowID, changes) {
static async updateRow(table, userID, rowID, changes) {
throw new Error(`updateRow() must be implemented`);
};
static deleteRow(table, userID, rowID) {
static async deleteRow(table, userID, rowID) {
throw new Error(`deleteRow() must be implemented`);
};
@ -137,7 +178,7 @@ export class Database {
* Rerenders all of the applications that are displaying data from
* this database
*/
static render(opts) {
static async render(opts) {
for (const app of this._apps.values()) {
app.render(opts);
};
@ -148,9 +189,9 @@ export class Database {
* Used to listen for changes from other clients and rerender the apps
* as required in order to keep the data as up-to-date as possible.
*/
static registerListeners() {};
static async registerListeners() {};
static unregisterListeners() {};
static async unregisterListeners() {};
};
/* eslint-enable no-unused-vars */

View file

@ -1,3 +1,4 @@
import { createDiceTable } from "./utils.mjs";
import { Database } from "./Database.mjs";
import { filterPrivateRows } from "../privacy.mjs";
import { Logger } from "../Logger.mjs";
@ -7,48 +8,9 @@ const { deleteProperty, diffObject, expandObject, mergeObject, randomID } = foun
export class MemoryDatabase extends Database {
static #tables = {
"Dice/d10": {
name: `Dice/d10`,
buckets: {
type: `range`,
locked: true,
min: 1,
max: 10,
step: 1,
},
graph: {
type: `bar`,
stacked: true,
},
},
"Dice/d20": {
name: `Dice/d20`,
buckets: {
type: `range`,
locked: true,
min: 1,
max: 20,
step: 1,
},
graph: {
type: `bar`,
stacked: true,
},
},
"Dice/d100": {
name: `Dice/d100`,
buckets: {
type: `range`,
locked: true,
min: 1,
max: 100,
step: 1,
},
graph: {
type: `bar`,
stacked: true,
},
},
"Dice/d10": createDiceTable(10),
"Dice/d20": createDiceTable(20),
"Dice/d100": createDiceTable(100),
"Successes Number": {
name: `Successes Number`,
buckets: {
@ -88,13 +50,13 @@ export class MemoryDatabase extends Database {
static #rows = {};
static createTable(tableConfig) {
static async createTable(tableConfig) {
this.#tables[tableConfig.name] = tableConfig;
this.render();
return true;
};
static getTableNames() {
static async getTableNames() {
const tables = new Set();
for (const tableID of Object.keys(this.#tables)) {
const [ targetTable ] = tableID.split(`/`, 2);
@ -103,7 +65,7 @@ export class MemoryDatabase extends Database {
return Array.from(tables);
};
static getSubtableNames(table) {
static async getSubtableNames(table) {
const subtables = new Set();
for (const tableID of Object.keys(this.#tables)) {
const [ targetTable, targetSubtable ] = tableID.split(`/`, 2);
@ -115,16 +77,15 @@ export class MemoryDatabase extends Database {
};
/** @returns {Array<Table>} */
static getTables() {
static async getTables() {
return Object.values(this.#tables);
};
static getTable(tableID) {
static async getTable(tableID) {
return this.#tables[tableID];
};
static async updateTable(tableID, changes) {
Logger.debug({tableID, changes});
const table = this.getTable(tableID);
if (!table) { return false };
@ -156,7 +117,7 @@ export class MemoryDatabase extends Database {
return true;
};
static createRow(table, userID, row, { rerender = true } = {}) {
static async createRow(table, userID, row, { rerender = true } = {}) {
if (!this.#tables[table]) { return };
this.#rows[userID] ??= {};
this.#rows[userID][table] ??= [];
@ -172,7 +133,7 @@ export class MemoryDatabase extends Database {
};
};
static createRows(table, userID, rows, { rerender = true } = {}) {
static async createRows(table, userID, rows, { rerender = true } = {}) {
if (!this.#tables[table]) { return };
this.#rows[userID] ??= {};
this.#rows[userID][table] ??= [];
@ -187,7 +148,7 @@ export class MemoryDatabase extends Database {
};
};
static getRows(tableID, userIDs, privacy = `none`) {
static async getRows(tableID, userIDs, privacy = `none`) {
if (userIDs.length === 0) {
return {};
};
@ -207,7 +168,7 @@ export class MemoryDatabase extends Database {
return datasets;
};
static updateRow(table, userID, rowID, changes) {
static async updateRow(table, userID, rowID, changes) {
if (!this.#tables[table] || !this.#rows[userID]?.[table]) { return };
let row = this.#rows[userID][table].find(row => row._id === rowID);
if (!row) { return };
@ -215,7 +176,7 @@ export class MemoryDatabase extends Database {
this.render({ userUpdated: userID });
};
static deleteRow(table, userID, rowID) {
static async deleteRow(table, userID, rowID) {
if (!this.#tables[table] || !this.#rows[userID]?.[table]) { return };
let rowIndex = this.#rows[userID][table].findIndex(row => row._id === rowID);
if (rowIndex === -1) { return };
@ -227,7 +188,7 @@ export class MemoryDatabase extends Database {
* Used to listen for changes from other clients and refresh the local DB as
* required, so that the StatsTracker stays up to date.
*/
static registerListeners() {};
static async registerListeners() {};
static unregisterListeners() {};
static async unregisterListeners() {};
};