import { matcher } from "../tag_utils.js";
/**
* Base Model for all entities.
*/
class Model {
/**
* @param {Object} params
* @param [params.tags] {String[]} an array of tags to add to this model instance.
*/
constructor({ tags = [] } = {}) {
/**
* An array of string tags that characterize this item.
* @property {Set} tags
*/
this.tags = new Set(tags);
}
/**
* Given a prefix like `ammo` or `media`, will return the specific tag for this
* item, such as `ammo:22` or `media:35mm`.
*
* @param prefix {String} the prefix to match
* @return {String} the first tag found that matches this prefix
*/
typeOf(prefix) {
if (typeof prefix !== "string") {
throw Error("typeOf argument must be a string");
}
let p = prefix + ":";
let r = Array.from(this.tags).find((tag) => tag.startsWith(p));
return r ? r : null;
}
/**
* Does this model have the given tag?
* @param {String} tag
* @returns {boolean} true if it does, false otherwise
*/
is(tag) {
return matcher(tag, this.tags);
}
/**
* Does this model have the given tag?
* @param {String} tag
* @returns {boolean} true if it does, false otherwise
*/
has(tag) {
return matcher(tag, this.tags);
}
/**
* Does this model not have the given tag?
* @param {String} tag
* @returns {boolean} true if it does not have the tag, false otherwise
*/
not(tag) {
return !matcher(tag, this.tags);
}
/**
* Converts the model to JSON, converting sets to arrays.
*
* @returns {String} JSON
*/
asJSON() {
return JSON.stringify(this, (_key, value) =>
value instanceof Set ? [...value].sort() : value
);
}
equals(model) {
if (!model || !model.asJSON) {
return false;
}
console.log(this.asJSON(), model.asJSON());
return this.asJSON() === model.asJSON();
}
}
export default Model;