UNPKG

@studiometa/js-toolkit

Version:

A set of useful little bits of JavaScript to boost your project! 🚀

115 lines (114 loc) • 2.58 kB
import { cache } from "../utils/cache.js"; class AbstractService { /** * Service configuration. */ static config = []; /** * Cache for the created instances. */ static __instances = /* @__PURE__ */ new Map(); /** * Get a service instance as a singleton based on the given key. */ static getInstance(keys = [this], ...args) { return cache(keys, () => { const instance = new this(...args); return { add: (key, callback) => instance.add(key, callback), remove: (key) => instance.remove(key), has: (key) => instance.has(key), props: () => instance.props }; }); } /** * Is the service active or not? */ __isInit = false; /** * Props for the service. */ props = {}; /** * Holds all the callbacks that will be triggered. */ callbacks = /* @__PURE__ */ new Map(); /** * Does the service has the given key? */ has(key) { return this.callbacks.has(key); } /** * Get a service callback by its key. */ get(key) { return this.callbacks.get(key); } /** * Add a callback to the service. */ add(key, callback) { if (this.has(key)) { console.warn(`The key \`${String(key)}\` has already been added.`); return; } if (this.callbacks.size === 0 && !this.__isInit) { this.init(); this.__isInit = true; } this.callbacks.set(key, callback); } /** * Remove a callback from the service by its key. */ remove(key) { this.callbacks.delete(key); if (this.callbacks.size === 0 && this.__isInit) { this.kill(); this.__isInit = false; } } /** * Trigger all service callbacks with service props. */ trigger(props) { for (const callback of this.callbacks.values()) { callback(props); } } /* v8 ignore next 6 */ /** * Implements the EventListenerObject interface. */ handleEvent(event) { } /** * Add or remove event listeners based on the static `config` property. */ __manageEvents(mode) { for (const [target, events] of this.constructor.config) { const resolvedTarget = target(this); for (const [type, options] of events) { resolvedTarget[`${mode}EventListener`](type, this, options); } } } /** * Triggered when the service is initialized. */ init() { this.__manageEvents("add"); } /** * Triggered when the service is killed. */ kill() { this.__manageEvents("remove"); } } export { AbstractService }; //# sourceMappingURL=AbstractService.js.map