@studiometa/js-toolkit 3.0.0-alpha.6 → 3.0.0-alpha.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/Base/Base.js CHANGED
@@ -341,7 +341,16 @@ class Base extends EventTarget {
341
341
  }
342
342
  set.add(listener);
343
343
  const target = getEventTarget(this, event, this.__config);
344
- target.addEventListener(event, listener, options);
344
+ target?.addEventListener(event, listener, options);
345
+ if (isDev) {
346
+ if (!target) {
347
+ console.warn(
348
+ `[${this.$id}]`,
349
+ `The "${event}" event is missing from the configuration and is not a native`,
350
+ `event for the root element of type \`${this.$el.constructor.name}\`.`
351
+ );
352
+ }
353
+ }
345
354
  return () => {
346
355
  this.$off(event, listener, options);
347
356
  };
@@ -363,7 +372,7 @@ class Base extends EventTarget {
363
372
  }
364
373
  this.__eventHandlers.get(event).delete(listener);
365
374
  const target = getEventTarget(this, event, this.__config);
366
- target.removeEventListener(event, listener, options);
375
+ target?.removeEventListener(event, listener, options);
367
376
  }
368
377
  /**
369
378
  * Emits an event.
package/Base/Base.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../packages/js-toolkit/Base/Base.ts"],
4
- "sourcesContent": ["/* eslint-disable no-use-before-define */\nimport {\n getComponentElements,\n getEventTarget,\n addToQueue,\n addInstance,\n deleteInstance,\n} from './utils.js';\nimport {\n ChildrenManager,\n RefsManager,\n ServicesManager,\n EventsManager,\n OptionsManager,\n} from './managers/index.js';\nimport { noop, isDev, isFunction, isArray } from '../utils/index.js';\n\nlet id = 0;\n\nexport type BaseEl = HTMLElement & { __base__?: WeakMap<BaseConstructor, Base | 'terminated'> };\nexport type BaseConstructor<T extends Base = Base> = {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n new (...args: any[]): T;\n prototype: Base;\n} & Pick<typeof Base, keyof typeof Base>;\nexport type BaseAsyncConstructor<T extends Base = Base> = (\n instance: Base,\n) => Promise<BaseConstructor<T> | { default: BaseConstructor<T> }>;\nexport type BaseOptions = { [name: string]: unknown };\nexport type BaseRefs = { [name: string]: HTMLElement | HTMLElement[] };\nexport type BaseChildren = { [nameOrSelector: string]: Base[] | Promise<Base>[] };\nexport type BaseConfigComponents = {\n [nameOrSelector: string]: BaseConstructor | BaseAsyncConstructor;\n};\n\nexport type BaseConfig = {\n name: string;\n debug?: boolean;\n log?: boolean;\n refs?: string[];\n emits?: string[];\n components?: BaseConfigComponents;\n options?: import('./managers/OptionsManager').OptionsSchema;\n};\n\nexport type BaseProps = {\n $el?: HTMLElement;\n $options?: BaseOptions;\n $refs?: BaseRefs;\n $children?: BaseChildren;\n $parent?: Base;\n};\n\nexport type Managers = {\n ChildrenManager: typeof ChildrenManager;\n EventsManager: typeof EventsManager;\n OptionsManager: typeof OptionsManager;\n RefsManager: typeof RefsManager;\n ServicesManager: typeof ServicesManager;\n};\n\n/**\n * Base class.\n */\nexport class Base<T extends BaseProps = BaseProps> extends EventTarget {\n /**\n * This is a Base instance.\n */\n static readonly $isBase = true as const;\n\n /**\n * The instance parent.\n */\n $parent: T['$parent'] & Base = null;\n\n /**\n * The instance id.\n */\n $id: string;\n\n /**\n * The root element.\n */\n $el: T['$el'] & BaseEl;\n\n /**\n * The state of the component.\n */\n $isMounted = false;\n\n /**\n * Store the event handlers.\n */\n __eventHandlers: Map<string, Set<EventListenerOrEventListenerObject>> = new Map();\n\n /**\n * Get the root instance of the app.\n */\n get $root(): Base {\n if (!this.$parent) {\n return this;\n }\n\n let parent = this.$parent;\n let root = this.$parent;\n\n while (parent) {\n if (!parent.$parent) {\n root = parent;\n }\n\n parent = parent.$parent;\n }\n\n return root;\n }\n\n /**\n * Merge configuration with the parents' configurations.\n */\n get __config(): BaseConfig {\n let proto = Object.getPrototypeOf(this);\n let { config } = proto.constructor;\n\n while (proto.constructor.config && proto.constructor.$isBase) {\n config = { ...proto.constructor.config, ...config };\n\n if (proto.constructor.config.options) {\n config.options = { ...proto.constructor.config.options, ...config.options };\n }\n\n if (proto.constructor.config.emits && config.emits) {\n config.emits = [...proto.constructor.config.emits, ...config.emits];\n }\n\n proto = Object.getPrototypeOf(proto);\n }\n\n config.options = config.options ?? {};\n config.refs = config.refs ?? [];\n config.components = config.components ?? {};\n\n return config;\n }\n\n static config: BaseConfig = {\n name: 'Base',\n emits: [\n // hook events\n 'before-mounted',\n 'mounted',\n 'updated',\n 'destroyed',\n 'terminated',\n // default services' events\n 'ticked',\n 'scrolled',\n 'resized',\n 'moved',\n 'loaded',\n 'keyed',\n ],\n };\n\n __services: ServicesManager;\n\n get $services(): ServicesManager {\n return this.__services;\n }\n\n __refs: RefsManager & T['$refs'] & BaseRefs;\n\n get $refs(): RefsManager & T['$refs'] & BaseRefs {\n return this.__refs;\n }\n\n __options: OptionsManager & T['$options'] & BaseOptions;\n\n get $options(): OptionsManager & T['$options'] & BaseOptions {\n return this.__options;\n }\n\n __children: ChildrenManager & T['$children'] & BaseChildren;\n\n get $children(): ChildrenManager & T['$children'] & BaseChildren {\n return this.__children;\n }\n\n __events: EventsManager;\n\n /**\n * Small helper to log stuff.\n */\n get $log(): (...args: unknown[]) => void {\n return this.__options.log ? window.console.log.bind(window, `[${this.__config.name}]`) : noop;\n }\n\n /**\n * Small helper to make warning easier.\n */\n get $warn(): (...args: unknown[]) => void {\n return this.__options.log ? window.console.warn.bind(window, `[${this.__config.name}]`) : noop;\n }\n\n /**\n * Small helper to debug information.\n */\n get __debug(): (...args: unknown[]) => void {\n return isDev && this.__options.debug\n ? window.console.log.bind(window, `[debug] [${this.$id}]`)\n : noop;\n }\n\n /**\n * Get manager constructors.\n */\n get __managers(): Managers {\n return {\n ChildrenManager,\n EventsManager,\n OptionsManager,\n RefsManager,\n ServicesManager,\n };\n }\n\n /**\n * Call an instance method and emit corresponding events.\n */\n __callMethod(method: string, ...args: unknown[]): unknown {\n if (isDev) {\n this.__debug('callMethod', method, ...args);\n }\n\n this.$emit(method, ...args);\n\n // We always emit an event, but we do not call the method if it does not exist\n if (!isFunction(this[method])) {\n return null;\n }\n\n if (isDev) {\n this.__debug(method, this, ...args);\n }\n\n return this[method].call(this, ...args);\n }\n\n /**\n * Test if the given event has been bound to the instance.\n *\n * @param {string} event The event's name.\n * @returns {boolean} Wether the given event has been bound or not.\n */\n __hasEvent(event: string): boolean {\n const eventHandlers = this.__eventHandlers.get(event);\n return eventHandlers && eventHandlers.size > 0;\n }\n\n /**\n * Class constructor where all the magic takes place.\n *\n * @param {HTMLElement} element The component's root element dd.\n */\n constructor(element: HTMLElement) {\n super();\n\n if (!element) {\n if (isDev) {\n throw new Error('The root element must be defined.');\n }\n return;\n }\n\n const { __config } = this;\n\n if (__config.name === 'Base') {\n if (isDev) {\n throw new Error('The `config.name` property is required.');\n }\n return;\n }\n\n this.$id = `${__config.name}-${id}`;\n id += 1;\n\n this.$el = element;\n\n if (!this.$el.__base__) {\n this.$el.__base__ = new WeakMap();\n }\n\n this.$el.__base__.set(this.__ctor, this);\n\n for (const service of ['Options', 'Services', 'Events', 'Refs', 'Children']) {\n this[`__${service.toLowerCase()}`] = new this.__managers[`${service}Manager`](this);\n }\n\n this.$on('mounted', () => {\n addInstance(this);\n });\n this.$on('destroyed', () => {\n deleteInstance(this);\n });\n\n if (isDev) {\n this.__debug('constructor', this);\n }\n }\n\n /**\n * Trigger the `mounted` callback.\n */\n async $mount(): Promise<this> {\n if (this.$isMounted) {\n return this;\n }\n\n this.$emit('before-mounted');\n\n if (isDev) {\n this.__debug('$mount');\n }\n\n await Promise.all([\n addToQueue(() => this.$children.registerAll()),\n addToQueue(() => this.$refs.registerAll()),\n addToQueue(() => this.__events.bindRootElement()),\n addToQueue(() => this.$services.enableAll()),\n addToQueue(() => this.$children.mountAll()),\n addToQueue(() => (this.$isMounted = true)),\n addToQueue(() => this.__callMethod('mounted')),\n ]);\n\n return this;\n }\n\n /**\n * Update the instance children.\n */\n async $update(): Promise<this> {\n if (isDev) {\n this.__debug('$update');\n }\n\n await Promise.all([\n // Undo\n addToQueue(() => this.$refs.unregisterAll()),\n addToQueue(() => this.$services.disableAll()),\n // Redo\n addToQueue(() => this.$children.registerAll()),\n addToQueue(() => this.$refs.registerAll()),\n addToQueue(() => this.$services.enableAll()),\n // Update\n addToQueue(() => this.$children.updateAll()),\n addToQueue(() => this.__callMethod('updated')),\n ]);\n\n return this;\n }\n\n /**\n * Trigger the `destroyed` callback.\n */\n async $destroy(): Promise<this> {\n if (!this.$isMounted) {\n return this;\n }\n\n if (isDev) {\n this.__debug('$destroy');\n }\n\n await Promise.all([\n addToQueue(() => (this.$isMounted = false)),\n addToQueue(() => this.__events.unbindRootElement()),\n addToQueue(() => this.$refs.unregisterAll()),\n addToQueue(() => this.$services.disableAll()),\n addToQueue(() => this.$children.destroyAll()),\n addToQueue(() => this.__callMethod('destroyed')),\n ]);\n\n return this;\n }\n\n /**\n * Terminate a child instance when it is not needed anymore.\n */\n async $terminate(): Promise<void> {\n if (isDev) {\n this.__debug('$terminate');\n }\n\n await Promise.all([\n // First, destroy the component.\n addToQueue(() => this.$destroy()),\n // Execute the `terminated` hook if it exists\n addToQueue(() => this.__callMethod('terminated')),\n // Delete instance\n addToQueue(() => this.$el.__base__.set(this.__ctor, 'terminated')),\n ]);\n }\n\n /**\n * Add an emitted event.\n *\n * @param {string} event The event name.\n * @returns {void}\n */\n __addEmits(event: string): void {\n const ctor = this.__ctor;\n if (isArray(ctor.config.emits)) {\n ctor.config.emits.push(event);\n } else {\n ctor.config.emits = [event];\n }\n }\n\n /**\n * Remove an emitted event.\n *\n * @param {string} event The event name.\n * @returns {void}\n */\n __removeEmits(event: string): void {\n const ctor = this.__ctor;\n const index = ctor.config.emits.indexOf(event);\n ctor.config.emits.splice(index, 1);\n }\n\n /**\n * Get the instance constructor.\n */\n get __ctor(): BaseConstructor {\n return this.constructor as BaseConstructor;\n }\n\n /**\n * Bind a listener function to an event.\n *\n * @param {string} event\n * Name of the event.\n * @param {EventListenerOrEventListenerObject} listener\n * Function to be called.\n * @param {boolean|AddEventListenerOptions} [options]\n * Options for the `removeEventListener` method.\n * @returns {() => void}\n * A function to unbind the listener.\n */\n $on(\n event: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ): () => void {\n if (isDev) {\n this.__debug('$on', event, listener, options);\n }\n\n let set = this.__eventHandlers.get(event);\n\n if (!set) {\n set = new Set();\n this.__eventHandlers.set(event, set);\n }\n\n set.add(listener);\n\n const target = getEventTarget(this, event, this.__config);\n target.addEventListener(event, listener, options);\n\n return () => {\n this.$off(event, listener, options);\n };\n }\n\n /**\n * Unbind a listener function from an event.\n *\n * @param {string} event\n * Name of the event.\n * @param {EventListenerOrEventListenerObject} listener\n * Function to be removed.\n * @param {boolean|EventListenerOptions} [options]\n * Options for the `removeEventListener` method.\n * @returns {void}\n */\n $off(\n event: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | EventListenerOptions,\n ) {\n if (isDev) {\n this.__debug('$off', event, listener);\n }\n\n this.__eventHandlers.get(event).delete(listener);\n\n const target = getEventTarget(this, event, this.__config);\n target.removeEventListener(event, listener, options);\n }\n\n /**\n * Emits an event.\n *\n * @param {string} event Name of the event.\n * @param {any[]} args The arguments to apply to the functions bound to this event.\n * @returns {void}\n */\n $emit(event: string, ...args: unknown[]) {\n if (isDev) {\n this.__debug('$emit', event, args);\n }\n\n this.dispatchEvent(new CustomEvent(event, { detail: args }));\n }\n\n /**\n * Register and mount all instances of the component.\n */\n static $register(nameOrSelector?: string): Array<Promise<Base>> {\n return getComponentElements(nameOrSelector ?? this.config.name).map((el) =>\n new this(el).$mount(),\n );\n }\n}\n"],
5
- "mappings": "AACA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,MAAM,OAAO,YAAY,eAAe;AAEjD,IAAI,KAAK;AA+CF,MAAM,aAA8C,YAAY;AAAA;AAAA;AAAA;AAAA,EAIrE,OAAgB,UAAU;AAAA;AAAA;AAAA;AAAA,EAK1B,UAA+B;AAAA;AAAA;AAAA;AAAA,EAK/B;AAAA;AAAA;AAAA;AAAA,EAKA;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa;AAAA;AAAA;AAAA;AAAA,EAKb,kBAAwE,oBAAI,IAAI;AAAA;AAAA;AAAA;AAAA,EAKhF,IAAI,QAAc;AAChB,QAAI,CAAC,KAAK,SAAS;AACjB,aAAO;AAAA,IACT;AAEA,QAAI,SAAS,KAAK;AAClB,QAAI,OAAO,KAAK;AAEhB,WAAO,QAAQ;AACb,UAAI,CAAC,OAAO,SAAS;AACnB,eAAO;AAAA,MACT;AAEA,eAAS,OAAO;AAAA,IAClB;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,WAAuB;AACzB,QAAI,QAAQ,OAAO,eAAe,IAAI;AACtC,QAAI,EAAE,OAAO,IAAI,MAAM;AAEvB,WAAO,MAAM,YAAY,UAAU,MAAM,YAAY,SAAS;AAC5D,eAAS,EAAE,GAAG,MAAM,YAAY,QAAQ,GAAG,OAAO;AAElD,UAAI,MAAM,YAAY,OAAO,SAAS;AACpC,eAAO,UAAU,EAAE,GAAG,MAAM,YAAY,OAAO,SAAS,GAAG,OAAO,QAAQ;AAAA,MAC5E;AAEA,UAAI,MAAM,YAAY,OAAO,SAAS,OAAO,OAAO;AAClD,eAAO,QAAQ,CAAC,GAAG,MAAM,YAAY,OAAO,OAAO,GAAG,OAAO,KAAK;AAAA,MACpE;AAEA,cAAQ,OAAO,eAAe,KAAK;AAAA,IACrC;AAEA,WAAO,UAAU,OAAO,WAAW,CAAC;AACpC,WAAO,OAAO,OAAO,QAAQ,CAAC;AAC9B,WAAO,aAAa,OAAO,cAAc,CAAC;AAE1C,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,SAAqB;AAAA,IAC1B,MAAM;AAAA,IACN,OAAO;AAAA;AAAA,MAEL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA;AAAA,MAEA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA;AAAA,EAEA,IAAI,YAA6B;AAC/B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA;AAAA,EAEA,IAAI,QAA6C;AAC/C,WAAO,KAAK;AAAA,EACd;AAAA,EAEA;AAAA,EAEA,IAAI,WAAyD;AAC3D,WAAO,KAAK;AAAA,EACd;AAAA,EAEA;AAAA,EAEA,IAAI,YAA6D;AAC/D,WAAO,KAAK;AAAA,EACd;AAAA,EAEA;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,OAAqC;AACvC,WAAO,KAAK,UAAU,MAAM,OAAO,QAAQ,IAAI,KAAK,QAAQ,IAAI,KAAK,SAAS,IAAI,GAAG,IAAI;AAAA,EAC3F;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,QAAsC;AACxC,WAAO,KAAK,UAAU,MAAM,OAAO,QAAQ,KAAK,KAAK,QAAQ,IAAI,KAAK,SAAS,IAAI,GAAG,IAAI;AAAA,EAC5F;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,UAAwC;AAC1C,WAAO,SAAS,KAAK,UAAU,QAC3B,OAAO,QAAQ,IAAI,KAAK,QAAQ,YAAY,KAAK,GAAG,GAAG,IACvD;AAAA,EACN;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,aAAuB;AACzB,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,WAAmB,MAA0B;AACxD,QAAI,OAAO;AACT,WAAK,QAAQ,cAAc,QAAQ,GAAG,IAAI;AAAA,IAC5C;AAEA,SAAK,MAAM,QAAQ,GAAG,IAAI;AAG1B,QAAI,CAAC,WAAW,KAAK,MAAM,CAAC,GAAG;AAC7B,aAAO;AAAA,IACT;AAEA,QAAI,OAAO;AACT,WAAK,QAAQ,QAAQ,MAAM,GAAG,IAAI;AAAA,IACpC;AAEA,WAAO,KAAK,MAAM,EAAE,KAAK,MAAM,GAAG,IAAI;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,WAAW,OAAwB;AACjC,UAAM,gBAAgB,KAAK,gBAAgB,IAAI,KAAK;AACpD,WAAO,iBAAiB,cAAc,OAAO;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,YAAY,SAAsB;AAChC,UAAM;AAEN,QAAI,CAAC,SAAS;AACZ,UAAI,OAAO;AACT,cAAM,IAAI,MAAM,mCAAmC;AAAA,MACrD;AACA;AAAA,IACF;AAEA,UAAM,EAAE,SAAS,IAAI;AAErB,QAAI,SAAS,SAAS,QAAQ;AAC5B,UAAI,OAAO;AACT,cAAM,IAAI,MAAM,yCAAyC;AAAA,MAC3D;AACA;AAAA,IACF;AAEA,SAAK,MAAM,GAAG,SAAS,IAAI,IAAI,EAAE;AACjC,UAAM;AAEN,SAAK,MAAM;AAEX,QAAI,CAAC,KAAK,IAAI,UAAU;AACtB,WAAK,IAAI,WAAW,oBAAI,QAAQ;AAAA,IAClC;AAEA,SAAK,IAAI,SAAS,IAAI,KAAK,QAAQ,IAAI;AAEvC,eAAW,WAAW,CAAC,WAAW,YAAY,UAAU,QAAQ,UAAU,GAAG;AAC3E,WAAK,KAAK,QAAQ,YAAY,CAAC,EAAE,IAAI,IAAI,KAAK,WAAW,GAAG,OAAO,SAAS,EAAE,IAAI;AAAA,IACpF;AAEA,SAAK,IAAI,WAAW,MAAM;AACxB,kBAAY,IAAI;AAAA,IAClB,CAAC;AACD,SAAK,IAAI,aAAa,MAAM;AAC1B,qBAAe,IAAI;AAAA,IACrB,CAAC;AAED,QAAI,OAAO;AACT,WAAK,QAAQ,eAAe,IAAI;AAAA,IAClC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAwB;AAC5B,QAAI,KAAK,YAAY;AACnB,aAAO;AAAA,IACT;AAEA,SAAK,MAAM,gBAAgB;AAE3B,QAAI,OAAO;AACT,WAAK,QAAQ,QAAQ;AAAA,IACvB;AAEA,UAAM,QAAQ,IAAI;AAAA,MAChB,WAAW,MAAM,KAAK,UAAU,YAAY,CAAC;AAAA,MAC7C,WAAW,MAAM,KAAK,MAAM,YAAY,CAAC;AAAA,MACzC,WAAW,MAAM,KAAK,SAAS,gBAAgB,CAAC;AAAA,MAChD,WAAW,MAAM,KAAK,UAAU,UAAU,CAAC;AAAA,MAC3C,WAAW,MAAM,KAAK,UAAU,SAAS,CAAC;AAAA,MAC1C,WAAW,MAAO,KAAK,aAAa,IAAK;AAAA,MACzC,WAAW,MAAM,KAAK,aAAa,SAAS,CAAC;AAAA,IAC/C,CAAC;AAED,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAyB;AAC7B,QAAI,OAAO;AACT,WAAK,QAAQ,SAAS;AAAA,IACxB;AAEA,UAAM,QAAQ,IAAI;AAAA;AAAA,MAEhB,WAAW,MAAM,KAAK,MAAM,cAAc,CAAC;AAAA,MAC3C,WAAW,MAAM,KAAK,UAAU,WAAW,CAAC;AAAA;AAAA,MAE5C,WAAW,MAAM,KAAK,UAAU,YAAY,CAAC;AAAA,MAC7C,WAAW,MAAM,KAAK,MAAM,YAAY,CAAC;AAAA,MACzC,WAAW,MAAM,KAAK,UAAU,UAAU,CAAC;AAAA;AAAA,MAE3C,WAAW,MAAM,KAAK,UAAU,UAAU,CAAC;AAAA,MAC3C,WAAW,MAAM,KAAK,aAAa,SAAS,CAAC;AAAA,IAC/C,CAAC;AAED,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,WAA0B;AAC9B,QAAI,CAAC,KAAK,YAAY;AACpB,aAAO;AAAA,IACT;AAEA,QAAI,OAAO;AACT,WAAK,QAAQ,UAAU;AAAA,IACzB;AAEA,UAAM,QAAQ,IAAI;AAAA,MAChB,WAAW,MAAO,KAAK,aAAa,KAAM;AAAA,MAC1C,WAAW,MAAM,KAAK,SAAS,kBAAkB,CAAC;AAAA,MAClD,WAAW,MAAM,KAAK,MAAM,cAAc,CAAC;AAAA,MAC3C,WAAW,MAAM,KAAK,UAAU,WAAW,CAAC;AAAA,MAC5C,WAAW,MAAM,KAAK,UAAU,WAAW,CAAC;AAAA,MAC5C,WAAW,MAAM,KAAK,aAAa,WAAW,CAAC;AAAA,IACjD,CAAC;AAED,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aAA4B;AAChC,QAAI,OAAO;AACT,WAAK,QAAQ,YAAY;AAAA,IAC3B;AAEA,UAAM,QAAQ,IAAI;AAAA;AAAA,MAEhB,WAAW,MAAM,KAAK,SAAS,CAAC;AAAA;AAAA,MAEhC,WAAW,MAAM,KAAK,aAAa,YAAY,CAAC;AAAA;AAAA,MAEhD,WAAW,MAAM,KAAK,IAAI,SAAS,IAAI,KAAK,QAAQ,YAAY,CAAC;AAAA,IACnE,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,WAAW,OAAqB;AAC9B,UAAM,OAAO,KAAK;AAClB,QAAI,QAAQ,KAAK,OAAO,KAAK,GAAG;AAC9B,WAAK,OAAO,MAAM,KAAK,KAAK;AAAA,IAC9B,OAAO;AACL,WAAK,OAAO,QAAQ,CAAC,KAAK;AAAA,IAC5B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,cAAc,OAAqB;AACjC,UAAM,OAAO,KAAK;AAClB,UAAM,QAAQ,KAAK,OAAO,MAAM,QAAQ,KAAK;AAC7C,SAAK,OAAO,MAAM,OAAO,OAAO,CAAC;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,SAA0B;AAC5B,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,IACE,OACA,UACA,SACY;AACZ,QAAI,OAAO;AACT,WAAK,QAAQ,OAAO,OAAO,UAAU,OAAO;AAAA,IAC9C;AAEA,QAAI,MAAM,KAAK,gBAAgB,IAAI,KAAK;AAExC,QAAI,CAAC,KAAK;AACR,YAAM,oBAAI,IAAI;AACd,WAAK,gBAAgB,IAAI,OAAO,GAAG;AAAA,IACrC;AAEA,QAAI,IAAI,QAAQ;AAEhB,UAAM,SAAS,eAAe,MAAM,OAAO,KAAK,QAAQ;AACxD,WAAO,iBAAiB,OAAO,UAAU,OAAO;AAEhD,WAAO,MAAM;AACX,WAAK,KAAK,OAAO,UAAU,OAAO;AAAA,IACpC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,KACE,OACA,UACA,SACA;AACA,QAAI,OAAO;AACT,WAAK,QAAQ,QAAQ,OAAO,QAAQ;AAAA,IACtC;AAEA,SAAK,gBAAgB,IAAI,KAAK,EAAE,OAAO,QAAQ;AAE/C,UAAM,SAAS,eAAe,MAAM,OAAO,KAAK,QAAQ;AACxD,WAAO,oBAAoB,OAAO,UAAU,OAAO;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,UAAkB,MAAiB;AACvC,QAAI,OAAO;AACT,WAAK,QAAQ,SAAS,OAAO,IAAI;AAAA,IACnC;AAEA,SAAK,cAAc,IAAI,YAAY,OAAO,EAAE,QAAQ,KAAK,CAAC,CAAC;AAAA,EAC7D;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,UAAU,gBAA+C;AAC9D,WAAO,qBAAqB,kBAAkB,KAAK,OAAO,IAAI,EAAE;AAAA,MAAI,CAAC,OACnE,IAAI,KAAK,EAAE,EAAE,OAAO;AAAA,IACtB;AAAA,EACF;AACF;",
4
+ "sourcesContent": ["/* eslint-disable no-use-before-define */\nimport {\n getComponentElements,\n getEventTarget,\n addToQueue,\n addInstance,\n deleteInstance,\n} from './utils.js';\nimport {\n ChildrenManager,\n RefsManager,\n ServicesManager,\n EventsManager,\n OptionsManager,\n} from './managers/index.js';\nimport { noop, isDev, isFunction, isArray } from '../utils/index.js';\n\nlet id = 0;\n\nexport type BaseEl = HTMLElement & { __base__?: WeakMap<BaseConstructor, Base | 'terminated'> };\nexport type BaseConstructor<T extends Base = Base> = {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n new (...args: any[]): T;\n prototype: Base;\n} & Pick<typeof Base, keyof typeof Base>;\nexport type BaseAsyncConstructor<T extends Base = Base> = (\n instance: Base,\n) => Promise<BaseConstructor<T> | { default: BaseConstructor<T> }>;\nexport type BaseOptions = { [name: string]: unknown };\nexport type BaseRefs = { [name: string]: HTMLElement | HTMLElement[] };\nexport type BaseChildren = { [nameOrSelector: string]: Base[] | Promise<Base>[] };\nexport type BaseConfigComponents = {\n [nameOrSelector: string]: BaseConstructor | BaseAsyncConstructor;\n};\n\nexport type BaseConfig = {\n name: string;\n debug?: boolean;\n log?: boolean;\n refs?: string[];\n emits?: string[];\n components?: BaseConfigComponents;\n options?: import('./managers/OptionsManager').OptionsSchema;\n};\n\nexport type BaseProps = {\n $el?: HTMLElement;\n $options?: BaseOptions;\n $refs?: BaseRefs;\n $children?: BaseChildren;\n $parent?: Base;\n};\n\nexport type Managers = {\n ChildrenManager: typeof ChildrenManager;\n EventsManager: typeof EventsManager;\n OptionsManager: typeof OptionsManager;\n RefsManager: typeof RefsManager;\n ServicesManager: typeof ServicesManager;\n};\n\n/**\n * Base class.\n */\nexport class Base<T extends BaseProps = BaseProps> extends EventTarget {\n /**\n * This is a Base instance.\n */\n static readonly $isBase = true as const;\n\n /**\n * The instance parent.\n */\n $parent: T['$parent'] & Base = null;\n\n /**\n * The instance id.\n */\n $id: string;\n\n /**\n * The root element.\n */\n $el: T['$el'] & BaseEl;\n\n /**\n * The state of the component.\n */\n $isMounted = false;\n\n /**\n * Store the event handlers.\n */\n __eventHandlers: Map<string, Set<EventListenerOrEventListenerObject>> = new Map();\n\n /**\n * Get the root instance of the app.\n */\n get $root(): Base {\n if (!this.$parent) {\n return this;\n }\n\n let parent = this.$parent;\n let root = this.$parent;\n\n while (parent) {\n if (!parent.$parent) {\n root = parent;\n }\n\n parent = parent.$parent;\n }\n\n return root;\n }\n\n /**\n * Merge configuration with the parents' configurations.\n */\n get __config(): BaseConfig {\n let proto = Object.getPrototypeOf(this);\n let { config } = proto.constructor;\n\n while (proto.constructor.config && proto.constructor.$isBase) {\n config = { ...proto.constructor.config, ...config };\n\n if (proto.constructor.config.options) {\n config.options = { ...proto.constructor.config.options, ...config.options };\n }\n\n if (proto.constructor.config.emits && config.emits) {\n config.emits = [...proto.constructor.config.emits, ...config.emits];\n }\n\n proto = Object.getPrototypeOf(proto);\n }\n\n config.options = config.options ?? {};\n config.refs = config.refs ?? [];\n config.components = config.components ?? {};\n\n return config;\n }\n\n static config: BaseConfig = {\n name: 'Base',\n emits: [\n // hook events\n 'before-mounted',\n 'mounted',\n 'updated',\n 'destroyed',\n 'terminated',\n // default services' events\n 'ticked',\n 'scrolled',\n 'resized',\n 'moved',\n 'loaded',\n 'keyed',\n ],\n };\n\n __services: ServicesManager;\n\n get $services(): ServicesManager {\n return this.__services;\n }\n\n __refs: RefsManager & T['$refs'] & BaseRefs;\n\n get $refs(): RefsManager & T['$refs'] & BaseRefs {\n return this.__refs;\n }\n\n __options: OptionsManager & T['$options'] & BaseOptions;\n\n get $options(): OptionsManager & T['$options'] & BaseOptions {\n return this.__options;\n }\n\n __children: ChildrenManager & T['$children'] & BaseChildren;\n\n get $children(): ChildrenManager & T['$children'] & BaseChildren {\n return this.__children;\n }\n\n __events: EventsManager;\n\n /**\n * Small helper to log stuff.\n */\n get $log(): (...args: unknown[]) => void {\n return this.__options.log ? window.console.log.bind(window, `[${this.__config.name}]`) : noop;\n }\n\n /**\n * Small helper to make warning easier.\n */\n get $warn(): (...args: unknown[]) => void {\n return this.__options.log ? window.console.warn.bind(window, `[${this.__config.name}]`) : noop;\n }\n\n /**\n * Small helper to debug information.\n */\n get __debug(): (...args: unknown[]) => void {\n return isDev && this.__options.debug\n ? window.console.log.bind(window, `[debug] [${this.$id}]`)\n : noop;\n }\n\n /**\n * Get manager constructors.\n */\n get __managers(): Managers {\n return {\n ChildrenManager,\n EventsManager,\n OptionsManager,\n RefsManager,\n ServicesManager,\n };\n }\n\n /**\n * Call an instance method and emit corresponding events.\n */\n __callMethod(method: string, ...args: unknown[]): unknown {\n if (isDev) {\n this.__debug('callMethod', method, ...args);\n }\n\n this.$emit(method, ...args);\n\n // We always emit an event, but we do not call the method if it does not exist\n if (!isFunction(this[method])) {\n return null;\n }\n\n if (isDev) {\n this.__debug(method, this, ...args);\n }\n\n return this[method].call(this, ...args);\n }\n\n /**\n * Test if the given event has been bound to the instance.\n *\n * @param {string} event The event's name.\n * @returns {boolean} Wether the given event has been bound or not.\n */\n __hasEvent(event: string): boolean {\n const eventHandlers = this.__eventHandlers.get(event);\n return eventHandlers && eventHandlers.size > 0;\n }\n\n /**\n * Class constructor where all the magic takes place.\n *\n * @param {HTMLElement} element The component's root element dd.\n */\n constructor(element: HTMLElement) {\n super();\n\n if (!element) {\n if (isDev) {\n throw new Error('The root element must be defined.');\n }\n return;\n }\n\n const { __config } = this;\n\n if (__config.name === 'Base') {\n if (isDev) {\n throw new Error('The `config.name` property is required.');\n }\n return;\n }\n\n this.$id = `${__config.name}-${id}`;\n id += 1;\n\n this.$el = element;\n\n if (!this.$el.__base__) {\n this.$el.__base__ = new WeakMap();\n }\n\n this.$el.__base__.set(this.__ctor, this);\n\n for (const service of ['Options', 'Services', 'Events', 'Refs', 'Children']) {\n this[`__${service.toLowerCase()}`] = new this.__managers[`${service}Manager`](this);\n }\n\n this.$on('mounted', () => {\n addInstance(this);\n });\n this.$on('destroyed', () => {\n deleteInstance(this);\n });\n\n if (isDev) {\n this.__debug('constructor', this);\n }\n }\n\n /**\n * Trigger the `mounted` callback.\n */\n async $mount(): Promise<this> {\n if (this.$isMounted) {\n return this;\n }\n\n this.$emit('before-mounted');\n\n if (isDev) {\n this.__debug('$mount');\n }\n\n await Promise.all([\n addToQueue(() => this.$children.registerAll()),\n addToQueue(() => this.$refs.registerAll()),\n addToQueue(() => this.__events.bindRootElement()),\n addToQueue(() => this.$services.enableAll()),\n addToQueue(() => this.$children.mountAll()),\n addToQueue(() => (this.$isMounted = true)),\n addToQueue(() => this.__callMethod('mounted')),\n ]);\n\n return this;\n }\n\n /**\n * Update the instance children.\n */\n async $update(): Promise<this> {\n if (isDev) {\n this.__debug('$update');\n }\n\n await Promise.all([\n // Undo\n addToQueue(() => this.$refs.unregisterAll()),\n addToQueue(() => this.$services.disableAll()),\n // Redo\n addToQueue(() => this.$children.registerAll()),\n addToQueue(() => this.$refs.registerAll()),\n addToQueue(() => this.$services.enableAll()),\n // Update\n addToQueue(() => this.$children.updateAll()),\n addToQueue(() => this.__callMethod('updated')),\n ]);\n\n return this;\n }\n\n /**\n * Trigger the `destroyed` callback.\n */\n async $destroy(): Promise<this> {\n if (!this.$isMounted) {\n return this;\n }\n\n if (isDev) {\n this.__debug('$destroy');\n }\n\n await Promise.all([\n addToQueue(() => (this.$isMounted = false)),\n addToQueue(() => this.__events.unbindRootElement()),\n addToQueue(() => this.$refs.unregisterAll()),\n addToQueue(() => this.$services.disableAll()),\n addToQueue(() => this.$children.destroyAll()),\n addToQueue(() => this.__callMethod('destroyed')),\n ]);\n\n return this;\n }\n\n /**\n * Terminate a child instance when it is not needed anymore.\n */\n async $terminate(): Promise<void> {\n if (isDev) {\n this.__debug('$terminate');\n }\n\n await Promise.all([\n // First, destroy the component.\n addToQueue(() => this.$destroy()),\n // Execute the `terminated` hook if it exists\n addToQueue(() => this.__callMethod('terminated')),\n // Delete instance\n addToQueue(() => this.$el.__base__.set(this.__ctor, 'terminated')),\n ]);\n }\n\n /**\n * Add an emitted event.\n *\n * @param {string} event The event name.\n * @returns {void}\n */\n __addEmits(event: string): void {\n const ctor = this.__ctor;\n if (isArray(ctor.config.emits)) {\n ctor.config.emits.push(event);\n } else {\n ctor.config.emits = [event];\n }\n }\n\n /**\n * Remove an emitted event.\n *\n * @param {string} event The event name.\n * @returns {void}\n */\n __removeEmits(event: string): void {\n const ctor = this.__ctor;\n const index = ctor.config.emits.indexOf(event);\n ctor.config.emits.splice(index, 1);\n }\n\n /**\n * Get the instance constructor.\n */\n get __ctor(): BaseConstructor {\n return this.constructor as BaseConstructor;\n }\n\n /**\n * Bind a listener function to an event.\n *\n * @param {string} event\n * Name of the event.\n * @param {EventListenerOrEventListenerObject} listener\n * Function to be called.\n * @param {boolean|AddEventListenerOptions} [options]\n * Options for the `removeEventListener` method.\n * @returns {() => void}\n * A function to unbind the listener.\n */\n $on(\n event: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ): () => void {\n if (isDev) {\n this.__debug('$on', event, listener, options);\n }\n\n let set = this.__eventHandlers.get(event);\n\n if (!set) {\n set = new Set();\n this.__eventHandlers.set(event, set);\n }\n\n set.add(listener);\n\n const target = getEventTarget(this, event, this.__config);\n target?.addEventListener(event, listener, options);\n\n if (isDev) {\n if (!target) {\n console.warn(\n `[${this.$id}]`,\n `The \"${event}\" event is missing from the configuration and is not a native`,\n `event for the root element of type \\`${this.$el.constructor.name}\\`.`,\n );\n }\n }\n\n return () => {\n this.$off(event, listener, options);\n };\n }\n\n /**\n * Unbind a listener function from an event.\n *\n * @param {string} event\n * Name of the event.\n * @param {EventListenerOrEventListenerObject} listener\n * Function to be removed.\n * @param {boolean|EventListenerOptions} [options]\n * Options for the `removeEventListener` method.\n * @returns {void}\n */\n $off(\n event: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | EventListenerOptions,\n ) {\n if (isDev) {\n this.__debug('$off', event, listener);\n }\n\n this.__eventHandlers.get(event).delete(listener);\n\n const target = getEventTarget(this, event, this.__config);\n target?.removeEventListener(event, listener, options);\n }\n\n /**\n * Emits an event.\n *\n * @param {string} event Name of the event.\n * @param {any[]} args The arguments to apply to the functions bound to this event.\n * @returns {void}\n */\n $emit(event: string, ...args: unknown[]) {\n if (isDev) {\n this.__debug('$emit', event, args);\n }\n\n this.dispatchEvent(new CustomEvent(event, { detail: args }));\n }\n\n /**\n * Register and mount all instances of the component.\n */\n static $register(nameOrSelector?: string): Array<Promise<Base>> {\n return getComponentElements(nameOrSelector ?? this.config.name).map((el) =>\n new this(el).$mount(),\n );\n }\n}\n"],
5
+ "mappings": "AACA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,MAAM,OAAO,YAAY,eAAe;AAEjD,IAAI,KAAK;AA+CF,MAAM,aAA8C,YAAY;AAAA;AAAA;AAAA;AAAA,EAIrE,OAAgB,UAAU;AAAA;AAAA;AAAA;AAAA,EAK1B,UAA+B;AAAA;AAAA;AAAA;AAAA,EAK/B;AAAA;AAAA;AAAA;AAAA,EAKA;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa;AAAA;AAAA;AAAA;AAAA,EAKb,kBAAwE,oBAAI,IAAI;AAAA;AAAA;AAAA;AAAA,EAKhF,IAAI,QAAc;AAChB,QAAI,CAAC,KAAK,SAAS;AACjB,aAAO;AAAA,IACT;AAEA,QAAI,SAAS,KAAK;AAClB,QAAI,OAAO,KAAK;AAEhB,WAAO,QAAQ;AACb,UAAI,CAAC,OAAO,SAAS;AACnB,eAAO;AAAA,MACT;AAEA,eAAS,OAAO;AAAA,IAClB;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,WAAuB;AACzB,QAAI,QAAQ,OAAO,eAAe,IAAI;AACtC,QAAI,EAAE,OAAO,IAAI,MAAM;AAEvB,WAAO,MAAM,YAAY,UAAU,MAAM,YAAY,SAAS;AAC5D,eAAS,EAAE,GAAG,MAAM,YAAY,QAAQ,GAAG,OAAO;AAElD,UAAI,MAAM,YAAY,OAAO,SAAS;AACpC,eAAO,UAAU,EAAE,GAAG,MAAM,YAAY,OAAO,SAAS,GAAG,OAAO,QAAQ;AAAA,MAC5E;AAEA,UAAI,MAAM,YAAY,OAAO,SAAS,OAAO,OAAO;AAClD,eAAO,QAAQ,CAAC,GAAG,MAAM,YAAY,OAAO,OAAO,GAAG,OAAO,KAAK;AAAA,MACpE;AAEA,cAAQ,OAAO,eAAe,KAAK;AAAA,IACrC;AAEA,WAAO,UAAU,OAAO,WAAW,CAAC;AACpC,WAAO,OAAO,OAAO,QAAQ,CAAC;AAC9B,WAAO,aAAa,OAAO,cAAc,CAAC;AAE1C,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,SAAqB;AAAA,IAC1B,MAAM;AAAA,IACN,OAAO;AAAA;AAAA,MAEL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA;AAAA,MAEA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA;AAAA,EAEA,IAAI,YAA6B;AAC/B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA;AAAA,EAEA,IAAI,QAA6C;AAC/C,WAAO,KAAK;AAAA,EACd;AAAA,EAEA;AAAA,EAEA,IAAI,WAAyD;AAC3D,WAAO,KAAK;AAAA,EACd;AAAA,EAEA;AAAA,EAEA,IAAI,YAA6D;AAC/D,WAAO,KAAK;AAAA,EACd;AAAA,EAEA;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,OAAqC;AACvC,WAAO,KAAK,UAAU,MAAM,OAAO,QAAQ,IAAI,KAAK,QAAQ,IAAI,KAAK,SAAS,IAAI,GAAG,IAAI;AAAA,EAC3F;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,QAAsC;AACxC,WAAO,KAAK,UAAU,MAAM,OAAO,QAAQ,KAAK,KAAK,QAAQ,IAAI,KAAK,SAAS,IAAI,GAAG,IAAI;AAAA,EAC5F;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,UAAwC;AAC1C,WAAO,SAAS,KAAK,UAAU,QAC3B,OAAO,QAAQ,IAAI,KAAK,QAAQ,YAAY,KAAK,GAAG,GAAG,IACvD;AAAA,EACN;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,aAAuB;AACzB,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,WAAmB,MAA0B;AACxD,QAAI,OAAO;AACT,WAAK,QAAQ,cAAc,QAAQ,GAAG,IAAI;AAAA,IAC5C;AAEA,SAAK,MAAM,QAAQ,GAAG,IAAI;AAG1B,QAAI,CAAC,WAAW,KAAK,MAAM,CAAC,GAAG;AAC7B,aAAO;AAAA,IACT;AAEA,QAAI,OAAO;AACT,WAAK,QAAQ,QAAQ,MAAM,GAAG,IAAI;AAAA,IACpC;AAEA,WAAO,KAAK,MAAM,EAAE,KAAK,MAAM,GAAG,IAAI;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,WAAW,OAAwB;AACjC,UAAM,gBAAgB,KAAK,gBAAgB,IAAI,KAAK;AACpD,WAAO,iBAAiB,cAAc,OAAO;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,YAAY,SAAsB;AAChC,UAAM;AAEN,QAAI,CAAC,SAAS;AACZ,UAAI,OAAO;AACT,cAAM,IAAI,MAAM,mCAAmC;AAAA,MACrD;AACA;AAAA,IACF;AAEA,UAAM,EAAE,SAAS,IAAI;AAErB,QAAI,SAAS,SAAS,QAAQ;AAC5B,UAAI,OAAO;AACT,cAAM,IAAI,MAAM,yCAAyC;AAAA,MAC3D;AACA;AAAA,IACF;AAEA,SAAK,MAAM,GAAG,SAAS,IAAI,IAAI,EAAE;AACjC,UAAM;AAEN,SAAK,MAAM;AAEX,QAAI,CAAC,KAAK,IAAI,UAAU;AACtB,WAAK,IAAI,WAAW,oBAAI,QAAQ;AAAA,IAClC;AAEA,SAAK,IAAI,SAAS,IAAI,KAAK,QAAQ,IAAI;AAEvC,eAAW,WAAW,CAAC,WAAW,YAAY,UAAU,QAAQ,UAAU,GAAG;AAC3E,WAAK,KAAK,QAAQ,YAAY,CAAC,EAAE,IAAI,IAAI,KAAK,WAAW,GAAG,OAAO,SAAS,EAAE,IAAI;AAAA,IACpF;AAEA,SAAK,IAAI,WAAW,MAAM;AACxB,kBAAY,IAAI;AAAA,IAClB,CAAC;AACD,SAAK,IAAI,aAAa,MAAM;AAC1B,qBAAe,IAAI;AAAA,IACrB,CAAC;AAED,QAAI,OAAO;AACT,WAAK,QAAQ,eAAe,IAAI;AAAA,IAClC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAwB;AAC5B,QAAI,KAAK,YAAY;AACnB,aAAO;AAAA,IACT;AAEA,SAAK,MAAM,gBAAgB;AAE3B,QAAI,OAAO;AACT,WAAK,QAAQ,QAAQ;AAAA,IACvB;AAEA,UAAM,QAAQ,IAAI;AAAA,MAChB,WAAW,MAAM,KAAK,UAAU,YAAY,CAAC;AAAA,MAC7C,WAAW,MAAM,KAAK,MAAM,YAAY,CAAC;AAAA,MACzC,WAAW,MAAM,KAAK,SAAS,gBAAgB,CAAC;AAAA,MAChD,WAAW,MAAM,KAAK,UAAU,UAAU,CAAC;AAAA,MAC3C,WAAW,MAAM,KAAK,UAAU,SAAS,CAAC;AAAA,MAC1C,WAAW,MAAO,KAAK,aAAa,IAAK;AAAA,MACzC,WAAW,MAAM,KAAK,aAAa,SAAS,CAAC;AAAA,IAC/C,CAAC;AAED,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAyB;AAC7B,QAAI,OAAO;AACT,WAAK,QAAQ,SAAS;AAAA,IACxB;AAEA,UAAM,QAAQ,IAAI;AAAA;AAAA,MAEhB,WAAW,MAAM,KAAK,MAAM,cAAc,CAAC;AAAA,MAC3C,WAAW,MAAM,KAAK,UAAU,WAAW,CAAC;AAAA;AAAA,MAE5C,WAAW,MAAM,KAAK,UAAU,YAAY,CAAC;AAAA,MAC7C,WAAW,MAAM,KAAK,MAAM,YAAY,CAAC;AAAA,MACzC,WAAW,MAAM,KAAK,UAAU,UAAU,CAAC;AAAA;AAAA,MAE3C,WAAW,MAAM,KAAK,UAAU,UAAU,CAAC;AAAA,MAC3C,WAAW,MAAM,KAAK,aAAa,SAAS,CAAC;AAAA,IAC/C,CAAC;AAED,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,WAA0B;AAC9B,QAAI,CAAC,KAAK,YAAY;AACpB,aAAO;AAAA,IACT;AAEA,QAAI,OAAO;AACT,WAAK,QAAQ,UAAU;AAAA,IACzB;AAEA,UAAM,QAAQ,IAAI;AAAA,MAChB,WAAW,MAAO,KAAK,aAAa,KAAM;AAAA,MAC1C,WAAW,MAAM,KAAK,SAAS,kBAAkB,CAAC;AAAA,MAClD,WAAW,MAAM,KAAK,MAAM,cAAc,CAAC;AAAA,MAC3C,WAAW,MAAM,KAAK,UAAU,WAAW,CAAC;AAAA,MAC5C,WAAW,MAAM,KAAK,UAAU,WAAW,CAAC;AAAA,MAC5C,WAAW,MAAM,KAAK,aAAa,WAAW,CAAC;AAAA,IACjD,CAAC;AAED,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aAA4B;AAChC,QAAI,OAAO;AACT,WAAK,QAAQ,YAAY;AAAA,IAC3B;AAEA,UAAM,QAAQ,IAAI;AAAA;AAAA,MAEhB,WAAW,MAAM,KAAK,SAAS,CAAC;AAAA;AAAA,MAEhC,WAAW,MAAM,KAAK,aAAa,YAAY,CAAC;AAAA;AAAA,MAEhD,WAAW,MAAM,KAAK,IAAI,SAAS,IAAI,KAAK,QAAQ,YAAY,CAAC;AAAA,IACnE,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,WAAW,OAAqB;AAC9B,UAAM,OAAO,KAAK;AAClB,QAAI,QAAQ,KAAK,OAAO,KAAK,GAAG;AAC9B,WAAK,OAAO,MAAM,KAAK,KAAK;AAAA,IAC9B,OAAO;AACL,WAAK,OAAO,QAAQ,CAAC,KAAK;AAAA,IAC5B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,cAAc,OAAqB;AACjC,UAAM,OAAO,KAAK;AAClB,UAAM,QAAQ,KAAK,OAAO,MAAM,QAAQ,KAAK;AAC7C,SAAK,OAAO,MAAM,OAAO,OAAO,CAAC;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,SAA0B;AAC5B,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,IACE,OACA,UACA,SACY;AACZ,QAAI,OAAO;AACT,WAAK,QAAQ,OAAO,OAAO,UAAU,OAAO;AAAA,IAC9C;AAEA,QAAI,MAAM,KAAK,gBAAgB,IAAI,KAAK;AAExC,QAAI,CAAC,KAAK;AACR,YAAM,oBAAI,IAAI;AACd,WAAK,gBAAgB,IAAI,OAAO,GAAG;AAAA,IACrC;AAEA,QAAI,IAAI,QAAQ;AAEhB,UAAM,SAAS,eAAe,MAAM,OAAO,KAAK,QAAQ;AACxD,YAAQ,iBAAiB,OAAO,UAAU,OAAO;AAEjD,QAAI,OAAO;AACT,UAAI,CAAC,QAAQ;AACX,gBAAQ;AAAA,UACN,IAAI,KAAK,GAAG;AAAA,UACZ,QAAQ,KAAK;AAAA,UACb,wCAAwC,KAAK,IAAI,YAAY,IAAI;AAAA,QACnE;AAAA,MACF;AAAA,IACF;AAEA,WAAO,MAAM;AACX,WAAK,KAAK,OAAO,UAAU,OAAO;AAAA,IACpC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,KACE,OACA,UACA,SACA;AACA,QAAI,OAAO;AACT,WAAK,QAAQ,QAAQ,OAAO,QAAQ;AAAA,IACtC;AAEA,SAAK,gBAAgB,IAAI,KAAK,EAAE,OAAO,QAAQ;AAE/C,UAAM,SAAS,eAAe,MAAM,OAAO,KAAK,QAAQ;AACxD,YAAQ,oBAAoB,OAAO,UAAU,OAAO;AAAA,EACtD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,UAAkB,MAAiB;AACvC,QAAI,OAAO;AACT,WAAK,QAAQ,SAAS,OAAO,IAAI;AAAA,IACnC;AAEA,SAAK,cAAc,IAAI,YAAY,OAAO,EAAE,QAAQ,KAAK,CAAC,CAAC;AAAA,EAC7D;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,UAAU,gBAA+C;AAC9D,WAAO,qBAAqB,kBAAkB,KAAK,OAAO,IAAI,EAAE;AAAA,MAAI,CAAC,OACnE,IAAI,KAAK,EAAE,EAAE,OAAO;AAAA,IACtB;AAAA,EACF;AACF;",
6
6
  "names": []
7
7
  }
@@ -1,33 +1,5 @@
1
1
  import type { Base } from '../index.js';
2
2
  import { AbstractManager } from './AbstractManager.js';
3
- /**
4
- * Normalize the given name to PascalCase, such as:
5
- *
6
- * ```
7
- * sentence case => SentenceCase
8
- * lowercase => Lowercase
9
- * UPPERCASE => Uppercase
10
- * kebab-case => KebabCase
11
- * snake_case => SnakeCase
12
- * camelCase => CamelCase
13
- * PascalCase => PascalCase
14
- * .class-selector => ClassSelector
15
- * .bem__selector => BemSelector
16
- * __id-selector => IdSelector
17
- * .complex[class^ ="__"] => ComplexClass
18
- * ```
19
- *
20
- * @param {string} name
21
- * @returns {string}
22
- */
23
- export declare function normalizeName(name: string): string;
24
- /**
25
- * Normalize the event names from PascalCase to kebab-case.
26
- *
27
- * @param {string} name
28
- * @returns {string}
29
- */
30
- export declare function normalizeEventName(name: string): string;
31
3
  export type EventManagerCallbackParams = {
32
4
  event: Event | null;
33
5
  args: Array<any>;
@@ -1,34 +1,9 @@
1
1
  import getAllProperties from "../../utils/object/getAllProperties.js";
2
- import { isArray } from "../../utils/index.js";
3
- import { getEventTarget, eventIsNative, eventIsDefinedInConfig } from "../utils.js";
2
+ import { dashCase, isArray, pascalCase } from "../../utils/index.js";
3
+ import { getEventTarget } from "../utils.js";
4
4
  import { AbstractManager } from "./AbstractManager.js";
5
5
  import { normalizeRefName } from "./RefsManager.js";
6
6
  import { features } from "../features.js";
7
- const names = /* @__PURE__ */ new Map();
8
- const normalizeRegex1 = /[A-Z]([A-Z].*)/g;
9
- const normalizeRegex2 = /[^a-zA-Z\d\s:]/g;
10
- const normalizeRegex3 = /(^\w|\s+\w)/g;
11
- function normalizeName(name) {
12
- if (!names.has(name)) {
13
- names.set(
14
- name,
15
- name.replaceAll(normalizeRegex1, (c) => c.toLowerCase()).replaceAll(normalizeRegex2, " ").replaceAll(normalizeRegex3, (c) => c.trim().toUpperCase()).trim()
16
- );
17
- }
18
- return names.get(name);
19
- }
20
- const eventNames = /* @__PURE__ */ new Map();
21
- const normalizeEventRegex1 = /[A-Z]/g;
22
- const normalizeEventRegex2 = /^-/;
23
- function normalizeEventName(name) {
24
- if (!eventNames.has(name)) {
25
- eventNames.set(
26
- name,
27
- name.replaceAll(normalizeEventRegex1, (c) => `-${c.toLowerCase()}`).replace(normalizeEventRegex2, "")
28
- );
29
- }
30
- return eventNames.get(name);
31
- }
32
7
  const regexes = /* @__PURE__ */ new Map();
33
8
  function getRegex(regex) {
34
9
  if (!regexes.has(regex)) {
@@ -37,12 +12,12 @@ function getRegex(regex) {
37
12
  return regexes.get(regex);
38
13
  }
39
14
  function getEventNameByMethod(method, name = "") {
40
- const regex = getRegex(`^on${normalizeName(name)}([A-Z].*)$`);
15
+ const regex = getRegex(`^on${pascalCase(name)}([A-Z].*)$`);
41
16
  const [, event] = method.match(regex);
42
- return normalizeEventName(event);
17
+ return dashCase(event);
43
18
  }
44
19
  function getEventMethodsByName(that, name = "") {
45
- const regex = getRegex(`^on${normalizeName(name)}[A-Z].*$`);
20
+ const regex = getRegex(`^on${pascalCase(name)}[A-Z].*$`);
46
21
  const key = regex.toString();
47
22
  let methods = that.__methodsCache.get(key);
48
23
  if (!methods) {
@@ -71,9 +46,12 @@ function manageRef(that, name, elements, mode = "add") {
71
46
  function manageChild(that, name, instance, mode = "add") {
72
47
  const action = mode === "add" ? "$on" : "$off";
73
48
  const methods = getEventMethodsByName(that, name);
49
+ const config = instance.__config;
74
50
  for (const method of methods) {
75
51
  const event = getEventNameByMethod(method, name);
76
- instance[action](event, that.__childrenHandler);
52
+ if (getEventTarget(instance, event, config)) {
53
+ instance[action](event, that.__childrenHandler);
54
+ }
77
55
  }
78
56
  }
79
57
  const isDocumentRegex = /^onDocument[A-Z][a-z]+/;
@@ -88,16 +66,16 @@ function manageRootElement(that, mode = "add") {
88
66
  const { __base: base, __config: config } = that;
89
67
  for (const method of methods) {
90
68
  let event = getEventNameByMethod(method);
91
- if (eventIsDefinedInConfig(event, config) || eventIsNative(event, base.$el)) {
92
- const target = getEventTarget(base, event, config);
93
- target[modeMethod](event, that.__rootElementHandler);
94
- } else if (methodIsGlobal(method)) {
69
+ if (methodIsGlobal(method)) {
95
70
  event = getEventNameByMethod(method, methodIsDocument(method) ? "document" : "window");
96
71
  const target = getGlobalEventTarget(method);
97
72
  target[modeMethod](
98
73
  event,
99
74
  methodIsDocument(method) ? that.__documentHandler : that.__windowHandler
100
75
  );
76
+ } else {
77
+ const target = getEventTarget(base, event, config);
78
+ target?.[modeMethod](event, that.__rootElementHandler);
101
79
  }
102
80
  }
103
81
  }
@@ -117,7 +95,7 @@ class EventsManager extends AbstractManager {
117
95
  */
118
96
  __rootElementHandler = {
119
97
  handleEvent: (event) => {
120
- const normalizedEventName = normalizeName(event.type);
98
+ const normalizedEventName = pascalCase(event.type);
121
99
  const method = `on${normalizedEventName}`;
122
100
  const isCustomEvent = event instanceof CustomEvent;
123
101
  this.__base[method](
@@ -140,7 +118,7 @@ class EventsManager extends AbstractManager {
140
118
  * @returns {void}
141
119
  */
142
120
  handleEvent: (event) => {
143
- const normalizedEventName = normalizeName(event.type);
121
+ const normalizedEventName = pascalCase(event.type);
144
122
  const method = `onDocument${normalizedEventName}`;
145
123
  this.__base[method](normalizeParams({ event, target: document }));
146
124
  }
@@ -156,7 +134,7 @@ class EventsManager extends AbstractManager {
156
134
  * @returns {void}
157
135
  */
158
136
  handleEvent: (event) => {
159
- const normalizedEventName = normalizeName(event.type);
137
+ const normalizedEventName = pascalCase(event.type);
160
138
  const method = `onWindow${normalizedEventName}`;
161
139
  this.__base[method](normalizeParams({ event, target: window }));
162
140
  }
@@ -169,8 +147,8 @@ class EventsManager extends AbstractManager {
169
147
  const ref = event.currentTarget;
170
148
  const attributes = features.get("attributes");
171
149
  const refName = normalizeRefName(ref.getAttribute(attributes.ref));
172
- const normalizedRefName = normalizeName(refName);
173
- const normalizedEventName = normalizeName(event.type);
150
+ const normalizedRefName = pascalCase(refName);
151
+ const normalizedEventName = pascalCase(event.type);
174
152
  const method = `on${normalizedRefName}${normalizedEventName}`;
175
153
  let index = 0;
176
154
  if (isArray(this.__base.$refs[refName])) {
@@ -192,8 +170,8 @@ class EventsManager extends AbstractManager {
192
170
  (instance) => instance === event.currentTarget || instance.$el === event.currentTarget
193
171
  )
194
172
  })).find(({ child }) => child);
195
- const normalizedChildName = normalizeName(name);
196
- const normalizedEventName = normalizeName(event.type);
173
+ const normalizedChildName = pascalCase(name);
174
+ const normalizedEventName = pascalCase(event.type);
197
175
  const method = `on${normalizedChildName}${normalizedEventName}`;
198
176
  const index = [...childrenManager[name]].indexOf(resolvedChild);
199
177
  const args = isArray(event.detail) ? event.detail : [];
@@ -280,8 +258,6 @@ class EventsManager extends AbstractManager {
280
258
  }
281
259
  }
282
260
  export {
283
- EventsManager,
284
- normalizeEventName,
285
- normalizeName
261
+ EventsManager
286
262
  };
287
263
  //# sourceMappingURL=EventsManager.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../packages/js-toolkit/Base/managers/EventsManager.ts"],
4
- "sourcesContent": ["import type { Base } from '../index.js';\nimport getAllProperties from '../../utils/object/getAllProperties.js';\nimport { isArray } from '../../utils/index.js';\nimport { getEventTarget, eventIsNative, eventIsDefinedInConfig } from '../utils.js';\nimport { AbstractManager } from './AbstractManager.js';\nimport { normalizeRefName } from './RefsManager.js';\nimport { features } from '../features.js';\n\nconst names = new Map();\nconst normalizeRegex1 = /[A-Z]([A-Z].*)/g;\nconst normalizeRegex2 = /[^a-zA-Z\\d\\s:]/g;\nconst normalizeRegex3 = /(^\\w|\\s+\\w)/g;\n\n/**\n * Normalize the given name to PascalCase, such as:\n *\n * ```\n * sentence case => SentenceCase\n * lowercase => Lowercase\n * UPPERCASE => Uppercase\n * kebab-case => KebabCase\n * snake_case => SnakeCase\n * camelCase => CamelCase\n * PascalCase => PascalCase\n * .class-selector => ClassSelector\n * .bem__selector => BemSelector\n * __id-selector => IdSelector\n * .complex[class^ =\"__\"] => ComplexClass\n * ```\n *\n * @param {string} name\n * @returns {string}\n */\nexport function normalizeName(name: string): string {\n if (!names.has(name)) {\n names.set(\n name,\n name\n .replaceAll(normalizeRegex1, (c) => c.toLowerCase())\n .replaceAll(normalizeRegex2, ' ')\n .replaceAll(normalizeRegex3, (c) => c.trim().toUpperCase())\n .trim(),\n );\n }\n\n return names.get(name);\n}\n\nconst eventNames = new Map();\n\nconst normalizeEventRegex1 = /[A-Z]/g;\nconst normalizeEventRegex2 = /^-/;\n/**\n * Normalize the event names from PascalCase to kebab-case.\n *\n * @param {string} name\n * @returns {string}\n */\nexport function normalizeEventName(name: string): string {\n if (!eventNames.has(name)) {\n eventNames.set(\n name,\n name\n .replaceAll(normalizeEventRegex1, (c) => `-${c.toLowerCase()}`)\n .replace(normalizeEventRegex2, ''),\n );\n }\n\n return eventNames.get(name);\n}\n\nconst regexes = new Map();\n\n/**\n * Get a regex with a cache;\n *\n * @param {string} regex\n * @returns {RegExp}\n */\nfunction getRegex(regex: string): RegExp {\n if (!regexes.has(regex)) {\n regexes.set(regex, new RegExp(regex));\n }\n\n return regexes.get(regex);\n}\n\n/**\n * Get the event name from the given method and its tied ref or children name.\n *\n * @param {string} method\n * @param {string} name\n * @returns {string}\n * @private\n */\nfunction getEventNameByMethod(method: string, name = ''): string {\n const regex = getRegex(`^on${normalizeName(name)}([A-Z].*)$`);\n const [, event] = method.match(regex);\n return normalizeEventName(event);\n}\n\n/**\n * Get the base instance methods matching the `onSomething` pattern.\n *\n * @param {EventsManager} that\n * @param {string} [name]\n * @returns {string[]}\n * @private\n */\n// eslint-disable-next-line no-use-before-define\nfunction getEventMethodsByName(that: EventsManager, name = ''): string[] {\n const regex = getRegex(`^on${normalizeName(name)}[A-Z].*$`);\n const key = regex.toString();\n\n let methods = that.__methodsCache.get(key);\n\n if (!methods) {\n methods = Array.from(\n getAllProperties(that.__base, [], (method) => regex.test(method)).reduce(\n (set, [method]) => set.add(method),\n new Set(),\n ),\n ) as string[];\n that.__methodsCache.set(key, methods);\n }\n\n return methods;\n}\n\n/**\n * Manage a ref event methods.\n *\n * @param {EventsManager} that\n * @param {string} name\n * The name of the ref.\n * @param {HTMLElement[]} elements\n * The elements of the ref.\n * @param {'add'|'remove'} [mode]\n * The action to perform: add or remove the event listeners.\n * @returns {void}\n * @private\n */\nfunction manageRef(\n // eslint-disable-next-line no-use-before-define\n that: EventsManager,\n name: string,\n elements: HTMLElement[],\n mode: 'add' | 'remove' = 'add',\n) {\n const action = `${mode}EventListener`;\n const methods = getEventMethodsByName(that, name);\n for (const method of methods) {\n const event = getEventNameByMethod(method, name);\n for (const element of elements) {\n if (element instanceof EventTarget) {\n element[action](event, that.__refsHandler);\n }\n }\n }\n}\n/**\n * Manage event methods to the given child instance.\n *\n * @param {EventsManager} that\n * @param {string} name\n * The name of the ref.\n * @param {Base} instance\n * A base instance.\n * @param {'add'|'remove'} [mode]\n * The action to perform: add or remove the event listeners.\n * @returns {void}\n * @private\n */\nfunction manageChild(\n // eslint-disable-next-line no-use-before-define\n that: EventsManager,\n name: string,\n instance: Base,\n mode: 'add' | 'remove' = 'add',\n) {\n const action = mode === 'add' ? '$on' : '$off';\n const methods = getEventMethodsByName(that, name);\n for (const method of methods) {\n const event = getEventNameByMethod(method, name);\n instance[action](event, that.__childrenHandler);\n }\n}\n\nconst isDocumentRegex = /^onDocument[A-Z][a-z]+/;\nconst isWindowRegex = /^onWindow[A-Z][a-z]+/;\nconst methodIsDocument = (method) => isDocumentRegex.test(method);\nconst methodIsWindow = (method) => isWindowRegex.test(method);\nconst methodIsGlobal = (method) => methodIsWindow(method) || methodIsDocument(method);\nconst getGlobalEventTarget = (method) => (methodIsDocument(method) ? document : window);\n\n/**\n * Manage event methods on the root element.\n *\n * @param {EventsManager} that\n * @param {'add'|'remove'} [mode]\n * The action to perform: add or remove the event listeners, defaults to 'add'.\n * @returns {void}\n * @private\n */\n// eslint-disable-next-line no-use-before-define\nfunction manageRootElement(that: EventsManager, mode: 'add' | 'remove' = 'add') {\n const modeMethod = `${mode}EventListener`;\n const methods = getEventMethodsByName(that);\n\n const { __base: base, __config: config } = that;\n\n for (const method of methods) {\n let event = getEventNameByMethod(method);\n\n if (eventIsDefinedInConfig(event, config) || eventIsNative(event, base.$el)) {\n const target = getEventTarget(base, event, config);\n target[modeMethod](event, that.__rootElementHandler);\n } else if (methodIsGlobal(method)) {\n event = getEventNameByMethod(method, methodIsDocument(method) ? 'document' : 'window');\n const target = getGlobalEventTarget(method);\n target[modeMethod](\n event,\n methodIsDocument(method) ? that.__documentHandler : that.__windowHandler,\n );\n }\n }\n}\n\nexport type EventManagerCallbackParams = {\n event: Event | null;\n args: Array<any>;\n index: number;\n target: Element | Base | Promise<Base> | typeof window | typeof document | null;\n};\n\n/**\n * Normalize `on...` method params.\n */\nfunction normalizeParams(\n params: Partial<EventManagerCallbackParams> = {},\n): EventManagerCallbackParams {\n return {\n event: null,\n args: [],\n index: 0,\n target: null,\n ...params,\n };\n}\n\n/**\n * Event management class.\n *\n * @todo Prevent binding of `onChildOrRefEvent` to the root element\n * @todo Use event delegation?\n */\nexport class EventsManager extends AbstractManager {\n __methodsCache: Map<string, string[]> = new Map();\n\n /**\n * Event listener object for the root element.\n */\n __rootElementHandler: EventListenerObject = {\n handleEvent: (event: Event | CustomEvent) => {\n const normalizedEventName = normalizeName(event.type);\n const method = `on${normalizedEventName}`;\n const isCustomEvent = event instanceof CustomEvent;\n\n this.__base[method](\n normalizeParams({\n event,\n args: isCustomEvent ? event.detail ?? [] : [],\n target: isCustomEvent ? this.__base : this.__element,\n }),\n );\n },\n };\n\n /**\n * Event listener object for the root element.\n *\n * @type {EventListenerObject}\n */\n __documentHandler = {\n /**\n * @param {Event|CustomEvent} event\n * @returns {void}\n */\n handleEvent: (event) => {\n const normalizedEventName = normalizeName(event.type);\n const method = `onDocument${normalizedEventName}`;\n\n this.__base[method](normalizeParams({ event, target: document }));\n },\n };\n\n /**\n * Event listener object for the root element.\n *\n * @type {EventListenerObject}\n */\n __windowHandler = {\n /**\n * @param {Event|CustomEvent} event\n * @returns {void}\n */\n handleEvent: (event) => {\n const normalizedEventName = normalizeName(event.type);\n const method = `onWindow${normalizedEventName}`;\n\n this.__base[method](normalizeParams({ event, target: window }));\n },\n };\n\n /**\n * Event listener object for the refs.\n */\n __refsHandler: EventListenerObject = {\n handleEvent: (event) => {\n const ref = event.currentTarget as HTMLElement;\n const attributes = features.get('attributes');\n const refName = normalizeRefName(ref.getAttribute(attributes.ref));\n\n const normalizedRefName = normalizeName(refName);\n const normalizedEventName = normalizeName(event.type);\n const method = `on${normalizedRefName}${normalizedEventName}`;\n\n let index = 0;\n if (isArray(this.__base.$refs[refName])) {\n index = (this.__base.$refs[refName] as HTMLElement[]).indexOf(ref);\n }\n\n this.__base[method](normalizeParams({ event, index, target: ref }));\n },\n };\n\n /**\n * Event listener object for the children.\n */\n __childrenHandler: EventListenerObject = {\n handleEvent: (event: CustomEvent) => {\n const childrenManager = this.__base.$children;\n\n // @todo handle async child components\n const { name, child: resolvedChild } = childrenManager.registeredNames\n .map((childName) => ({\n name: childName,\n child: [...childrenManager[childName]].find(\n // @ts-ignore\n (instance) => instance === event.currentTarget || instance.$el === event.currentTarget,\n ),\n }))\n .find(({ child }) => child);\n\n const normalizedChildName = normalizeName(name);\n const normalizedEventName = normalizeName(event.type);\n const method = `on${normalizedChildName}${normalizedEventName}`;\n\n const index = [...childrenManager[name]].indexOf(resolvedChild);\n\n const args = isArray(event.detail) ? event.detail : [];\n this.__base[method](normalizeParams({ event, index, args, target: resolvedChild }));\n },\n };\n\n /**\n * Class constructor.\n */\n constructor(base: Base) {\n super(base);\n\n this.__hideProperties([\n '__methodsCache',\n '__rootElementHandler',\n '__refsHandler',\n '__childrenHandler',\n '__documentHandler',\n '__windowHandler',\n ]);\n }\n\n /**\n * Bind event methods to the given ref elements.\n *\n * @param {string} name\n * The name of the ref.\n * @param {HTMLElement[]} elements\n * The elements of the ref.\n * @returns {void}\n */\n bindRef(name: string, elements: HTMLElement[]) {\n manageRef(this, name, elements);\n }\n\n /**\n * Bind event methods to the given ref elements.\n *\n * @param {string} name\n * The name of the ref.\n * @param {HTMLElement[]} elements\n * The elements of the ref.\n * @returns {void}\n */\n unbindRef(name: string, elements: HTMLElement[]) {\n manageRef(this, name, elements, 'remove');\n }\n\n /**\n * Bind event methods to the given child instance.\n *\n * @param {string} name\n * The name of the ref.\n * @param {Base} instance\n * A base instance.\n * @returns {void}\n */\n bindChild(name: string, instance: Base) {\n manageChild(this, name, instance);\n }\n\n /**\n * Unbind event methods to the given child instance.\n *\n * @param {string} name\n * The name of the ref.\n * @param {Base} instance\n * A base instance.\n * @returns {void}\n */\n unbindChild(name: string, instance: Base) {\n manageChild(this, name, instance, 'remove');\n }\n\n /**\n * Bind event methods on the root element.\n *\n * @returns {void}\n */\n bindRootElement() {\n manageRootElement(this);\n }\n\n /**\n * Unbind event method from the root element.\n *\n * @returns {void}\n */\n unbindRootElement() {\n manageRootElement(this, 'remove');\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type { Base } from '../index.js';\nimport getAllProperties from '../../utils/object/getAllProperties.js';\nimport { dashCase, isArray, pascalCase } from '../../utils/index.js';\nimport { getEventTarget, eventIsNative, eventIsDefinedInConfig } from '../utils.js';\nimport { AbstractManager } from './AbstractManager.js';\nimport { normalizeRefName } from './RefsManager.js';\nimport { features } from '../features.js';\n\nconst regexes = new Map();\n\n/**\n * Get a regex with a cache;\n *\n * @param {string} regex\n * @returns {RegExp}\n */\nfunction getRegex(regex: string): RegExp {\n if (!regexes.has(regex)) {\n regexes.set(regex, new RegExp(regex));\n }\n\n return regexes.get(regex);\n}\n\n/**\n * Get the event name from the given method and its tied ref or children name.\n *\n * @param {string} method\n * @param {string} name\n * @returns {string}\n * @private\n */\nfunction getEventNameByMethod(method: string, name = ''): string {\n const regex = getRegex(`^on${pascalCase(name)}([A-Z].*)$`);\n const [, event] = method.match(regex);\n return dashCase(event);\n}\n\n/**\n * Get the base instance methods matching the `onSomething` pattern.\n *\n * @param {EventsManager} that\n * @param {string} [name]\n * @returns {string[]}\n * @private\n */\n// eslint-disable-next-line no-use-before-define\nfunction getEventMethodsByName(that: EventsManager, name = ''): string[] {\n const regex = getRegex(`^on${pascalCase(name)}[A-Z].*$`);\n const key = regex.toString();\n\n let methods = that.__methodsCache.get(key);\n\n if (!methods) {\n methods = Array.from(\n getAllProperties(that.__base, [], (method) => regex.test(method)).reduce(\n (set, [method]) => set.add(method),\n new Set(),\n ),\n ) as string[];\n that.__methodsCache.set(key, methods);\n }\n\n return methods;\n}\n\n/**\n * Manage a ref event methods.\n *\n * @param {EventsManager} that\n * @param {string} name\n * The name of the ref.\n * @param {HTMLElement[]} elements\n * The elements of the ref.\n * @param {'add'|'remove'} [mode]\n * The action to perform: add or remove the event listeners.\n * @returns {void}\n * @private\n */\nfunction manageRef(\n // eslint-disable-next-line no-use-before-define\n that: EventsManager,\n name: string,\n elements: HTMLElement[],\n mode: 'add' | 'remove' = 'add',\n) {\n const action = `${mode}EventListener`;\n const methods = getEventMethodsByName(that, name);\n for (const method of methods) {\n const event = getEventNameByMethod(method, name);\n for (const element of elements) {\n if (element instanceof EventTarget) {\n element[action](event, that.__refsHandler);\n }\n }\n }\n}\n/**\n * Manage event methods to the given child instance.\n *\n * @param {EventsManager} that\n * @param {string} name\n * The name of the ref.\n * @param {Base} instance\n * A base instance.\n * @param {'add'|'remove'} [mode]\n * The action to perform: add or remove the event listeners.\n * @returns {void}\n * @private\n */\nfunction manageChild(\n // eslint-disable-next-line no-use-before-define\n that: EventsManager,\n name: string,\n instance: Base,\n mode: 'add' | 'remove' = 'add',\n) {\n const action = mode === 'add' ? '$on' : '$off';\n const methods = getEventMethodsByName(that, name);\n const config = instance.__config;\n for (const method of methods) {\n const event = getEventNameByMethod(method, name);\n if (getEventTarget(instance, event, config)) {\n instance[action](event, that.__childrenHandler);\n }\n }\n}\n\nconst isDocumentRegex = /^onDocument[A-Z][a-z]+/;\nconst isWindowRegex = /^onWindow[A-Z][a-z]+/;\nconst methodIsDocument = (method) => isDocumentRegex.test(method);\nconst methodIsWindow = (method) => isWindowRegex.test(method);\nconst methodIsGlobal = (method) => methodIsWindow(method) || methodIsDocument(method);\nconst getGlobalEventTarget = (method) => (methodIsDocument(method) ? document : window);\n\n/**\n * Manage event methods on the root element.\n *\n * @param {EventsManager} that\n * @param {'add'|'remove'} [mode]\n * The action to perform: add or remove the event listeners, defaults to 'add'.\n * @returns {void}\n * @private\n */\n// eslint-disable-next-line no-use-before-define\nfunction manageRootElement(that: EventsManager, mode: 'add' | 'remove' = 'add') {\n const modeMethod = `${mode}EventListener`;\n const methods = getEventMethodsByName(that);\n\n const { __base: base, __config: config } = that;\n\n for (const method of methods) {\n let event = getEventNameByMethod(method);\n\n if (methodIsGlobal(method)) {\n event = getEventNameByMethod(method, methodIsDocument(method) ? 'document' : 'window');\n const target = getGlobalEventTarget(method);\n target[modeMethod](\n event,\n methodIsDocument(method) ? that.__documentHandler : that.__windowHandler,\n );\n } else {\n const target = getEventTarget(base, event, config);\n target?.[modeMethod](event, that.__rootElementHandler);\n }\n }\n}\n\nexport type EventManagerCallbackParams = {\n event: Event | null;\n args: Array<any>;\n index: number;\n target: Element | Base | Promise<Base> | typeof window | typeof document | null;\n};\n\n/**\n * Normalize `on...` method params.\n */\nfunction normalizeParams(\n params: Partial<EventManagerCallbackParams> = {},\n): EventManagerCallbackParams {\n return {\n event: null,\n args: [],\n index: 0,\n target: null,\n ...params,\n };\n}\n\n/**\n * Event management class.\n *\n * @todo Prevent binding of `onChildOrRefEvent` to the root element\n * @todo Use event delegation?\n */\nexport class EventsManager extends AbstractManager {\n __methodsCache: Map<string, string[]> = new Map();\n\n /**\n * Event listener object for the root element.\n */\n __rootElementHandler: EventListenerObject = {\n handleEvent: (event: Event | CustomEvent) => {\n const normalizedEventName = pascalCase(event.type);\n const method = `on${normalizedEventName}`;\n const isCustomEvent = event instanceof CustomEvent;\n\n this.__base[method](\n normalizeParams({\n event,\n args: isCustomEvent ? event.detail ?? [] : [],\n target: isCustomEvent ? this.__base : this.__element,\n }),\n );\n },\n };\n\n /**\n * Event listener object for the root element.\n *\n * @type {EventListenerObject}\n */\n __documentHandler = {\n /**\n * @param {Event|CustomEvent} event\n * @returns {void}\n */\n handleEvent: (event) => {\n const normalizedEventName = pascalCase(event.type);\n const method = `onDocument${normalizedEventName}`;\n\n this.__base[method](normalizeParams({ event, target: document }));\n },\n };\n\n /**\n * Event listener object for the root element.\n *\n * @type {EventListenerObject}\n */\n __windowHandler = {\n /**\n * @param {Event|CustomEvent} event\n * @returns {void}\n */\n handleEvent: (event) => {\n const normalizedEventName = pascalCase(event.type);\n const method = `onWindow${normalizedEventName}`;\n\n this.__base[method](normalizeParams({ event, target: window }));\n },\n };\n\n /**\n * Event listener object for the refs.\n */\n __refsHandler: EventListenerObject = {\n handleEvent: (event) => {\n const ref = event.currentTarget as HTMLElement;\n const attributes = features.get('attributes');\n const refName = normalizeRefName(ref.getAttribute(attributes.ref));\n\n const normalizedRefName = pascalCase(refName);\n const normalizedEventName = pascalCase(event.type);\n const method = `on${normalizedRefName}${normalizedEventName}`;\n\n let index = 0;\n if (isArray(this.__base.$refs[refName])) {\n index = (this.__base.$refs[refName] as HTMLElement[]).indexOf(ref);\n }\n\n this.__base[method](normalizeParams({ event, index, target: ref }));\n },\n };\n\n /**\n * Event listener object for the children.\n */\n __childrenHandler: EventListenerObject = {\n handleEvent: (event: CustomEvent) => {\n const childrenManager = this.__base.$children;\n\n // @todo handle async child components\n const { name, child: resolvedChild } = childrenManager.registeredNames\n .map((childName) => ({\n name: childName,\n child: [...childrenManager[childName]].find(\n // @ts-ignore\n (instance) => instance === event.currentTarget || instance.$el === event.currentTarget,\n ),\n }))\n .find(({ child }) => child);\n\n const normalizedChildName = pascalCase(name);\n const normalizedEventName = pascalCase(event.type);\n const method = `on${normalizedChildName}${normalizedEventName}`;\n\n const index = [...childrenManager[name]].indexOf(resolvedChild);\n\n const args = isArray(event.detail) ? event.detail : [];\n this.__base[method](normalizeParams({ event, index, args, target: resolvedChild }));\n },\n };\n\n /**\n * Class constructor.\n */\n constructor(base: Base) {\n super(base);\n\n this.__hideProperties([\n '__methodsCache',\n '__rootElementHandler',\n '__refsHandler',\n '__childrenHandler',\n '__documentHandler',\n '__windowHandler',\n ]);\n }\n\n /**\n * Bind event methods to the given ref elements.\n *\n * @param {string} name\n * The name of the ref.\n * @param {HTMLElement[]} elements\n * The elements of the ref.\n * @returns {void}\n */\n bindRef(name: string, elements: HTMLElement[]) {\n manageRef(this, name, elements);\n }\n\n /**\n * Bind event methods to the given ref elements.\n *\n * @param {string} name\n * The name of the ref.\n * @param {HTMLElement[]} elements\n * The elements of the ref.\n * @returns {void}\n */\n unbindRef(name: string, elements: HTMLElement[]) {\n manageRef(this, name, elements, 'remove');\n }\n\n /**\n * Bind event methods to the given child instance.\n *\n * @param {string} name\n * The name of the ref.\n * @param {Base} instance\n * A base instance.\n * @returns {void}\n */\n bindChild(name: string, instance: Base) {\n manageChild(this, name, instance);\n }\n\n /**\n * Unbind event methods to the given child instance.\n *\n * @param {string} name\n * The name of the ref.\n * @param {Base} instance\n * A base instance.\n * @returns {void}\n */\n unbindChild(name: string, instance: Base) {\n manageChild(this, name, instance, 'remove');\n }\n\n /**\n * Bind event methods on the root element.\n *\n * @returns {void}\n */\n bindRootElement() {\n manageRootElement(this);\n }\n\n /**\n * Unbind event method from the root element.\n *\n * @returns {void}\n */\n unbindRootElement() {\n manageRootElement(this, 'remove');\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -34,7 +34,7 @@ export type OptionsInterface = {
34
34
  /**
35
35
  * Get a property name.
36
36
  */
37
- export declare function __getPropertyName(name: string, prefix?: string): string;
37
+ export declare const __getPropertyName: (name: string, prefix?: unknown) => string;
38
38
  /**
39
39
  * Class options to manage options as data attributes on an HTML element.
40
40
  *
@@ -1,6 +1,14 @@
1
1
  import deepmerge from "deepmerge";
2
2
  import { AbstractManager } from "./AbstractManager.js";
3
- import { isDev, isFunction, isDefined, isBoolean, isArray, isObject } from "../../utils/index.js";
3
+ import {
4
+ isDev,
5
+ isFunction,
6
+ isDefined,
7
+ isBoolean,
8
+ isArray,
9
+ isObject,
10
+ memo
11
+ } from "../../utils/index.js";
4
12
  import { features } from "../features.js";
5
13
  const types = /* @__PURE__ */ new Set([String, Number, Boolean, Array, Object]);
6
14
  const __defaultValues = {
@@ -10,19 +18,12 @@ const __defaultValues = {
10
18
  Array: () => [],
11
19
  Object: () => ({})
12
20
  };
13
- const __propertyNameCache = /* @__PURE__ */ new Map();
14
- const matchUppercaseRegexp = /([A-Z])/g;
15
- function __getPropertyName(name, prefix = "") {
16
- const key = name + prefix;
17
- if (__propertyNameCache.has(key)) {
18
- return __propertyNameCache.get(key);
19
- }
21
+ const UPPERCASE_REGEX = /([A-Z])/g;
22
+ const __getPropertyName = memo(function __getPropertyName2(name, prefix = "") {
20
23
  const attributes = features.get("attributes");
21
- const normalizedName = name.replace(matchUppercaseRegexp, "-$1");
22
- const propertyName = `${attributes.option}${prefix ? `-${prefix}` : ""}-${normalizedName}`;
23
- __propertyNameCache.set(key, propertyName);
24
+ const propertyName = `${attributes.option}${prefix ? `-${prefix}` : ""}-${name.replaceAll(UPPERCASE_REGEX, "-$1")}`;
24
25
  return propertyName;
25
- }
26
+ });
26
27
  function __register(that, name, config) {
27
28
  if (!types.has(config.type)) {
28
29
  if (isDev) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../packages/js-toolkit/Base/managers/OptionsManager.ts"],
4
- "sourcesContent": ["import deepmerge from 'deepmerge';\nimport type { Options as DeepmergeOptions } from 'deepmerge';\nimport { AbstractManager } from './AbstractManager.js';\nimport { isDev, isFunction, isDefined, isBoolean, isArray, isObject } from '../../utils/index.js';\nimport type { Base } from '../index.js';\nimport { features } from '../features.js';\n\ntype OptionType =\n | StringConstructor\n | NumberConstructor\n | BooleanConstructor\n | ArrayConstructor\n | ObjectConstructor;\n\ntype ArrayOption = {\n type: ArrayConstructor;\n default?: (instance: Base) => unknown[];\n merge?: boolean | DeepmergeOptions;\n};\n\ntype ObjectOption = {\n type: ObjectConstructor;\n default?: (instance: Base) => unknown;\n merge?: boolean | DeepmergeOptions;\n};\n\ntype StringOption = {\n type: StringConstructor;\n default?: string | ((instance: Base) => string);\n};\n\ntype NumberOption = {\n type: NumberConstructor;\n default?: number | ((instance: Base) => number);\n};\n\ntype BooleanOption = {\n type: BooleanConstructor;\n default?: boolean | ((instance: Base) => boolean);\n};\n\nexport type OptionObject = ArrayOption | ObjectOption | StringOption | NumberOption | BooleanOption;\nexport type OptionsSchema = { [name: string]: OptionType | OptionObject };\nexport type OptionsInterface = { [optionName: string]: unknown };\n\n/**\n * List of allowed types.\n */\nconst types: Set<OptionType> = new Set([String, Number, Boolean, Array, Object]);\n\n/**\n * The default values to return for each available type.\n */\nconst __defaultValues = {\n String: '',\n Number: 0,\n Boolean: false,\n Array: () => [],\n Object: () => ({}),\n};\n\n/**\n * Property name cache.\n */\nconst __propertyNameCache: Map<string, string> = new Map();\nconst matchUppercaseRegexp = /([A-Z])/g;\n\n/**\n * Get a property name.\n */\nexport function __getPropertyName(name: string, prefix = '') {\n const key = name + prefix;\n\n if (__propertyNameCache.has(key)) {\n return __propertyNameCache.get(key);\n }\n\n const attributes = features.get('attributes');\n const normalizedName = name.replace(matchUppercaseRegexp, '-$1');\n const propertyName = `${attributes.option}${prefix ? `-${prefix}` : ''}-${normalizedName}`;\n __propertyNameCache.set(key, propertyName);\n return propertyName;\n}\n\n/**\n * Register an option.\n *\n * @param {OptionsManager} that\n * @param {string} name\n * @param {OptionObject} config\n * @returns {void}\n * @private\n */\nfunction __register(that: OptionsManager, name: string, config: OptionObject) {\n if (!types.has(config.type)) {\n if (isDev) {\n throw new Error(\n `The \"${name}\" option has an invalid type. The allowed types are: String, Number, Boolean, Array and Object.`,\n );\n }\n return;\n }\n\n config.default = config.default ?? __defaultValues[config.type.name];\n\n if ((config.type === Array || config.type === Object) && !isFunction(config.default)) {\n if (isDev) {\n throw new Error(\n `The default value for options of type \"${config.type.name}\" must be returned by a function.`,\n );\n }\n return;\n }\n\n Object.defineProperty(that, name, {\n get: () => that.get(name, config),\n set: (value) => {\n that.set(name, value, config);\n },\n enumerable: true,\n });\n}\n\n/**\n * Class options to manage options as data attributes on an HTML element.\n *\n * @todo Use `MutationObserver` to update values? Might be more performant.\n */\nexport class OptionsManager extends AbstractManager {\n /**\n * An object to store Array and Object values for reference.\n *\n * @private\n */\n __values = {};\n\n /**\n * Default value for the name property.\n */\n name = 'Base';\n\n /**\n * Default value for the debug property.\n */\n debug = false;\n\n /**\n * Default value for the log property.\n */\n log = false;\n\n /**\n * Class constructor.\n */\n constructor(base: Base) {\n super(base);\n\n this.__hideProperties(['__values', '__defaultValues']);\n const schema: OptionsSchema = this.__config.options || {};\n this.name = this.__config.name;\n\n schema.debug = {\n type: Boolean,\n default: this.__config.debug ?? false,\n };\n\n schema.log = {\n type: Boolean,\n default: this.__config.log ?? false,\n };\n\n for (const [name, config] of Object.entries(schema)) {\n __register(\n this,\n name,\n types.has(config as OptionType)\n ? ({ type: config as OptionType } as OptionObject)\n : (config as OptionObject),\n );\n }\n }\n\n /**\n * Get an option value.\n */\n get(name: string, config: OptionObject) {\n const { type } = config;\n const defaultValue = isFunction(config.default) ? config.default(this.__base) : config.default;\n const propertyName = __getPropertyName(name);\n const hasProperty = this.__element.hasAttribute(propertyName);\n\n if (type === Boolean) {\n if (defaultValue) {\n const negatedPropertyName = __getPropertyName(name, 'no');\n const hasNegatedProperty = this.__element.hasAttribute(negatedPropertyName);\n\n return !hasNegatedProperty;\n }\n\n return hasProperty || defaultValue;\n }\n\n const value = this.__element.getAttribute(propertyName);\n\n if (type === Number) {\n return hasProperty ? Number(value) : defaultValue;\n }\n\n if (type === Array || type === Object) {\n // eslint-disable-next-line no-param-reassign\n config = type === Array ? (config as ArrayOption) : (config as ObjectOption);\n\n if (!this.__values[name]) {\n let val = hasProperty ? JSON.parse(value) : defaultValue;\n\n if (isDefined(config.merge)) {\n val = isBoolean(config.merge)\n ? deepmerge(defaultValue, val)\n : deepmerge(defaultValue, val, config.merge);\n }\n\n this.__values[name] = val;\n }\n\n return this.__values[name];\n }\n\n return hasProperty ? value : defaultValue;\n }\n\n /**\n * Set an option value.\n */\n set(name: string, value: unknown, config: OptionObject) {\n const { type, default: defaultValue } = config;\n const propertyName = __getPropertyName(name);\n\n if (value.constructor.name !== type.name) {\n if (isDev) {\n const val = isArray(value) || isObject(value) ? JSON.stringify(value) : value;\n throw new TypeError(\n `The \"${val}\" value for the \"${name}\" option must be of type \"${type.name}\"`,\n );\n }\n return;\n }\n\n switch (type) {\n case Boolean:\n if (defaultValue) {\n const negatedPropertyName = __getPropertyName(name, 'no');\n\n if (value) {\n this.__element.removeAttribute(negatedPropertyName);\n } else {\n this.__element.setAttribute(negatedPropertyName, '');\n }\n } else if (value) {\n this.__element.setAttribute(propertyName, '');\n } else {\n this.__element.removeAttribute(propertyName);\n }\n break;\n case Array:\n case Object:\n this.__values[name] = value;\n break;\n default:\n this.__element.setAttribute(propertyName, value as string);\n }\n }\n}\n"],
5
- "mappings": "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",
6
- "names": []
4
+ "sourcesContent": ["import deepmerge from 'deepmerge';\nimport type { Options as DeepmergeOptions } from 'deepmerge';\nimport { AbstractManager } from './AbstractManager.js';\nimport {\n isDev,\n isFunction,\n isDefined,\n isBoolean,\n isArray,\n isObject,\n memo,\n} from '../../utils/index.js';\nimport type { Base } from '../index.js';\nimport { features } from '../features.js';\n\ntype OptionType =\n | StringConstructor\n | NumberConstructor\n | BooleanConstructor\n | ArrayConstructor\n | ObjectConstructor;\n\ntype ArrayOption = {\n type: ArrayConstructor;\n default?: (instance: Base) => unknown[];\n merge?: boolean | DeepmergeOptions;\n};\n\ntype ObjectOption = {\n type: ObjectConstructor;\n default?: (instance: Base) => unknown;\n merge?: boolean | DeepmergeOptions;\n};\n\ntype StringOption = {\n type: StringConstructor;\n default?: string | ((instance: Base) => string);\n};\n\ntype NumberOption = {\n type: NumberConstructor;\n default?: number | ((instance: Base) => number);\n};\n\ntype BooleanOption = {\n type: BooleanConstructor;\n default?: boolean | ((instance: Base) => boolean);\n};\n\nexport type OptionObject = ArrayOption | ObjectOption | StringOption | NumberOption | BooleanOption;\nexport type OptionsSchema = { [name: string]: OptionType | OptionObject };\nexport type OptionsInterface = { [optionName: string]: unknown };\n\n/**\n * List of allowed types.\n */\nconst types: Set<OptionType> = new Set([String, Number, Boolean, Array, Object]);\n\n/**\n * The default values to return for each available type.\n */\nconst __defaultValues = {\n String: '',\n Number: 0,\n Boolean: false,\n Array: () => [],\n Object: () => ({}),\n};\n\nconst UPPERCASE_REGEX = /([A-Z])/g;\n\n/**\n * Get a property name.\n */\nexport const __getPropertyName = memo(function __getPropertyName(name: string, prefix = '') {\n const attributes = features.get('attributes');\n const propertyName = `${attributes.option}${prefix ? `-${prefix}` : ''}-${name.replaceAll(UPPERCASE_REGEX, '-$1')}`;\n return propertyName;\n});\n\n/**\n * Register an option.\n *\n * @param {OptionsManager} that\n * @param {string} name\n * @param {OptionObject} config\n * @returns {void}\n * @private\n */\nfunction __register(that: OptionsManager, name: string, config: OptionObject) {\n if (!types.has(config.type)) {\n if (isDev) {\n throw new Error(\n `The \"${name}\" option has an invalid type. The allowed types are: String, Number, Boolean, Array and Object.`,\n );\n }\n return;\n }\n\n config.default = config.default ?? __defaultValues[config.type.name];\n\n if ((config.type === Array || config.type === Object) && !isFunction(config.default)) {\n if (isDev) {\n throw new Error(\n `The default value for options of type \"${config.type.name}\" must be returned by a function.`,\n );\n }\n return;\n }\n\n Object.defineProperty(that, name, {\n get: () => that.get(name, config),\n set: (value) => {\n that.set(name, value, config);\n },\n enumerable: true,\n });\n}\n\n/**\n * Class options to manage options as data attributes on an HTML element.\n *\n * @todo Use `MutationObserver` to update values? Might be more performant.\n */\nexport class OptionsManager extends AbstractManager {\n /**\n * An object to store Array and Object values for reference.\n *\n * @private\n */\n __values = {};\n\n /**\n * Default value for the name property.\n */\n name = 'Base';\n\n /**\n * Default value for the debug property.\n */\n debug = false;\n\n /**\n * Default value for the log property.\n */\n log = false;\n\n /**\n * Class constructor.\n */\n constructor(base: Base) {\n super(base);\n\n this.__hideProperties(['__values', '__defaultValues']);\n const schema: OptionsSchema = this.__config.options || {};\n this.name = this.__config.name;\n\n schema.debug = {\n type: Boolean,\n default: this.__config.debug ?? false,\n };\n\n schema.log = {\n type: Boolean,\n default: this.__config.log ?? false,\n };\n\n for (const [name, config] of Object.entries(schema)) {\n __register(\n this,\n name,\n types.has(config as OptionType)\n ? ({ type: config as OptionType } as OptionObject)\n : (config as OptionObject),\n );\n }\n }\n\n /**\n * Get an option value.\n */\n get(name: string, config: OptionObject) {\n const { type } = config;\n const defaultValue = isFunction(config.default) ? config.default(this.__base) : config.default;\n const propertyName = __getPropertyName(name);\n const hasProperty = this.__element.hasAttribute(propertyName);\n\n if (type === Boolean) {\n if (defaultValue) {\n const negatedPropertyName = __getPropertyName(name, 'no');\n const hasNegatedProperty = this.__element.hasAttribute(negatedPropertyName);\n\n return !hasNegatedProperty;\n }\n\n return hasProperty || defaultValue;\n }\n\n const value = this.__element.getAttribute(propertyName);\n\n if (type === Number) {\n return hasProperty ? Number(value) : defaultValue;\n }\n\n if (type === Array || type === Object) {\n // eslint-disable-next-line no-param-reassign\n config = type === Array ? (config as ArrayOption) : (config as ObjectOption);\n\n if (!this.__values[name]) {\n let val = hasProperty ? JSON.parse(value) : defaultValue;\n\n if (isDefined(config.merge)) {\n val = isBoolean(config.merge)\n ? deepmerge(defaultValue, val)\n : deepmerge(defaultValue, val, config.merge);\n }\n\n this.__values[name] = val;\n }\n\n return this.__values[name];\n }\n\n return hasProperty ? value : defaultValue;\n }\n\n /**\n * Set an option value.\n */\n set(name: string, value: unknown, config: OptionObject) {\n const { type, default: defaultValue } = config;\n const propertyName = __getPropertyName(name);\n\n if (value.constructor.name !== type.name) {\n if (isDev) {\n const val = isArray(value) || isObject(value) ? JSON.stringify(value) : value;\n throw new TypeError(\n `The \"${val}\" value for the \"${name}\" option must be of type \"${type.name}\"`,\n );\n }\n return;\n }\n\n switch (type) {\n case Boolean:\n if (defaultValue) {\n const negatedPropertyName = __getPropertyName(name, 'no');\n\n if (value) {\n this.__element.removeAttribute(negatedPropertyName);\n } else {\n this.__element.setAttribute(negatedPropertyName, '');\n }\n } else if (value) {\n this.__element.setAttribute(propertyName, '');\n } else {\n this.__element.removeAttribute(propertyName);\n }\n break;\n case Array:\n case Object:\n this.__values[name] = value;\n break;\n default:\n this.__element.setAttribute(propertyName, value as string);\n }\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["__getPropertyName"]
7
7
  }
@@ -2,7 +2,7 @@ import { AbstractManager } from './AbstractManager.js';
2
2
  /**
3
3
  * Normalize the name of ref.
4
4
  */
5
- export declare function normalizeRefName(name: string): any;
5
+ export declare const normalizeRefName: (name: string) => string;
6
6
  /**
7
7
  * Refs Manager
8
8
  *
@@ -4,16 +4,14 @@ import {
4
4
  isArray,
5
5
  getAncestorWhereUntil,
6
6
  endsWith,
7
- startsWith
7
+ startsWith,
8
+ memo,
9
+ camelCase
8
10
  } from "../../utils/index.js";
9
11
  import { features } from "../features.js";
10
12
  const NORMALIZE_REF_NAME_REGEX = /\[\]$/;
11
13
  const NAMESPACED_REF_REGEX = /^(.*\.)/;
12
- const normalizedRefNamesCache = /* @__PURE__ */ new Map();
13
- function normalizeRefName(name) {
14
- if (normalizedRefNamesCache.has(name)) {
15
- return normalizedRefNamesCache.get(name);
16
- }
14
+ const normalizeRefName = memo(function normalizeRefName2(name) {
17
15
  let normalizedName = name;
18
16
  if (endsWith(name, "[]")) {
19
17
  normalizedName = normalizedName.replace(NORMALIZE_REF_NAME_REGEX, "");
@@ -21,9 +19,8 @@ function normalizeRefName(name) {
21
19
  if (normalizedName.includes(".")) {
22
20
  return normalizedName.replace(NAMESPACED_REF_REGEX, "");
23
21
  }
24
- normalizedRefNamesCache.set(name, normalizedName);
25
22
  return normalizedName;
26
- }
23
+ });
27
24
  function refBelongToInstance(ref, rootElement, name) {
28
25
  const attributes = features.get("attributes");
29
26
  const isPrefixed = startsWith(ref.getAttribute(attributes.ref), name);
@@ -54,7 +51,7 @@ function __register(that, refName) {
54
51
  if (refs.length) {
55
52
  that.__eventsManager.bindRef(refName, refs);
56
53
  }
57
- Object.defineProperty(that, propName, {
54
+ Object.defineProperty(that, camelCase(propName), {
58
55
  // @todo remove usage of non-multiple refs as array
59
56
  value: isMultiple || refs.length > 1 ? refs : refs[0],
60
57
  enumerable: true,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../packages/js-toolkit/Base/managers/RefsManager.ts"],
4
- "sourcesContent": ["import { AbstractManager } from './AbstractManager.js';\nimport {\n isDev,\n isArray,\n isDefined,\n getAncestorWhereUntil,\n endsWith,\n startsWith,\n} from '../../utils/index.js';\nimport { features } from '../features.js';\n\nconst NORMALIZE_REF_NAME_REGEX = /\\[\\]$/;\nconst NAMESPACED_REF_REGEX = /^(.*\\.)/;\nconst normalizedRefNamesCache = new Map();\n\n/**\n * Normalize the name of ref.\n */\nexport function normalizeRefName(name: string) {\n if (normalizedRefNamesCache.has(name)) {\n return normalizedRefNamesCache.get(name);\n }\n\n let normalizedName = name;\n\n if (endsWith(name, '[]')) {\n normalizedName = normalizedName.replace(NORMALIZE_REF_NAME_REGEX, '');\n }\n\n if (normalizedName.includes('.')) {\n return normalizedName.replace(NAMESPACED_REF_REGEX, '');\n }\n\n normalizedRefNamesCache.set(name, normalizedName);\n return normalizedName;\n}\n\n/**\n * Filter refs belonging to the related Base instance.\n */\nfunction refBelongToInstance(ref: HTMLElement, rootElement: HTMLElement, name: string) {\n const attributes = features.get('attributes');\n const isPrefixed = startsWith(ref.getAttribute(attributes.ref), name);\n const firstComponentAncestor = getAncestorWhereUntil(\n ref,\n (el) =>\n el &&\n (isPrefixed\n ? el.getAttribute(attributes.component) === name && el\n : el.getAttribute(attributes.component)) &&\n el !== rootElement,\n (el) => el === rootElement,\n );\n\n return firstComponentAncestor === rootElement;\n}\n\n/**\n * Register one ref.\n *\n * @param {RefsManager} that\n * @param {string} refName The ref name.\n * @private\n */\nfunction __register(that: RefsManager, refName: string) {\n const isMultiple = endsWith(refName, '[]');\n const propName = normalizeRefName(refName);\n const { name } = that.__base.$options;\n const attributes = features.get('attributes');\n\n const refs = Array.from(\n that.__element.querySelectorAll<HTMLElement>(\n `[${attributes.ref}=\"${refName}\"],[${attributes.ref}=\"${name}.${refName}\"]`,\n ),\n ).filter((ref) => refBelongToInstance(ref, that.__element, name));\n\n /* v8 ignore next 7 */\n if (isDev && !isMultiple && refs.length > 1) {\n console.warn(\n `[${that.__base.$id}]`,\n `The \"${refName}\" ref has been found multiple times.`,\n 'Did you forgot to add the `[]` suffix to its name?',\n );\n }\n\n if (refs.length) {\n that.__eventsManager.bindRef(refName, refs);\n }\n\n Object.defineProperty(that, propName, {\n // @todo remove usage of non-multiple refs as array\n value: isMultiple || refs.length > 1 ? refs : refs[0],\n enumerable: true,\n configurable: true,\n });\n}\n\n/**\n * Unregister one ref.\n */\nfunction __unregister(that: RefsManager, refName: string) {\n const propName = normalizeRefName(refName);\n const refs = isArray(that[propName]) ? that[propName] : [that[propName]];\n that.__eventsManager.unbindRef(refName, refs);\n}\n\n/**\n * Refs Manager\n *\n * @todo Use `MutationObserver` to automatically update refs?\n */\nexport class RefsManager extends AbstractManager {\n /**\n * Get refs configuration.\n */\n get __refs() {\n return this.__config.refs ?? [];\n }\n\n /**\n * Register all refs.\n */\n registerAll() {\n for (const refName of this.__refs) __register(this, refName);\n }\n\n /**\n * Unregister all refs.\n */\n unregisterAll() {\n for (const refName of this.__refs) __unregister(this, refName);\n }\n}\n"],
5
- "mappings": "AAAA,SAAS,uBAAuB;AAChC;AAAA,EACE;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,gBAAgB;AAEzB,MAAM,2BAA2B;AACjC,MAAM,uBAAuB;AAC7B,MAAM,0BAA0B,oBAAI,IAAI;AAKjC,SAAS,iBAAiB,MAAc;AAC7C,MAAI,wBAAwB,IAAI,IAAI,GAAG;AACrC,WAAO,wBAAwB,IAAI,IAAI;AAAA,EACzC;AAEA,MAAI,iBAAiB;AAErB,MAAI,SAAS,MAAM,IAAI,GAAG;AACxB,qBAAiB,eAAe,QAAQ,0BAA0B,EAAE;AAAA,EACtE;AAEA,MAAI,eAAe,SAAS,GAAG,GAAG;AAChC,WAAO,eAAe,QAAQ,sBAAsB,EAAE;AAAA,EACxD;AAEA,0BAAwB,IAAI,MAAM,cAAc;AAChD,SAAO;AACT;AAKA,SAAS,oBAAoB,KAAkB,aAA0B,MAAc;AACrF,QAAM,aAAa,SAAS,IAAI,YAAY;AAC5C,QAAM,aAAa,WAAW,IAAI,aAAa,WAAW,GAAG,GAAG,IAAI;AACpE,QAAM,yBAAyB;AAAA,IAC7B;AAAA,IACA,CAAC,OACC,OACC,aACG,GAAG,aAAa,WAAW,SAAS,MAAM,QAAQ,KAClD,GAAG,aAAa,WAAW,SAAS,MACxC,OAAO;AAAA,IACT,CAAC,OAAO,OAAO;AAAA,EACjB;AAEA,SAAO,2BAA2B;AACpC;AASA,SAAS,WAAW,MAAmB,SAAiB;AACtD,QAAM,aAAa,SAAS,SAAS,IAAI;AACzC,QAAM,WAAW,iBAAiB,OAAO;AACzC,QAAM,EAAE,KAAK,IAAI,KAAK,OAAO;AAC7B,QAAM,aAAa,SAAS,IAAI,YAAY;AAE5C,QAAM,OAAO,MAAM;AAAA,IACjB,KAAK,UAAU;AAAA,MACb,IAAI,WAAW,GAAG,KAAK,OAAO,OAAO,WAAW,GAAG,KAAK,IAAI,IAAI,OAAO;AAAA,IACzE;AAAA,EACF,EAAE,OAAO,CAAC,QAAQ,oBAAoB,KAAK,KAAK,WAAW,IAAI,CAAC;AAGhE,MAAI,SAAS,CAAC,cAAc,KAAK,SAAS,GAAG;AAC3C,YAAQ;AAAA,MACN,IAAI,KAAK,OAAO,GAAG;AAAA,MACnB,QAAQ,OAAO;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAEA,MAAI,KAAK,QAAQ;AACf,SAAK,gBAAgB,QAAQ,SAAS,IAAI;AAAA,EAC5C;AAEA,SAAO,eAAe,MAAM,UAAU;AAAA;AAAA,IAEpC,OAAO,cAAc,KAAK,SAAS,IAAI,OAAO,KAAK,CAAC;AAAA,IACpD,YAAY;AAAA,IACZ,cAAc;AAAA,EAChB,CAAC;AACH;AAKA,SAAS,aAAa,MAAmB,SAAiB;AACxD,QAAM,WAAW,iBAAiB,OAAO;AACzC,QAAM,OAAO,QAAQ,KAAK,QAAQ,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,KAAK,QAAQ,CAAC;AACvE,OAAK,gBAAgB,UAAU,SAAS,IAAI;AAC9C;AAOO,MAAM,oBAAoB,gBAAgB;AAAA;AAAA;AAAA;AAAA,EAI/C,IAAI,SAAS;AACX,WAAO,KAAK,SAAS,QAAQ,CAAC;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc;AACZ,eAAW,WAAW,KAAK,OAAQ,YAAW,MAAM,OAAO;AAAA,EAC7D;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAgB;AACd,eAAW,WAAW,KAAK,OAAQ,cAAa,MAAM,OAAO;AAAA,EAC/D;AACF;",
6
- "names": []
4
+ "sourcesContent": ["import { AbstractManager } from './AbstractManager.js';\nimport {\n isDev,\n isArray,\n isDefined,\n getAncestorWhereUntil,\n endsWith,\n startsWith,\n memo,\n camelCase,\n} from '../../utils/index.js';\nimport { features } from '../features.js';\n\nconst NORMALIZE_REF_NAME_REGEX = /\\[\\]$/;\nconst NAMESPACED_REF_REGEX = /^(.*\\.)/;\n\n/**\n * Normalize the name of ref.\n */\nexport const normalizeRefName = memo(function normalizeRefName(name: string) {\n let normalizedName = name;\n\n if (endsWith(name, '[]')) {\n normalizedName = normalizedName.replace(NORMALIZE_REF_NAME_REGEX, '');\n }\n\n if (normalizedName.includes('.')) {\n return normalizedName.replace(NAMESPACED_REF_REGEX, '');\n }\n\n return normalizedName;\n});\n\n/**\n * Filter refs belonging to the related Base instance.\n */\nfunction refBelongToInstance(ref: HTMLElement, rootElement: HTMLElement, name: string) {\n const attributes = features.get('attributes');\n const isPrefixed = startsWith(ref.getAttribute(attributes.ref), name);\n const firstComponentAncestor = getAncestorWhereUntil(\n ref,\n (el) =>\n el &&\n (isPrefixed\n ? el.getAttribute(attributes.component) === name && el\n : el.getAttribute(attributes.component)) &&\n el !== rootElement,\n (el) => el === rootElement,\n );\n\n return firstComponentAncestor === rootElement;\n}\n\n/**\n * Register one ref.\n *\n * @param {RefsManager} that\n * @param {string} refName The ref name.\n * @private\n */\nfunction __register(that: RefsManager, refName: string) {\n const isMultiple = endsWith(refName, '[]');\n const propName = normalizeRefName(refName);\n const { name } = that.__base.$options;\n const attributes = features.get('attributes');\n\n const refs = Array.from(\n that.__element.querySelectorAll<HTMLElement>(\n `[${attributes.ref}=\"${refName}\"],[${attributes.ref}=\"${name}.${refName}\"]`,\n ),\n ).filter((ref) => refBelongToInstance(ref, that.__element, name));\n\n /* v8 ignore next 7 */\n if (isDev && !isMultiple && refs.length > 1) {\n console.warn(\n `[${that.__base.$id}]`,\n `The \"${refName}\" ref has been found multiple times.`,\n 'Did you forgot to add the `[]` suffix to its name?',\n );\n }\n\n if (refs.length) {\n that.__eventsManager.bindRef(refName, refs);\n }\n\n Object.defineProperty(that, camelCase(propName), {\n // @todo remove usage of non-multiple refs as array\n value: isMultiple || refs.length > 1 ? refs : refs[0],\n enumerable: true,\n configurable: true,\n });\n}\n\n/**\n * Unregister one ref.\n */\nfunction __unregister(that: RefsManager, refName: string) {\n const propName = normalizeRefName(refName);\n const refs = isArray(that[propName]) ? that[propName] : [that[propName]];\n that.__eventsManager.unbindRef(refName, refs);\n}\n\n/**\n * Refs Manager\n *\n * @todo Use `MutationObserver` to automatically update refs?\n */\nexport class RefsManager extends AbstractManager {\n /**\n * Get refs configuration.\n */\n get __refs() {\n return this.__config.refs ?? [];\n }\n\n /**\n * Register all refs.\n */\n registerAll() {\n for (const refName of this.__refs) __register(this, refName);\n }\n\n /**\n * Unregister all refs.\n */\n unregisterAll() {\n for (const refName of this.__refs) __unregister(this, refName);\n }\n}\n"],
5
+ "mappings": "AAAA,SAAS,uBAAuB;AAChC;AAAA,EACE;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,gBAAgB;AAEzB,MAAM,2BAA2B;AACjC,MAAM,uBAAuB;AAKtB,MAAM,mBAAmB,KAAK,SAASA,kBAAiB,MAAc;AAC3E,MAAI,iBAAiB;AAErB,MAAI,SAAS,MAAM,IAAI,GAAG;AACxB,qBAAiB,eAAe,QAAQ,0BAA0B,EAAE;AAAA,EACtE;AAEA,MAAI,eAAe,SAAS,GAAG,GAAG;AAChC,WAAO,eAAe,QAAQ,sBAAsB,EAAE;AAAA,EACxD;AAEA,SAAO;AACT,CAAC;AAKD,SAAS,oBAAoB,KAAkB,aAA0B,MAAc;AACrF,QAAM,aAAa,SAAS,IAAI,YAAY;AAC5C,QAAM,aAAa,WAAW,IAAI,aAAa,WAAW,GAAG,GAAG,IAAI;AACpE,QAAM,yBAAyB;AAAA,IAC7B;AAAA,IACA,CAAC,OACC,OACC,aACG,GAAG,aAAa,WAAW,SAAS,MAAM,QAAQ,KAClD,GAAG,aAAa,WAAW,SAAS,MACxC,OAAO;AAAA,IACT,CAAC,OAAO,OAAO;AAAA,EACjB;AAEA,SAAO,2BAA2B;AACpC;AASA,SAAS,WAAW,MAAmB,SAAiB;AACtD,QAAM,aAAa,SAAS,SAAS,IAAI;AACzC,QAAM,WAAW,iBAAiB,OAAO;AACzC,QAAM,EAAE,KAAK,IAAI,KAAK,OAAO;AAC7B,QAAM,aAAa,SAAS,IAAI,YAAY;AAE5C,QAAM,OAAO,MAAM;AAAA,IACjB,KAAK,UAAU;AAAA,MACb,IAAI,WAAW,GAAG,KAAK,OAAO,OAAO,WAAW,GAAG,KAAK,IAAI,IAAI,OAAO;AAAA,IACzE;AAAA,EACF,EAAE,OAAO,CAAC,QAAQ,oBAAoB,KAAK,KAAK,WAAW,IAAI,CAAC;AAGhE,MAAI,SAAS,CAAC,cAAc,KAAK,SAAS,GAAG;AAC3C,YAAQ;AAAA,MACN,IAAI,KAAK,OAAO,GAAG;AAAA,MACnB,QAAQ,OAAO;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAEA,MAAI,KAAK,QAAQ;AACf,SAAK,gBAAgB,QAAQ,SAAS,IAAI;AAAA,EAC5C;AAEA,SAAO,eAAe,MAAM,UAAU,QAAQ,GAAG;AAAA;AAAA,IAE/C,OAAO,cAAc,KAAK,SAAS,IAAI,OAAO,KAAK,CAAC;AAAA,IACpD,YAAY;AAAA,IACZ,cAAc;AAAA,EAChB,CAAC;AACH;AAKA,SAAS,aAAa,MAAmB,SAAiB;AACxD,QAAM,WAAW,iBAAiB,OAAO;AACzC,QAAM,OAAO,QAAQ,KAAK,QAAQ,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,KAAK,QAAQ,CAAC;AACvE,OAAK,gBAAgB,UAAU,SAAS,IAAI;AAC9C;AAOO,MAAM,oBAAoB,gBAAgB;AAAA;AAAA;AAAA;AAAA,EAI/C,IAAI,SAAS;AACX,WAAO,KAAK,SAAS,QAAQ,CAAC;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc;AACZ,eAAW,WAAW,KAAK,OAAQ,YAAW,MAAM,OAAO;AAAA,EAC7D;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAgB;AACd,eAAW,WAAW,KAAK,OAAQ,cAAa,MAAM,OAAO;AAAA,EAC/D;AACF;",
6
+ "names": ["normalizeRefName"]
7
7
  }
@@ -8,8 +8,8 @@ function __getResponsiveName(that, name) {
8
8
  return name;
9
9
  }
10
10
  let responsiveName = name;
11
- const propertyName = __getPropertyName(name);
12
- const regex = new RegExp(`${propertyName}:(.+)$`);
11
+ const propertyName = __getPropertyName(name).toLowerCase();
12
+ const regex = new RegExp(`${propertyName}:(.+)$`, "i");
13
13
  const attributes = features.get("attributes");
14
14
  const dataOptionRegExp = new RegExp(`^${attributes.option}-`);
15
15
  for (const optionName of that.__element.getAttributeNames()) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../packages/js-toolkit/Base/managers/ResponsiveOptionsManager.ts"],
4
- "sourcesContent": ["import { OptionsManager, __getPropertyName } from './OptionsManager.js';\nimport type { OptionObject } from './OptionsManager.js';\nimport { useResize } from '../../services/index.js';\nimport { isDev } from '../../utils/index.js';\nimport { features } from '../features.js';\n\nexport type ResponsiveOptionObject = OptionObject & { responsive?: boolean };\n\n/**\n * Get the currently active responsive name of an option.\n *\n * @param {ResponsiveOptionsManager} that\n * @param {string} name The default name of the option.\n * @returns {string} The responsive name if one matches the current breakpoint, the default name otherwise.\n */\nfunction __getResponsiveName(that: ResponsiveOptionsManager, name: string) {\n const { breakpoint } = useResize().props();\n\n if (!breakpoint) {\n return name;\n }\n\n let responsiveName = name;\n const propertyName = __getPropertyName(name);\n const regex = new RegExp(`${propertyName}:(.+)$`);\n const attributes = features.get('attributes');\n const dataOptionRegExp = new RegExp(`^${attributes.option}-`);\n\n for (const optionName of that.__element.getAttributeNames()) {\n if (regex.test(optionName)) {\n const [, breakpoints] = optionName.match(regex);\n const isInBreakpoint = breakpoints.split(':').includes(breakpoint);\n if (isInBreakpoint) {\n responsiveName = optionName.replace(dataOptionRegExp, '');\n }\n }\n }\n\n return responsiveName;\n}\n\n/**\n * Class options to manage options as data attributes on an HTML element.\n */\nexport class ResponsiveOptionsManager extends OptionsManager {\n /**\n * Get an option value.\n *\n * @param {string} name The option name.\n * @param {ResponsiveOptionObject} config The option configuration.\n * @returns {any}\n */\n get(name: string, config: ResponsiveOptionObject) {\n if (!config.responsive) {\n return super.get(name, config);\n }\n\n return super.get(__getResponsiveName(this, name), config);\n }\n\n /**\n * Set an option value.\n *\n * @param {string} name The option name.\n * @param {any} value The new value.\n * @param {ResponsiveOptionObject} config The option configuration.\n */\n set(name: string, value: unknown, config: ResponsiveOptionObject) {\n if (!config.responsive) {\n super.set(name, value, config);\n return;\n }\n\n if (isDev) {\n console.warn(`[${this.__config.name}]`, 'Responsive options are read-only.');\n }\n }\n}\n"],
5
- "mappings": "AAAA,SAAS,gBAAgB,yBAAyB;AAElD,SAAS,iBAAiB;AAC1B,SAAS,aAAa;AACtB,SAAS,gBAAgB;AAWzB,SAAS,oBAAoB,MAAgC,MAAc;AACzE,QAAM,EAAE,WAAW,IAAI,UAAU,EAAE,MAAM;AAEzC,MAAI,CAAC,YAAY;AACf,WAAO;AAAA,EACT;AAEA,MAAI,iBAAiB;AACrB,QAAM,eAAe,kBAAkB,IAAI;AAC3C,QAAM,QAAQ,IAAI,OAAO,GAAG,YAAY,QAAQ;AAChD,QAAM,aAAa,SAAS,IAAI,YAAY;AAC5C,QAAM,mBAAmB,IAAI,OAAO,IAAI,WAAW,MAAM,GAAG;AAE5D,aAAW,cAAc,KAAK,UAAU,kBAAkB,GAAG;AAC3D,QAAI,MAAM,KAAK,UAAU,GAAG;AAC1B,YAAM,CAAC,EAAE,WAAW,IAAI,WAAW,MAAM,KAAK;AAC9C,YAAM,iBAAiB,YAAY,MAAM,GAAG,EAAE,SAAS,UAAU;AACjE,UAAI,gBAAgB;AAClB,yBAAiB,WAAW,QAAQ,kBAAkB,EAAE;AAAA,MAC1D;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAKO,MAAM,iCAAiC,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQ3D,IAAI,MAAc,QAAgC;AAChD,QAAI,CAAC,OAAO,YAAY;AACtB,aAAO,MAAM,IAAI,MAAM,MAAM;AAAA,IAC/B;AAEA,WAAO,MAAM,IAAI,oBAAoB,MAAM,IAAI,GAAG,MAAM;AAAA,EAC1D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,IAAI,MAAc,OAAgB,QAAgC;AAChE,QAAI,CAAC,OAAO,YAAY;AACtB,YAAM,IAAI,MAAM,OAAO,MAAM;AAC7B;AAAA,IACF;AAEA,QAAI,OAAO;AACT,cAAQ,KAAK,IAAI,KAAK,SAAS,IAAI,KAAK,mCAAmC;AAAA,IAC7E;AAAA,EACF;AACF;",
4
+ "sourcesContent": ["import { OptionsManager, __getPropertyName } from './OptionsManager.js';\nimport type { OptionObject } from './OptionsManager.js';\nimport { useResize } from '../../services/index.js';\nimport { isDev } from '../../utils/index.js';\nimport { features } from '../features.js';\n\nexport type ResponsiveOptionObject = OptionObject & { responsive?: boolean };\n\n/**\n * Get the currently active responsive name of an option.\n *\n * @param {ResponsiveOptionsManager} that\n * @param {string} name The default name of the option.\n * @returns {string} The responsive name if one matches the current breakpoint, the default name otherwise.\n */\nfunction __getResponsiveName(that: ResponsiveOptionsManager, name: string) {\n const { breakpoint } = useResize().props();\n\n if (!breakpoint) {\n return name;\n }\n\n let responsiveName = name;\n const propertyName = __getPropertyName(name).toLowerCase();\n const regex = new RegExp(`${propertyName}:(.+)$`, 'i');\n const attributes = features.get('attributes');\n const dataOptionRegExp = new RegExp(`^${attributes.option}-`);\n\n for (const optionName of that.__element.getAttributeNames()) {\n if (regex.test(optionName)) {\n const [, breakpoints] = optionName.match(regex);\n const isInBreakpoint = breakpoints.split(':').includes(breakpoint);\n if (isInBreakpoint) {\n responsiveName = optionName.replace(dataOptionRegExp, '');\n }\n }\n }\n\n return responsiveName;\n}\n\n/**\n * Class options to manage options as data attributes on an HTML element.\n */\nexport class ResponsiveOptionsManager extends OptionsManager {\n /**\n * Get an option value.\n *\n * @param {string} name The option name.\n * @param {ResponsiveOptionObject} config The option configuration.\n * @returns {any}\n */\n get(name: string, config: ResponsiveOptionObject) {\n if (!config.responsive) {\n return super.get(name, config);\n }\n\n return super.get(__getResponsiveName(this, name), config);\n }\n\n /**\n * Set an option value.\n *\n * @param {string} name The option name.\n * @param {any} value The new value.\n * @param {ResponsiveOptionObject} config The option configuration.\n */\n set(name: string, value: unknown, config: ResponsiveOptionObject) {\n if (!config.responsive) {\n super.set(name, value, config);\n return;\n }\n\n if (isDev) {\n console.warn(`[${this.__config.name}]`, 'Responsive options are read-only.');\n }\n }\n}\n"],
5
+ "mappings": "AAAA,SAAS,gBAAgB,yBAAyB;AAElD,SAAS,iBAAiB;AAC1B,SAAS,aAAa;AACtB,SAAS,gBAAgB;AAWzB,SAAS,oBAAoB,MAAgC,MAAc;AACzE,QAAM,EAAE,WAAW,IAAI,UAAU,EAAE,MAAM;AAEzC,MAAI,CAAC,YAAY;AACf,WAAO;AAAA,EACT;AAEA,MAAI,iBAAiB;AACrB,QAAM,eAAe,kBAAkB,IAAI,EAAE,YAAY;AACzD,QAAM,QAAQ,IAAI,OAAO,GAAG,YAAY,UAAU,GAAG;AACrD,QAAM,aAAa,SAAS,IAAI,YAAY;AAC5C,QAAM,mBAAmB,IAAI,OAAO,IAAI,WAAW,MAAM,GAAG;AAE5D,aAAW,cAAc,KAAK,UAAU,kBAAkB,GAAG;AAC3D,QAAI,MAAM,KAAK,UAAU,GAAG;AAC1B,YAAM,CAAC,EAAE,WAAW,IAAI,WAAW,MAAM,KAAK;AAC9C,YAAM,iBAAiB,YAAY,MAAM,GAAG,EAAE,SAAS,UAAU;AACjE,UAAI,gBAAgB;AAClB,yBAAiB,WAAW,QAAQ,kBAAkB,EAAE;AAAA,MAC1D;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAKO,MAAM,iCAAiC,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQ3D,IAAI,MAAc,QAAgC;AAChD,QAAI,CAAC,OAAO,YAAY;AACtB,aAAO,MAAM,IAAI,MAAM,MAAM;AAAA,IAC/B;AAEA,WAAO,MAAM,IAAI,oBAAoB,MAAM,IAAI,GAAG,MAAM;AAAA,EAC1D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,IAAI,MAAc,OAAgB,QAAgC;AAChE,QAAI,CAAC,OAAO,YAAY;AACtB,YAAM,IAAI,MAAM,OAAO,MAAM;AAC7B;AAAA,IACF;AAEA,QAAI,OAAO;AACT,cAAQ,KAAK,IAAI,KAAK,SAAS,IAAI,KAAK,mCAAmC;AAAA,IAC7E;AAAA,EACF;AACF;",
6
6
  "names": []
7
7
  }
package/Base/utils.js CHANGED
@@ -1,4 +1,4 @@
1
- import { isArray, isDefined, isDev, SmartQueue } from "../utils/index.js";
1
+ import { isArray, isDefined, SmartQueue } from "../utils/index.js";
2
2
  import { features } from "./features.js";
3
3
  let queue;
4
4
  function addToQueue(fn) {
@@ -56,14 +56,6 @@ function getEventTarget(instance, event, config) {
56
56
  if (eventIsNative(event, instance.$el)) {
57
57
  return instance.$el;
58
58
  }
59
- if (isDev) {
60
- console.warn(
61
- `[${config.name}]`,
62
- `The "${event}" event is missing from the configuration and is not a native`,
63
- `event for the root element of type \`${instance.$el.constructor.name}\`.`
64
- );
65
- }
66
- return instance;
67
59
  }
68
60
  const instances = /* @__PURE__ */ new Set();
69
61
  function getInstances(ctor) {
package/Base/utils.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../packages/js-toolkit/Base/utils.ts"],
4
- "sourcesContent": ["import { isArray, isDefined, isDev, SmartQueue } from '../utils/index.js';\nimport type { Base, BaseConfig, BaseConstructor } from './index.js';\nimport { features } from './features.js';\n\nlet queue: SmartQueue;\n\n/**\n * Add a task to the main queue.\n */\nexport function addToQueue(fn: () => unknown) {\n if (features.get('blocking')) {\n fn();\n return;\n }\n\n if (!queue) {\n queue = new SmartQueue();\n }\n\n return queue.add(fn);\n}\n\nconst selectors = new Map();\n\n// Separator used for multi-component declaration in `data-component` attributeS.\nconst separator = ' ';\n\n/**\n * Get the selector for a given component.\n */\nfunction getSelector(nameOrSelector: string): string {\n const { component } = features.get('attributes');\n const key = component + nameOrSelector;\n\n if (!selectors.has(key)) {\n const parts = [\n // Single selector\n `[${component}=\"${nameOrSelector}\"]`,\n // Selector in the middle of a list of selectors\n `[${component}*=\"${separator}${nameOrSelector}${separator}\"]`,\n // Selector at the end of a list of selectors\n `[${component}$=\"${separator}${nameOrSelector}\"]`,\n // Selector at the beginning of a list of selectors\n `[${component}^=\"${nameOrSelector}${separator}\"]`,\n ];\n selectors.set(key, parts.join(','));\n }\n\n return selectors.get(key);\n}\n\n/**\n * Get a list of elements based on the name of a component.\n *\n * @param {string} nameOrSelector\n * The name or selector to used for this component.\n * @param {HTMLElement|Document} element\n * The root element on which to query the selector, defaults to `document`.\n * @returns {Array<HTMLElement>}\n * A list of elements on which the component should be mounted.\n */\nexport function getComponentElements(\n nameOrSelector: string,\n element: HTMLElement | Document = document,\n): HTMLElement[] {\n const selector = getSelector(nameOrSelector);\n let elements = [];\n\n try {\n elements = Array.from(element.querySelectorAll(selector));\n // eslint-disable-next-line no-empty\n } catch {}\n\n // If no child component found with the default selector, and if the selector does not\n // start with an uppercase letter, matching a component's name, try a classic DOM selector.\n if (elements.length === 0 && nameOrSelector[0] === nameOrSelector[0].toLowerCase()) {\n elements = Array.from(element.querySelectorAll(nameOrSelector));\n }\n\n return elements;\n}\n\n/**\n * Test if an event is defined in the given config.\n */\nexport function eventIsDefinedInConfig(event: string, config: BaseConfig): boolean {\n return isArray(config.emits) && config.emits.includes(event);\n}\n\n/**\n * Test if an event can be used on the given element.\n */\nexport function eventIsNative(event: string, element: HTMLElement): boolean {\n return isDefined(element[`on${event}`]);\n}\n\n/**\n * Get the target of a given event.\n *\n * @todo Return false in v3 if event is not defined or not native to prevent adding a listener.\n */\nexport function getEventTarget(\n instance: Base,\n event: string,\n config: BaseConfig,\n): Base | Base['$el'] {\n if (eventIsDefinedInConfig(event, config)) {\n return instance;\n }\n\n if (eventIsNative(event, instance.$el)) {\n return instance.$el;\n }\n\n if (isDev) {\n console.warn(\n `[${config.name}]`,\n `The \"${event}\" event is missing from the configuration and is not a native`,\n `event for the root element of type \\`${instance.$el.constructor.name}\\`.`,\n );\n }\n\n // @todo v3 return false or null\n return instance;\n}\n\nconst instances = new Set<Base>();\n\n/**\n * Get all mounted instances or the ones from a given component.\n */\nexport function getInstances(): Set<Base>;\nexport function getInstances<T extends BaseConstructor = BaseConstructor>(\n ctor: T,\n): Set<InstanceType<T>>;\nexport function getInstances<T extends BaseConstructor = BaseConstructor>(\n ctor?: T,\n): Set<InstanceType<T>> | Set<Base> {\n if (isDefined(ctor)) {\n const filteredInstances = new Set<InstanceType<T>>();\n for (const instance of instances) {\n if (instance instanceof ctor) {\n filteredInstances.add(instance as InstanceType<T>);\n }\n }\n return filteredInstances;\n } else {\n return new Set(instances);\n }\n}\n\nexport function addInstance(instance: Base) {\n instances.add(instance);\n}\n\nexport function deleteInstance(instance: Base) {\n instances.delete(instance);\n}\n"],
5
- "mappings": "AAAA,SAAS,SAAS,WAAW,OAAO,kBAAkB;AAEtD,SAAS,gBAAgB;AAEzB,IAAI;AAKG,SAAS,WAAW,IAAmB;AAC5C,MAAI,SAAS,IAAI,UAAU,GAAG;AAC5B,OAAG;AACH;AAAA,EACF;AAEA,MAAI,CAAC,OAAO;AACV,YAAQ,IAAI,WAAW;AAAA,EACzB;AAEA,SAAO,MAAM,IAAI,EAAE;AACrB;AAEA,MAAM,YAAY,oBAAI,IAAI;AAG1B,MAAM,YAAY;AAKlB,SAAS,YAAY,gBAAgC;AACnD,QAAM,EAAE,UAAU,IAAI,SAAS,IAAI,YAAY;AAC/C,QAAM,MAAM,YAAY;AAExB,MAAI,CAAC,UAAU,IAAI,GAAG,GAAG;AACvB,UAAM,QAAQ;AAAA;AAAA,MAEZ,IAAI,SAAS,KAAK,cAAc;AAAA;AAAA,MAEhC,IAAI,SAAS,MAAM,SAAS,GAAG,cAAc,GAAG,SAAS;AAAA;AAAA,MAEzD,IAAI,SAAS,MAAM,SAAS,GAAG,cAAc;AAAA;AAAA,MAE7C,IAAI,SAAS,MAAM,cAAc,GAAG,SAAS;AAAA,IAC/C;AACA,cAAU,IAAI,KAAK,MAAM,KAAK,GAAG,CAAC;AAAA,EACpC;AAEA,SAAO,UAAU,IAAI,GAAG;AAC1B;AAYO,SAAS,qBACd,gBACA,UAAkC,UACnB;AACf,QAAM,WAAW,YAAY,cAAc;AAC3C,MAAI,WAAW,CAAC;AAEhB,MAAI;AACF,eAAW,MAAM,KAAK,QAAQ,iBAAiB,QAAQ,CAAC;AAAA,EAE1D,QAAQ;AAAA,EAAC;AAIT,MAAI,SAAS,WAAW,KAAK,eAAe,CAAC,MAAM,eAAe,CAAC,EAAE,YAAY,GAAG;AAClF,eAAW,MAAM,KAAK,QAAQ,iBAAiB,cAAc,CAAC;AAAA,EAChE;AAEA,SAAO;AACT;AAKO,SAAS,uBAAuB,OAAe,QAA6B;AACjF,SAAO,QAAQ,OAAO,KAAK,KAAK,OAAO,MAAM,SAAS,KAAK;AAC7D;AAKO,SAAS,cAAc,OAAe,SAA+B;AAC1E,SAAO,UAAU,QAAQ,KAAK,KAAK,EAAE,CAAC;AACxC;AAOO,SAAS,eACd,UACA,OACA,QACoB;AACpB,MAAI,uBAAuB,OAAO,MAAM,GAAG;AACzC,WAAO;AAAA,EACT;AAEA,MAAI,cAAc,OAAO,SAAS,GAAG,GAAG;AACtC,WAAO,SAAS;AAAA,EAClB;AAEA,MAAI,OAAO;AACT,YAAQ;AAAA,MACN,IAAI,OAAO,IAAI;AAAA,MACf,QAAQ,KAAK;AAAA,MACb,wCAAwC,SAAS,IAAI,YAAY,IAAI;AAAA,IACvE;AAAA,EACF;AAGA,SAAO;AACT;AAEA,MAAM,YAAY,oBAAI,IAAU;AASzB,SAAS,aACd,MACkC;AAClC,MAAI,UAAU,IAAI,GAAG;AACnB,UAAM,oBAAoB,oBAAI,IAAqB;AACnD,eAAW,YAAY,WAAW;AAChC,UAAI,oBAAoB,MAAM;AAC5B,0BAAkB,IAAI,QAA2B;AAAA,MACnD;AAAA,IACF;AACA,WAAO;AAAA,EACT,OAAO;AACL,WAAO,IAAI,IAAI,SAAS;AAAA,EAC1B;AACF;AAEO,SAAS,YAAY,UAAgB;AAC1C,YAAU,IAAI,QAAQ;AACxB;AAEO,SAAS,eAAe,UAAgB;AAC7C,YAAU,OAAO,QAAQ;AAC3B;",
4
+ "sourcesContent": ["import { isArray, isDefined, isDev, SmartQueue } from '../utils/index.js';\nimport type { Base, BaseConfig, BaseConstructor } from './index.js';\nimport { features } from './features.js';\n\nlet queue: SmartQueue;\n\n/**\n * Add a task to the main queue.\n */\nexport function addToQueue(fn: () => unknown) {\n if (features.get('blocking')) {\n fn();\n return;\n }\n\n if (!queue) {\n queue = new SmartQueue();\n }\n\n return queue.add(fn);\n}\n\nconst selectors = new Map();\n\n// Separator used for multi-component declaration in `data-component` attributeS.\nconst separator = ' ';\n\n/**\n * Get the selector for a given component.\n */\nfunction getSelector(nameOrSelector: string): string {\n const { component } = features.get('attributes');\n const key = component + nameOrSelector;\n\n if (!selectors.has(key)) {\n const parts = [\n // Single selector\n `[${component}=\"${nameOrSelector}\"]`,\n // Selector in the middle of a list of selectors\n `[${component}*=\"${separator}${nameOrSelector}${separator}\"]`,\n // Selector at the end of a list of selectors\n `[${component}$=\"${separator}${nameOrSelector}\"]`,\n // Selector at the beginning of a list of selectors\n `[${component}^=\"${nameOrSelector}${separator}\"]`,\n ];\n selectors.set(key, parts.join(','));\n }\n\n return selectors.get(key);\n}\n\n/**\n * Get a list of elements based on the name of a component.\n *\n * @param {string} nameOrSelector\n * The name or selector to used for this component.\n * @param {HTMLElement|Document} element\n * The root element on which to query the selector, defaults to `document`.\n * @returns {Array<HTMLElement>}\n * A list of elements on which the component should be mounted.\n */\nexport function getComponentElements(\n nameOrSelector: string,\n element: HTMLElement | Document = document,\n): HTMLElement[] {\n const selector = getSelector(nameOrSelector);\n let elements = [];\n\n try {\n elements = Array.from(element.querySelectorAll(selector));\n // eslint-disable-next-line no-empty\n } catch {}\n\n // If no child component found with the default selector, and if the selector does not\n // start with an uppercase letter, matching a component's name, try a classic DOM selector.\n if (elements.length === 0 && nameOrSelector[0] === nameOrSelector[0].toLowerCase()) {\n elements = Array.from(element.querySelectorAll(nameOrSelector));\n }\n\n return elements;\n}\n\n/**\n * Test if an event is defined in the given config.\n */\nexport function eventIsDefinedInConfig(event: string, config: BaseConfig): boolean {\n return isArray(config.emits) && config.emits.includes(event);\n}\n\n/**\n * Test if an event can be used on the given element.\n */\nexport function eventIsNative(event: string, element: HTMLElement): boolean {\n return isDefined(element[`on${event}`]);\n}\n\n/**\n * Get the target of a given event.\n *\n * @todo Return false in v3 if event is not defined or not native to prevent adding a listener.\n */\nexport function getEventTarget(\n instance: Base,\n event: string,\n config: BaseConfig,\n): Base | Base['$el'] {\n if (eventIsDefinedInConfig(event, config)) {\n return instance;\n }\n\n if (eventIsNative(event, instance.$el)) {\n return instance.$el;\n }\n}\n\nconst instances = new Set<Base>();\n\n/**\n * Get all mounted instances or the ones from a given component.\n */\nexport function getInstances(): Set<Base>;\nexport function getInstances<T extends BaseConstructor = BaseConstructor>(\n ctor: T,\n): Set<InstanceType<T>>;\nexport function getInstances<T extends BaseConstructor = BaseConstructor>(\n ctor?: T,\n): Set<InstanceType<T>> | Set<Base> {\n if (isDefined(ctor)) {\n const filteredInstances = new Set<InstanceType<T>>();\n for (const instance of instances) {\n if (instance instanceof ctor) {\n filteredInstances.add(instance as InstanceType<T>);\n }\n }\n return filteredInstances;\n } else {\n return new Set(instances);\n }\n}\n\nexport function addInstance(instance: Base) {\n instances.add(instance);\n}\n\nexport function deleteInstance(instance: Base) {\n instances.delete(instance);\n}\n"],
5
+ "mappings": "AAAA,SAAS,SAAS,WAAkB,kBAAkB;AAEtD,SAAS,gBAAgB;AAEzB,IAAI;AAKG,SAAS,WAAW,IAAmB;AAC5C,MAAI,SAAS,IAAI,UAAU,GAAG;AAC5B,OAAG;AACH;AAAA,EACF;AAEA,MAAI,CAAC,OAAO;AACV,YAAQ,IAAI,WAAW;AAAA,EACzB;AAEA,SAAO,MAAM,IAAI,EAAE;AACrB;AAEA,MAAM,YAAY,oBAAI,IAAI;AAG1B,MAAM,YAAY;AAKlB,SAAS,YAAY,gBAAgC;AACnD,QAAM,EAAE,UAAU,IAAI,SAAS,IAAI,YAAY;AAC/C,QAAM,MAAM,YAAY;AAExB,MAAI,CAAC,UAAU,IAAI,GAAG,GAAG;AACvB,UAAM,QAAQ;AAAA;AAAA,MAEZ,IAAI,SAAS,KAAK,cAAc;AAAA;AAAA,MAEhC,IAAI,SAAS,MAAM,SAAS,GAAG,cAAc,GAAG,SAAS;AAAA;AAAA,MAEzD,IAAI,SAAS,MAAM,SAAS,GAAG,cAAc;AAAA;AAAA,MAE7C,IAAI,SAAS,MAAM,cAAc,GAAG,SAAS;AAAA,IAC/C;AACA,cAAU,IAAI,KAAK,MAAM,KAAK,GAAG,CAAC;AAAA,EACpC;AAEA,SAAO,UAAU,IAAI,GAAG;AAC1B;AAYO,SAAS,qBACd,gBACA,UAAkC,UACnB;AACf,QAAM,WAAW,YAAY,cAAc;AAC3C,MAAI,WAAW,CAAC;AAEhB,MAAI;AACF,eAAW,MAAM,KAAK,QAAQ,iBAAiB,QAAQ,CAAC;AAAA,EAE1D,QAAQ;AAAA,EAAC;AAIT,MAAI,SAAS,WAAW,KAAK,eAAe,CAAC,MAAM,eAAe,CAAC,EAAE,YAAY,GAAG;AAClF,eAAW,MAAM,KAAK,QAAQ,iBAAiB,cAAc,CAAC;AAAA,EAChE;AAEA,SAAO;AACT;AAKO,SAAS,uBAAuB,OAAe,QAA6B;AACjF,SAAO,QAAQ,OAAO,KAAK,KAAK,OAAO,MAAM,SAAS,KAAK;AAC7D;AAKO,SAAS,cAAc,OAAe,SAA+B;AAC1E,SAAO,UAAU,QAAQ,KAAK,KAAK,EAAE,CAAC;AACxC;AAOO,SAAS,eACd,UACA,OACA,QACoB;AACpB,MAAI,uBAAuB,OAAO,MAAM,GAAG;AACzC,WAAO;AAAA,EACT;AAEA,MAAI,cAAc,OAAO,SAAS,GAAG,GAAG;AACtC,WAAO,SAAS;AAAA,EAClB;AACF;AAEA,MAAM,YAAY,oBAAI,IAAU;AASzB,SAAS,aACd,MACkC;AAClC,MAAI,UAAU,IAAI,GAAG;AACnB,UAAM,oBAAoB,oBAAI,IAAqB;AACnD,eAAW,YAAY,WAAW;AAChC,UAAI,oBAAoB,MAAM;AAC5B,0BAAkB,IAAI,QAA2B;AAAA,MACnD;AAAA,IACF;AACA,WAAO;AAAA,EACT,OAAO;AACL,WAAO,IAAI,IAAI,SAAS;AAAA,EAC1B;AACF;AAEO,SAAS,YAAY,UAAgB;AAC1C,YAAU,IAAI,QAAQ;AACxB;AAEO,SAAS,eAAe,UAAgB;AAC7C,YAAU,OAAO,QAAQ;AAC3B;",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@studiometa/js-toolkit",
3
- "version": "3.0.0-alpha.6",
3
+ "version": "3.0.0-alpha.7",
4
4
  "description": "A set of useful little bits of JavaScript to boost your project! 🚀",
5
5
  "publishConfig": {
6
6
  "access": "public"
package/utils/index.d.ts CHANGED
@@ -23,3 +23,4 @@ export { SmartQueue } from './SmartQueue.js';
23
23
  export * from './dom/index.js';
24
24
  export * from './wait.js';
25
25
  export * from './random.js';
26
+ export * from './memo.js';
package/utils/index.js CHANGED
@@ -27,6 +27,7 @@ import { SmartQueue } from "./SmartQueue.js";
27
27
  export * from "./dom/index.js";
28
28
  export * from "./wait.js";
29
29
  export * from "./random.js";
30
+ export * from "./memo.js";
30
31
  export {
31
32
  Queue,
32
33
  SmartQueue,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../packages/js-toolkit/utils/index.ts"],
4
- "sourcesContent": ["export { default as debounce } from './debounce.js';\nexport * from './trapFocus.js';\nexport { default as keyCodes } from './keyCodes.js';\nexport { default as memoize } from './memoize.js';\nexport { nextFrame } from './nextFrame.js';\nexport { nextTick } from './nextTick.js';\nexport { nextMicrotask } from './nextMicrotask.js';\nexport { default as throttle } from './throttle.js';\nexport { scrollTo } from './scrollTo.js';\nexport { default as getComponentResolver } from './getComponentResolver.js';\nexport * from './is.js';\nexport * from './has.js';\nexport * from './css/index.js';\nexport {\n objectToURLSearchParams,\n push as historyPush,\n replace as historyReplace,\n} from './history.js';\nexport * from './collide/index.js';\nexport * from './math/index.js';\nexport * from './string/index.js';\nexport * from './scheduler.js';\nexport * from './noop.js';\nexport { tween } from './tween.js';\nexport { Queue } from './Queue.js';\nexport { SmartQueue } from './SmartQueue.js';\nexport * from './dom/index.js';\nexport * from './wait.js';\nexport * from './random.js';\n"],
5
- "mappings": "AAAA,SAAoB,WAAXA,gBAA2B;AACpC,cAAc;AACd,SAAoB,WAAXA,gBAA2B;AACpC,SAAoB,WAAXA,gBAA0B;AACnC,SAAS,iBAAiB;AAC1B,SAAS,gBAAgB;AACzB,SAAS,qBAAqB;AAC9B,SAAoB,WAAXA,gBAA2B;AACpC,SAAS,gBAAgB;AACzB,SAAoB,WAAXA,gBAAuC;AAChD,cAAc;AACd,cAAc;AACd,cAAc;AACd;AAAA,EACE;AAAA,EACQ;AAAA,EACG;AAAA,OACN;AACP,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,SAAS,aAAa;AACtB,SAAS,aAAa;AACtB,SAAS,kBAAkB;AAC3B,cAAc;AACd,cAAc;AACd,cAAc;",
4
+ "sourcesContent": ["export { default as debounce } from './debounce.js';\nexport * from './trapFocus.js';\nexport { default as keyCodes } from './keyCodes.js';\nexport { default as memoize } from './memoize.js';\nexport { nextFrame } from './nextFrame.js';\nexport { nextTick } from './nextTick.js';\nexport { nextMicrotask } from './nextMicrotask.js';\nexport { default as throttle } from './throttle.js';\nexport { scrollTo } from './scrollTo.js';\nexport { default as getComponentResolver } from './getComponentResolver.js';\nexport * from './is.js';\nexport * from './has.js';\nexport * from './css/index.js';\nexport {\n objectToURLSearchParams,\n push as historyPush,\n replace as historyReplace,\n} from './history.js';\nexport * from './collide/index.js';\nexport * from './math/index.js';\nexport * from './string/index.js';\nexport * from './scheduler.js';\nexport * from './noop.js';\nexport { tween } from './tween.js';\nexport { Queue } from './Queue.js';\nexport { SmartQueue } from './SmartQueue.js';\nexport * from './dom/index.js';\nexport * from './wait.js';\nexport * from './random.js';\nexport * from './memo.js';\n"],
5
+ "mappings": "AAAA,SAAoB,WAAXA,gBAA2B;AACpC,cAAc;AACd,SAAoB,WAAXA,gBAA2B;AACpC,SAAoB,WAAXA,gBAA0B;AACnC,SAAS,iBAAiB;AAC1B,SAAS,gBAAgB;AACzB,SAAS,qBAAqB;AAC9B,SAAoB,WAAXA,gBAA2B;AACpC,SAAS,gBAAgB;AACzB,SAAoB,WAAXA,gBAAuC;AAChD,cAAc;AACd,cAAc;AACd,cAAc;AACd;AAAA,EACE;AAAA,EACQ;AAAA,EACG;AAAA,OACN;AACP,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,SAAS,aAAa;AACtB,SAAS,aAAa;AACtB,SAAS,kBAAkB;AAC3B,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;",
6
6
  "names": ["default"]
7
7
  }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Memoize the result of a function with a single argument indefinitely.
3
+ * This is a simpler implementation of the `memoize` function.
4
+ */
5
+ export declare function memo<T extends (...args: unknown[]) => unknown>(fn: T): T;
package/utils/memo.js ADDED
@@ -0,0 +1,14 @@
1
+ function memo(fn) {
2
+ const cache = /* @__PURE__ */ new Map();
3
+ return function cached(...args) {
4
+ const key = args.join("");
5
+ if (!cache.has(key)) {
6
+ cache.set(key, fn(...args));
7
+ }
8
+ return cache.get(key);
9
+ };
10
+ }
11
+ export {
12
+ memo
13
+ };
14
+ //# sourceMappingURL=memo.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../packages/js-toolkit/utils/memo.ts"],
4
+ "sourcesContent": ["/**\n * Memoize the result of a function with a single argument indefinitely.\n * This is a simpler implementation of the `memoize` function.\n */\nexport function memo<T extends (...args: unknown[]) => unknown>(fn: T): T {\n const cache = new Map<string, ReturnType<T>>();\n\n // @ts-ignore\n return function cached(...args) {\n const key = args.join('');\n if (!cache.has(key)) {\n cache.set(key, fn(...args) as ReturnType<T>);\n }\n return cache.get(key);\n };\n}\n"],
5
+ "mappings": "AAIO,SAAS,KAAgD,IAAU;AACxE,QAAM,QAAQ,oBAAI,IAA2B;AAG7C,SAAO,SAAS,UAAU,MAAM;AAC9B,UAAM,MAAM,KAAK,KAAK,EAAE;AACxB,QAAI,CAAC,MAAM,IAAI,GAAG,GAAG;AACnB,YAAM,IAAI,KAAK,GAAG,GAAG,IAAI,CAAkB;AAAA,IAC7C;AACA,WAAO,MAAM,IAAI,GAAG;AAAA,EACtB;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Convert a string to lowercase.
3
+ */
4
+ export declare function lowerCase(string: string): string;
5
+ /**
6
+ * Convert a string to UPPERCASE.
7
+ */
8
+ export declare function upperCase(string: string): string;
9
+ /**
10
+ * Convert a string to camelCase.
11
+ */
12
+ export declare const camelCase: (string: string) => string;
13
+ /**
14
+ * Convert a string to PascalCase.
15
+ */
16
+ export declare const pascalCase: (string: string) => string;
17
+ /**
18
+ * Convert a string to snake_case.
19
+ */
20
+ export declare const snakeCase: (string: string) => string;
21
+ /**
22
+ * Convert a string to dash-case.
23
+ */
24
+ export declare const dashCase: (string: string) => string;
@@ -0,0 +1,47 @@
1
+ import { memo } from "../memo.js";
2
+ const SPLIT_LOWER_UPPER_RE = /([\p{Ll}\d])(\p{Lu})/gu;
3
+ const SPLIT_UPPER_UPPER_RE = /(\p{Lu})([\p{Lu}][\p{Ll}])/gu;
4
+ const DEFAULT_STRIP_REGEXP = /[^\p{L}\d]+/giu;
5
+ const SPLIT_REPLACE_VALUE = "$1\0$2";
6
+ function split(value) {
7
+ let result = value.trim();
8
+ result = result.replace(SPLIT_LOWER_UPPER_RE, SPLIT_REPLACE_VALUE).replace(SPLIT_UPPER_UPPER_RE, SPLIT_REPLACE_VALUE);
9
+ result = result.replace(DEFAULT_STRIP_REGEXP, "\0");
10
+ let start = 0;
11
+ let end = result.length;
12
+ while (result.charAt(start) === "\0") start++;
13
+ if (start === end) return [];
14
+ while (result.charAt(end - 1) === "\0") end--;
15
+ return result.slice(start, end).split(/\0/g);
16
+ }
17
+ function delimitedCase(string, delimiter) {
18
+ return split(string).map((word) => lowerCase(word)).join(delimiter);
19
+ }
20
+ function lowerCase(string) {
21
+ return string.toLowerCase();
22
+ }
23
+ function upperCase(string) {
24
+ return string.toUpperCase();
25
+ }
26
+ const camelCase = memo(function camelCase2(string) {
27
+ const result = pascalCase(string);
28
+ return lowerCase(result[0]) + result.slice(1);
29
+ });
30
+ const pascalCase = memo(function pascalCase2(string) {
31
+ return split(string).map((word) => upperCase(word[0]) + lowerCase(word.slice(1))).join("");
32
+ });
33
+ const snakeCase = memo(function snakeCase2(string) {
34
+ return delimitedCase(string, "_");
35
+ });
36
+ const dashCase = memo(function dashCase2(string) {
37
+ return delimitedCase(string, "-");
38
+ });
39
+ export {
40
+ camelCase,
41
+ dashCase,
42
+ lowerCase,
43
+ pascalCase,
44
+ snakeCase,
45
+ upperCase
46
+ };
47
+ //# sourceMappingURL=changeCase.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../packages/js-toolkit/utils/string/changeCase.ts"],
4
+ "sourcesContent": ["import { memo } from '../memo.js';\n\nconst SPLIT_LOWER_UPPER_RE = /([\\p{Ll}\\d])(\\p{Lu})/gu;\nconst SPLIT_UPPER_UPPER_RE = /(\\p{Lu})([\\p{Lu}][\\p{Ll}])/gu;\nconst DEFAULT_STRIP_REGEXP = /[^\\p{L}\\d]+/giu;\nconst SPLIT_REPLACE_VALUE = '$1\\0$2';\n\n/**\n * Split function from the `change-case` package.\n * @see https://github.com/blakeembrey/change-case\n */\nfunction split(value: string) {\n let result = value.trim();\n\n result = result\n .replace(SPLIT_LOWER_UPPER_RE, SPLIT_REPLACE_VALUE)\n .replace(SPLIT_UPPER_UPPER_RE, SPLIT_REPLACE_VALUE);\n\n result = result.replace(DEFAULT_STRIP_REGEXP, '\\0');\n\n let start = 0;\n let end = result.length;\n\n // Trim the delimiter from around the output string.\n while (result.charAt(start) === '\\0') start++;\n if (start === end) return [];\n while (result.charAt(end - 1) === '\\0') end--;\n\n return result.slice(start, end).split(/\\0/g);\n}\n\n/**\n * Convert a string to lowercase and join each word with the given delimiter.\n */\nfunction delimitedCase(string: string, delimiter: string): string {\n return split(string)\n .map((word) => lowerCase(word))\n .join(delimiter);\n}\n/**\n * Convert a string to lowercase.\n */\nexport function lowerCase(string: string): string {\n return string.toLowerCase();\n}\n\n/**\n * Convert a string to UPPERCASE.\n */\nexport function upperCase(string: string): string {\n return string.toUpperCase();\n}\n\n/**\n * Convert a string to camelCase.\n */\nexport const camelCase = memo(function camelCase(string: string): string {\n const result = pascalCase(string);\n return lowerCase(result[0]) + result.slice(1);\n});\n\n/**\n * Convert a string to PascalCase.\n */\nexport const pascalCase = memo(function pascalCase(string: string): string {\n return split(string)\n .map((word) => upperCase(word[0]) + lowerCase(word.slice(1)))\n .join('');\n});\n\n/**\n * Convert a string to snake_case.\n */\nexport const snakeCase = memo(function snakeCase(string: string): string {\n return delimitedCase(string, '_');\n});\n\n/**\n * Convert a string to dash-case.\n */\nexport const dashCase = memo(function dashCase(string: string): string {\n return delimitedCase(string, '-');\n});\n"],
5
+ "mappings": "AAAA,SAAS,YAAY;AAErB,MAAM,uBAAuB;AAC7B,MAAM,uBAAuB;AAC7B,MAAM,uBAAuB;AAC7B,MAAM,sBAAsB;AAM5B,SAAS,MAAM,OAAe;AAC5B,MAAI,SAAS,MAAM,KAAK;AAExB,WAAS,OACN,QAAQ,sBAAsB,mBAAmB,EACjD,QAAQ,sBAAsB,mBAAmB;AAEpD,WAAS,OAAO,QAAQ,sBAAsB,IAAI;AAElD,MAAI,QAAQ;AACZ,MAAI,MAAM,OAAO;AAGjB,SAAO,OAAO,OAAO,KAAK,MAAM,KAAM;AACtC,MAAI,UAAU,IAAK,QAAO,CAAC;AAC3B,SAAO,OAAO,OAAO,MAAM,CAAC,MAAM,KAAM;AAExC,SAAO,OAAO,MAAM,OAAO,GAAG,EAAE,MAAM,KAAK;AAC7C;AAKA,SAAS,cAAc,QAAgB,WAA2B;AAChE,SAAO,MAAM,MAAM,EAChB,IAAI,CAAC,SAAS,UAAU,IAAI,CAAC,EAC7B,KAAK,SAAS;AACnB;AAIO,SAAS,UAAU,QAAwB;AAChD,SAAO,OAAO,YAAY;AAC5B;AAKO,SAAS,UAAU,QAAwB;AAChD,SAAO,OAAO,YAAY;AAC5B;AAKO,MAAM,YAAY,KAAK,SAASA,WAAU,QAAwB;AACvE,QAAM,SAAS,WAAW,MAAM;AAChC,SAAO,UAAU,OAAO,CAAC,CAAC,IAAI,OAAO,MAAM,CAAC;AAC9C,CAAC;AAKM,MAAM,aAAa,KAAK,SAASC,YAAW,QAAwB;AACzE,SAAO,MAAM,MAAM,EAChB,IAAI,CAAC,SAAS,UAAU,KAAK,CAAC,CAAC,IAAI,UAAU,KAAK,MAAM,CAAC,CAAC,CAAC,EAC3D,KAAK,EAAE;AACZ,CAAC;AAKM,MAAM,YAAY,KAAK,SAASC,WAAU,QAAwB;AACvE,SAAO,cAAc,QAAQ,GAAG;AAClC,CAAC;AAKM,MAAM,WAAW,KAAK,SAASC,UAAS,QAAwB;AACrE,SAAO,cAAc,QAAQ,GAAG;AAClC,CAAC;",
6
+ "names": ["camelCase", "pascalCase", "snakeCase", "dashCase"]
7
+ }
@@ -10,3 +10,4 @@ export { default as withTrailingCharacters } from './withTrailingCharacters.js';
10
10
  export { default as withTrailingSlash } from './withTrailingSlash.js';
11
11
  export * from './startsWith.js';
12
12
  export * from './endsWith.js';
13
+ export * from './changeCase.js';
@@ -10,6 +10,7 @@ import { default as default10 } from "./withTrailingCharacters.js";
10
10
  import { default as default11 } from "./withTrailingSlash.js";
11
11
  export * from "./startsWith.js";
12
12
  export * from "./endsWith.js";
13
+ export * from "./changeCase.js";
13
14
  export {
14
15
  default2 as withLeadingCharacters,
15
16
  default3 as withLeadingSlash,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../packages/js-toolkit/utils/string/index.ts"],
4
- "sourcesContent": ["export { default as withLeadingCharacters } from './withLeadingCharacters.js';\nexport { default as withLeadingSlash } from './withLeadingSlash.js';\nexport { default as withoutLeadingCharacters } from './withoutLeadingCharacters.js';\nexport { default as withoutLeadingCharactersRecursive } from './withoutLeadingCharactersRecursive.js';\nexport { default as withoutLeadingSlash } from './withoutLeadingSlash.js';\nexport { default as withoutTrailingCharacters } from './withoutTrailingCharacters.js';\nexport { default as withoutTrailingCharactersRecursive } from './withoutTrailingCharactersRecursive.js';\nexport { default as withoutTrailingSlash } from './withoutTrailingSlash.js';\nexport { default as withTrailingCharacters } from './withTrailingCharacters.js';\nexport { default as withTrailingSlash } from './withTrailingSlash.js';\nexport * from './startsWith.js';\nexport * from './endsWith.js';\n"],
5
- "mappings": "AAAA,SAAoB,WAAXA,gBAAwC;AACjD,SAAoB,WAAXA,gBAAmC;AAC5C,SAAoB,WAAXA,gBAA2C;AACpD,SAAoB,WAAXA,gBAAoD;AAC7D,SAAoB,WAAXA,gBAAsC;AAC/C,SAAoB,WAAXA,gBAA4C;AACrD,SAAoB,WAAXA,gBAAqD;AAC9D,SAAoB,WAAXA,gBAAuC;AAChD,SAAoB,WAAXA,iBAAyC;AAClD,SAAoB,WAAXA,iBAAoC;AAC7C,cAAc;AACd,cAAc;",
4
+ "sourcesContent": ["export { default as withLeadingCharacters } from './withLeadingCharacters.js';\nexport { default as withLeadingSlash } from './withLeadingSlash.js';\nexport { default as withoutLeadingCharacters } from './withoutLeadingCharacters.js';\nexport { default as withoutLeadingCharactersRecursive } from './withoutLeadingCharactersRecursive.js';\nexport { default as withoutLeadingSlash } from './withoutLeadingSlash.js';\nexport { default as withoutTrailingCharacters } from './withoutTrailingCharacters.js';\nexport { default as withoutTrailingCharactersRecursive } from './withoutTrailingCharactersRecursive.js';\nexport { default as withoutTrailingSlash } from './withoutTrailingSlash.js';\nexport { default as withTrailingCharacters } from './withTrailingCharacters.js';\nexport { default as withTrailingSlash } from './withTrailingSlash.js';\nexport * from './startsWith.js';\nexport * from './endsWith.js';\nexport * from './changeCase.js';\n"],
5
+ "mappings": "AAAA,SAAoB,WAAXA,gBAAwC;AACjD,SAAoB,WAAXA,gBAAmC;AAC5C,SAAoB,WAAXA,gBAA2C;AACpD,SAAoB,WAAXA,gBAAoD;AAC7D,SAAoB,WAAXA,gBAAsC;AAC/C,SAAoB,WAAXA,gBAA4C;AACrD,SAAoB,WAAXA,gBAAqD;AAC9D,SAAoB,WAAXA,gBAAuC;AAChD,SAAoB,WAAXA,iBAAyC;AAClD,SAAoB,WAAXA,iBAAoC;AAC7C,cAAc;AACd,cAAc;AACd,cAAc;",
6
6
  "names": ["default"]
7
7
  }