diff --git a/lib/core/Registry.js b/lib/core/Registry.js new file mode 100644 index 0000000..e3f3c84 --- /dev/null +++ b/lib/core/Registry.js @@ -0,0 +1,67 @@ +import Logger from './Logger'; +export default class Registry { + static #registry = new Map(); + + constructor() { + throw new Error( + 'Registry is a static class and cannot be instantiated.' + ); + } + + static getParent(uid) { + const parent = this.#registry.get(uid)?.parent ?? undefined; + if (!parent) return undefined; + + return this.#registry.get(parent)?.obj ?? undefined; + } + + static register(data) { + const { key, parent, obj, type } = data; + if (!key || !obj || !parent) + throw new Error('missing required parameters (key, obj, parent)'); + if (typeof key !== 'string') + throw new TypeError('key must be a string'); + + const uid = this.#uid(); + this.#registry.set(uid, { key, parent, obj, type }); + return uid; + } + + static update(uid, data) { + if (!this.#registry.has(uid)) throw new Error('uid not found'); + + this.#registry.set(uid, { ...this.#registry.get(uid), ...data }); + } + + static get(uid) { + return this.#registry.get(uid)?.obj ?? undefined; + } + + static unregister(identifier, key) { + if (this.#registry.get(identifier)?.key !== key) { + Logger.warn('only the owner can unregister'); + return false; + } + return this.#registry.delete(identifier); + } + + /** + * Generates a unique identifier. + * + * @param {number} [numGroups=1] - The number of groups in the identifier. + * @param {number} [groupLength=6] - The length of each group in the identifier. + * @returns {string} The unique identifier. + */ + static #uid(numGroups = 1, groupLength = 6) { + let uid = undefined; + while (!uid || Registry.#registry.has(uid)) { + uid = Array.from(Array(numGroups), () => + Math.random() + .toString(36) + .substring(2, groupLength + 2) + ).join(''); + } + + return uid; + } +}