{"version":3,"file":"index.mjs","names":[],"sources":["mimopo/croqueta/components/styles.service.ts","mimopo/croqueta/reactivity/readonly.ts","mimopo/croqueta/components/effect.ts","mimopo/croqueta/components/repeat.ts","mimopo/croqueta/components/render.ts","mimopo/croqueta/utils/memoize.ts","mimopo/croqueta/utils/synthax-highlighting.ts","mimopo/croqueta/utils/validate-event-name.ts","mimopo/croqueta/components/component.ts","mimopo/croqueta/components/webcomponent.ts","mimopo/croqueta/portal/portal.service.ts","mimopo/croqueta/portal/portal-out.component.ts","mimopo/croqueta/portal/portal-in.component.ts","mimopo/croqueta/router/provider.ts","mimopo/croqueta/router/outlet.ts","mimopo/croqueta/router/components/router.component.ts","mimopo/croqueta/router/strategies/hash-router-strategy.ts","mimopo/croqueta/router/strategies/path-router-strategy.ts","mimopo/croqueta/state/selectors.ts","mimopo/croqueta/state/feature.ts"],"sourcesContent":["import type { Destroy } from '../di';\nimport type { ComponentStatic } from './types';\n\n/**\n * A service responsible for managing and applying component styles.\n * It supports both Shadow DOM (via adoptedStyleSheets for performance) and\n * light DOM (by injecting <style> tags into the document head).\n * This service is designed to be a singleton within the application's injector.\n */\nexport class StylesService implements Destroy {\n  /**\n   * Caches CSSStyleSheet objects, keyed by component tag name.\n   * Used for Shadow DOM components to leverage adoptedStyleSheets.\n   */\n  private stylesheets = new Map<string, CSSStyleSheet>();\n\n  /**\n   * Caches <style> elements, keyed by component tag name.\n   * Used for light DOM components to avoid injecting duplicate style tags.\n   */\n  private styles = new Map<string, HTMLStyleElement>();\n\n  /**\n   * Caches global style strings to be applied to components.\n   */\n  private global: string = '';\n\n  /**\n   * Cleans up the service by clearing caches and removing any globally\n   * injected <style> elements from the document head.\n   * This is part of the `Destroy` lifecycle and is called when the application is torn down.\n   */\n  public destroy(): void {\n    this.stylesheets.clear();\n    for (const [, style] of this.styles) {\n      style.remove();\n    }\n    this.styles.clear();\n  }\n\n  /**\n   * Adds global CSS styles that will be applied to all components.\n   * This method must be called before any components are rendered to ensure\n   * styles are applied correctly.\n   * @param styles Strings containing the CSS rules to be applied globally.\n   */\n  public addGlobalStyles(...styles: string[]) {\n    if (this.stylesheets.size || this.styles.size) {\n      throw new Error(`Global styles must be registered before loading components`);\n    }\n    const content = styles.join('\\n');\n    this.global = this.global ? `${this.global}\\n${content}` : content;\n  }\n\n  /**\n   * Applies styles to a component's root.\n   * If the root is a ShadowRoot, it uses adoptedStyleSheets for optimal performance.\n   * If the root is a regular HTMLElement (light DOM), it injects a <style> tag\n   * into the document head, scoped to the component's tag.\n   * @param root The root element or shadow root to which styles will be applied.\n   * @param componentConstructor An object containing the component's static `tag` and `styles`.\n   */\n  public applyStyles(root: HTMLElement | ShadowRoot, componentConstructor: Pick<ComponentStatic, 'styles' | 'tag'>) {\n    if (root instanceof ShadowRoot) {\n      const stylesheets: CSSStyleSheet[] = [];\n      if (this.global) {\n        stylesheets.push(this.getStylesheet('global', this.global));\n      }\n      if (componentConstructor.styles) {\n        stylesheets.push(this.getStylesheet(componentConstructor.tag, componentConstructor.styles));\n      }\n      if (stylesheets.length) {\n        root.adoptedStyleSheets = stylesheets;\n      }\n    } else {\n      this.registerGlobalStyle(componentConstructor.tag);\n      if (componentConstructor.styles) {\n        this.registerStyle(componentConstructor.tag, componentConstructor.styles);\n      }\n    }\n  }\n\n  /**\n   * Retrieves a cached CSSStyleSheet for a given component tag, or creates\n   * and caches a new one if it doesn't exist. This avoids re-parsing the same\n   * style string for multiple instances of the same component.\n   * @param componentTag The tag name of the component, used as a cache key.\n   * @param styles The CSS style string to apply.\n   * @returns A `CSSStyleSheet` instance.\n   */\n  private getStylesheet(componentTag: string, styles: string) {\n    let sheet = this.stylesheets.get(componentTag);\n    if (!sheet) {\n      sheet = new CSSStyleSheet();\n      sheet.replaceSync(styles);\n      this.stylesheets.set(componentTag, sheet);\n    }\n    return sheet;\n  }\n\n  /**\n   * Creates and injects a `<style>` element into the document's head for components\n   * that render in the light DOM. The styles are scoped to the component's tag name.\n   * It ensures that styles for a given component tag are only registered once.\n   * @param componentTag The tag name of the component, used as a cache key and for scoping.\n   * @param styles The CSS style string to apply.\n   */\n  private registerStyle(componentTag: string, styles: string) {\n    if (this.styles.has(componentTag)) {\n      return;\n    }\n    const style = document.createElement('style');\n    style.innerHTML = `${componentTag} { ${styles} }`;\n    document.head.appendChild(style);\n    this.styles.set(componentTag, style);\n  }\n\n  /**\n   * Registers the global styles for a light DOM component.\n   * It creates a single `<style>` tag for global styles and updates it\n   * with the component's tag name to extend the style's scope.\n   * @param componentTag The tag name of the component to add to the global style scope.\n   */\n  private registerGlobalStyle(componentTag: string) {\n    if (!this.global || this.styles.has(componentTag)) {\n      return;\n    }\n    let style = this.styles.get('global');\n    if (style) {\n      style.innerHTML = `${componentTag}, ${style.innerHTML}`;\n    } else {\n      style = document.createElement('style');\n      style.innerHTML = `${componentTag} { ${this.global} }`;\n      document.head.appendChild(style);\n      this.styles.set('global', style);\n    }\n  }\n}\n","import { computed } from './computed';\nimport type { SignalComputed, SignalState } from './types';\n\n/**\n * Creates a readonly signal.\n * @param signal The signal to create a readonly version of.\n * @returns A readonly signal.\n */\nexport function readonly<T>(signal: SignalState<T>): SignalComputed<T> {\n  return computed(() => signal.get());\n}\n","import { type EffectCallback, type EffectCleanup, effect } from '../reactivity';\n\nconst nodeEffects = new WeakMap<Node, Set<EffectCleanup>>();\n\n/**\n * Registers an effect to be cleaned up when the given node is removed.\n */\nexport function registerEffect(node: Node, effectFn: EffectCallback) {\n  let set = nodeEffects.get(node);\n  if (!set) {\n    set = new Set();\n    nodeEffects.set(node, set);\n  }\n  set.add(effect(effectFn));\n}\n\n/**\n * Recursively cleans up effects associated with a node and its children.\n * Call this when a node is removed from the DOM.\n */\nexport function cleanup(node: Node) {\n  const set = nodeEffects.get(node);\n  if (set) {\n    set.forEach((dispose) => dispose());\n    nodeEffects.delete(node);\n  }\n\n  // Cleanup children recursively\n  if (node instanceof Element || node instanceof DocumentFragment) {\n    node.childNodes.forEach((child) => cleanup(child));\n  }\n}\n","import { cleanup, registerEffect } from './effect';\nimport type { RepeatResult, SignalLike } from './types';\n\n/**\n * @param itemsSignal - The reactive array\n * @param keyFn - Extracts a unique key (e.g., (item) => item.id)\n * @param templateFn - Returns an html`` template for each item\n */\nexport function repeat<T>(itemsSignal: SignalLike<T[]>, keyFn: (item: T) => unknown, templateFn: (item: T) => Node): RepeatResult<T> {\n  return {\n    type: 'repeat',\n    itemsSignal,\n    keyFn,\n    templateFn,\n    // Store for the persistent DOM nodes mapped by key\n    cache: new Map<unknown, { nodes: Node[]; item: T }>(),\n  };\n}\n\nexport function repeater(val: RepeatResult<unknown>, anchor: Node) {\n  const { itemsSignal, keyFn, templateFn, cache } = val;\n\n  registerEffect(anchor, () => {\n    const items = itemsSignal.get();\n    const parent = anchor.parentNode;\n    if (!parent) return;\n\n    // 1. Cleanup: Remove nodes no longer in the list\n    const currentKeys = new Set<unknown>();\n    for (const item of items) {\n      currentKeys.add(keyFn(item));\n    }\n\n    for (const [key, cached] of cache.entries()) {\n      if (!currentKeys.has(key)) {\n        cached.nodes.forEach((n: Node) => {\n          cleanup(n);\n          (n as ChildNode).remove();\n        });\n        cache.delete(key);\n      }\n    }\n\n    // 2. Reconciliation loop in reverse order to use insertBefore relative to anchor\n    let nextNode = anchor;\n    for (let i = items.length - 1; i >= 0; i--) {\n      const item = items[i];\n      const key = keyFn(item);\n\n      let cached = cache.get(key);\n      if (!cached) {\n        // Create new DOM nodes if not in cache\n        const content = templateFn(item);\n        // Track the actual DOM nodes\n        cached = { nodes: Array.from(content.childNodes), item };\n        cache.set(key, cached);\n      }\n\n      // 2. DOM Placement\n      // We move nodes into the correct position relative to the nextNode (initially the anchor)\n      for (let j = cached.nodes.length - 1; j >= 0; j--) {\n        const n = cached.nodes[j];\n        if (n.nextSibling !== nextNode) {\n          parent.insertBefore(n, nextNode);\n        }\n        nextNode = n;\n      }\n    }\n  });\n}\n","import { cleanup, registerEffect } from './effect';\nimport { repeater } from './repeat';\nimport { isRepeat, isSignal, isWritableSignal } from './utils';\n\n/**\n * Applies an attribute to an element. Handles boolean attributes by removing them when false\n * @param el The element to apply the attribute to.\n * @param attrName The name of the attribute.\n * @param val The value of the attribute.\n */\nfunction applyAttribute(el: HTMLElement, attrName: string, val: unknown) {\n  if (val === false || val === undefined || val === null) {\n    el.removeAttribute(attrName);\n  } else {\n    // oxlint-disable-next-line typescript/no-base-to-string\n    el.setAttribute(attrName, String(val));\n  }\n}\n\n/**\n * We use a WeakMap because the TemplateStringsArray is created for each tagged template literal\n */\nconst templateCache = new WeakMap<TemplateStringsArray, HTMLTemplateElement>();\n\n/**\n * Returns true if the accumulated HTML string ends inside an open attribute value\n * (i.e. there is an unmatched `=\"` that hasn't been closed by a subsequent `\"`).\n */\nfunction isInsideAttribute(accumulated: string): boolean {\n  // Walk backwards from the end looking for the last `=\"`.\n  // If found, count the `\"` characters after it — if there are none, we're inside the attribute.\n  const lastAttrOpen = accumulated.lastIndexOf('=\"');\n  if (lastAttrOpen === -1) return false;\n  // Everything after the `=\"` opening\n  const afterOpen = accumulated.slice(lastAttrOpen + 2);\n  // If there's no closing `\"` after the opening, we're still inside the attribute value\n  return !afterOpen.includes('\"');\n}\n\n/**\n * Parses a template literal into a template element.\n * @param strings The template literal strings.\n * @param values The values to interpolate into the template literal.\n * @returns The parsed template element.\n */\nfunction parseTemplate(strings: TemplateStringsArray, values: unknown[]) {\n  const template = document.createElement('template');\n  // 1. Build the HTML string with Comment Markers\n  // We use as a marker for dynamic holes\n  const processedHtml = strings.reduce((acc, str, i) => {\n    let placeholder = '';\n\n    if (i < values.length) {\n      // Check if this hole is inside an attribute value or a text node\n      const accumulated = acc + str;\n      if (isInsideAttribute(accumulated)) {\n        placeholder = `__attr_${i}__`;\n      } else {\n        placeholder = `<!--m${i}-->`;\n      }\n    }\n    return acc + str + placeholder;\n  }, '');\n\n  template.innerHTML = processedHtml;\n  return template;\n}\n\n/**\n * Handles event bindings.\n * @param el The element to bind the event to.\n * @param attrName The name of the event.\n * @param val The event handler.\n */\nfunction eventBinding(el: HTMLElement, attrName: string, val: unknown) {\n  const eventName = attrName.slice(1, -1).toLowerCase();\n  if (typeof val !== 'function') {\n    throw new Error(`[Framework Error]: Event handler \"${eventName}\" must be a function.`);\n  }\n  el.addEventListener(eventName, (e) => {\n    val(e instanceof CustomEvent ? e.detail : e);\n  });\n}\n\n/**\n * Handles two-way data bindings.\n * @param el The element to bind the two-way data binding to.\n * @param attrName The name of the property to bind.\n * @param val The signal to bind.\n */\nfunction twoWayBinding(el: HTMLElement, attrName: string, val: unknown) {\n  const propertyName = attrName.slice(2, -2).toLowerCase();\n  if (!isWritableSignal(val)) {\n    throw new Error(`[Framework Error]: Two way data binding on \"${propertyName}\" must be a writable Signal.`);\n  }\n  registerEffect(el, () => {\n    (el as any)[propertyName] = val.get();\n  });\n  el.addEventListener(`${propertyName}-change`, (e) => {\n    if (e instanceof CustomEvent) {\n      val.set(e.detail);\n    }\n  });\n}\n\nfunction propertyBinding(el: HTMLElement, attrName: string, val: unknown) {\n  const propertyName = attrName.slice(1, -1);\n  if (isSignal(val)) {\n    registerEffect(el, () => {\n      (el as any)[propertyName] = val.get();\n    });\n  } else {\n    (el as any)[propertyName] = val;\n  }\n}\n\n/**\n * Handles attribute bindings.\n * @param el The element to bind the attribute to.\n * @param attrName The name of the attribute to bind.\n * @param val The value to bind.\n */\nfunction attributeBinding(el: HTMLElement, attrName: string, val: unknown) {\n  if (isSignal(val)) {\n    registerEffect(el, () => {\n      applyAttribute(el, attrName, val.get());\n    });\n  } else {\n    applyAttribute(el, attrName, val);\n  }\n}\n\n/**\n * Renders a template literal to the DOM.\n * @param strings The template literal strings.\n * @param values The values to interpolate into the template literal.\n * @returns The rendered template literal.\n */\nexport function html(strings: TemplateStringsArray, ...values: unknown[]): DocumentFragment {\n  let template = templateCache.get(strings);\n  if (!template) {\n    template = parseTemplate(strings, values);\n    templateCache.set(strings, template);\n  }\n  // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- cloneNode over a DocumentFragment will always return a DocumentFragment\n  const fragment: DocumentFragment = template.content.cloneNode(true) as DocumentFragment;\n\n  // 2. Hydrate the fragment\n  const walker = document.createTreeWalker(fragment, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT);\n  let node: Node | null;\n  while ((node = walker.nextNode())) {\n    if (node instanceof HTMLElement) {\n      const el = node;\n      // We copy attributes to an array because we might remove them during iteration\n      for (const attr of Array.from(el.attributes)) {\n        const attrName = attr.name;\n        const attrValue = attr.value;\n\n        // Check if the value contains any markers like __attr_0__\n        const matches = attrValue.match(/__attr_(\\d+)__/g);\n        if (matches) {\n          // A. Special bindings or exact placeholder match (no mixed text)\n          if (attrName.startsWith('(') || attrName.startsWith('[') || (matches.length === 1 && attrValue === matches[0])) {\n            const i = parseInt(matches[0].match(/\\d+/)![0], 10);\n            const val = values[i];\n            el.removeAttribute(attrName);\n            if (attrName.startsWith('(') && attrName.endsWith(')')) {\n              eventBinding(el, attrName, val);\n            } else if (attrName.startsWith('[(') && attrName.endsWith(')]')) {\n              twoWayBinding(el, attrName, val);\n            } else if (attrName.startsWith('[') && attrName.endsWith(']')) {\n              propertyBinding(el, attrName, val);\n            } else {\n              attributeBinding(el, attrName, val);\n            }\n          } else {\n            // B. Mixed attribute value (e.g. src=\"https://example.com/__attr_0__\")\n            const indices = matches.map((m) => parseInt(m.match(/\\d+/)![0], 10));\n            const update = () => {\n              let finalValue = attrValue;\n              indices.forEach((idx) => {\n                const v = values[idx];\n                const val = isSignal(v) ? v.get() : v;\n                finalValue = finalValue.replace(`__attr_${idx}__`, String(val));\n              });\n              applyAttribute(el, attrName, finalValue);\n            };\n\n            if (indices.some((idx) => isSignal(values[idx]))) {\n              registerEffect(el, update);\n            } else {\n              update();\n            }\n          }\n        }\n      }\n    } else if (node.nodeType === Node.COMMENT_NODE) {\n      const comment = node as Comment;\n      const match = comment.textContent?.match(/^m(\\d+)$/);\n      if (match) {\n        const i = parseInt(match[1], 10);\n        const val = values[i];\n\n        if (isRepeat(val)) {\n          repeater(val, comment);\n        } else if (isSignal(val)) {\n          const anchor = comment as ChildNode;\n          let currentNodes: Node[] = [];\n          registerEffect(anchor, () => {\n            const v = val.get();\n            const parent = anchor.parentNode;\n            if (!parent) return;\n\n            // 1. Cleanup old nodes\n            currentNodes.forEach((n) => {\n              cleanup(n);\n              if (n.parentNode) {\n                n.parentNode.removeChild(n);\n              }\n            });\n            currentNodes = [];\n\n            // 2. Insert new content\n            if (v instanceof Node) {\n              const nodes = v instanceof DocumentFragment ? Array.from(v.childNodes) : [v];\n              nodes.forEach((n) => parent.insertBefore(n, anchor));\n              currentNodes = nodes;\n            } else {\n              const textNode = document.createTextNode(String(v));\n              parent.insertBefore(textNode, anchor);\n              currentNodes = [textNode];\n            }\n          });\n        } else if (val instanceof Node) {\n          comment.replaceWith(val);\n        } else {\n          comment.replaceWith(document.createTextNode(String(val)));\n        }\n      }\n    }\n  }\n\n  return fragment;\n}\n","/**\n * Memoizes a function by caching the result of its last execution.\n *\n * This function is useful for optimizing functions that are called repeatedly\n * with the same arguments in sequence. It only stores the arguments and result\n * of the most recent call.\n *\n * @template T The type of the function to memoize. It must be a function that\n *             takes any number of arguments and returns a value.\n * @param {T} fn The function to memoize.\n * @returns {T} A new function that is a memoized version of `fn`.\n */\nexport function memoize<T extends (...args: any[]) => any>(fn: T): T {\n  let lastArgs: Parameters<T> | undefined;\n  let lastResult: ReturnType<T>;\n\n  return function (...args: Parameters<T>): ReturnType<T> {\n    // Check if the new arguments are the same as the last ones.\n    if (lastArgs && args.length === lastArgs.length && args.every((arg, index) => arg === lastArgs?.[index])) {\n      // If they are the same, return the cached result.\n      return lastResult;\n    }\n\n    // If arguments are different or it's the first call, execute the function.\n    const result = fn(...args);\n\n    // Cache the new arguments and the new result.\n    lastArgs = args;\n    lastResult = result;\n\n    // Return the new result.\n    return result;\n  } as T;\n}\n","/** Tagged template to enable syntax highlighting for CSS in your IDE */\nexport const css = String.raw;\n","/**\n * Validates if an event name is a valid custom event name for the framework.\n *\n * Rules:\n * 1. Must not be empty.\n * 2. Must be lowercase (as the framework lowercases event names in templates).\n * 3. Must start with a letter.\n * 4. Must contain only lowercase letters, numbers, hyphens, or underscores.\n * 5. Must not start with 'on' (to avoid confusion with native event handlers).\n *\n * @param name The event name to validate.\n * @throws Error if the name is invalid.\n */\nexport function validateEventName(name: string): void {\n  if (!name) {\n    throw new Error('[Framework Error]: Event name cannot be empty.');\n  }\n\n  // Check for 'on' prefix\n  if (name.startsWith('on')) {\n    throw new Error(`[Framework Error]: Invalid event name \"${name}\". Custom event names should not start with \"on\".`);\n  }\n\n  // Regex: starts with a letter, followed by lowercase letters, numbers, hyphens or underscores\n  const validNameRegex = /^[a-z][a-z0-9-_]*$/;\n  if (!validNameRegex.test(name)) {\n    throw new Error(\n      `[Framework Error]: Invalid event name \"${name}\". ` +\n        'Custom event names must be lowercase, start with a letter, and only contain lowercase letters, numbers, hyphens, or underscores.'\n    );\n  }\n}\n","import { inject } from '../di';\nimport { type EffectCallback, type SignalState, signal } from '../reactivity';\nimport { validateEventName } from '../utils';\nimport { cleanup, registerEffect } from './effect';\nimport { StylesService } from './styles.service';\nimport type { ComponentConstructor, ComponentOptions, Emitter, SignalEmitter } from './types';\n\n/**\n * Base class for all components.\n */\nexport abstract class Component extends HTMLElement {\n  /**\n   * Renders the component to the DOM.\n   * @returns The node to render.\n   */\n  protected abstract render(): Node;\n  /**\n   * The root of the component.\n   * Depending on the encapsulation chosen, it will be a ShadowRoot or the component itself\n   */\n  protected root: ShadowRoot | this;\n\n  private options: ComponentOptions;\n  private stylesService = inject(StylesService);\n\n  constructor(options?: Partial<ComponentOptions>) {\n    super();\n    if (!(this.constructor as ComponentConstructor).tag) {\n      throw new Error(`Component ${this.constructor.name} must have a static tag property`);\n    }\n    const defaults: ComponentOptions = {\n      shadow: 'closed',\n    };\n    this.options = { ...defaults, ...options };\n    this.root = this.options.shadow === 'none' ? this : this.attachShadow({ mode: this.options.shadow });\n  }\n\n  /**\n   * Invoked when the custom element is first connected to the document's DOM.\n   * Always call super.connectedCallback() if you override this method.\n   * @see https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements#custom_element_lifecycle_callbacks\n   */\n  public connectedCallback() {\n    const { styles, tag } = this.constructor as ComponentConstructor;\n    this.stylesService.applyStyles(this.root, { styles, tag });\n    this.root.replaceChildren(this.render());\n  }\n\n  /**\n   * Invoked when the custom element is disconnected from the document's DOM.\n   * Always call super.disconnectedCallback() if you override this method.\n   * @see https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements#custom_element_lifecycle_callbacks\n   */\n  public disconnectedCallback() {\n    cleanup(this);\n    this.root?.replaceChildren();\n  }\n\n  /**\n   * Registers a function to be called whenever any of the signals it reads change.\n   * It automatically cleans up the effect when the component is disconnected.\n   * @param effectFn The function to register.\n   */\n  protected effect(effectFn: EffectCallback) {\n    registerEffect(this, effectFn);\n  }\n\n  /**\n   * Creates a one-way binding between a property and a signal.\n   * @param propName The name of the property to bind.\n   * @param initialValue The initial value of the property.\n   * @returns A signal that can be used to get or set the property value.\n   */\n  protected input<T>(propName: string, initialValue: T): SignalState<T> {\n    // TODO: improve validation by avoiding same name on property and signal and avoid methods overwrite\n    if (propName === 'input' || propName === 'output' || propName === 'inputOutput') {\n      throw new Error(`[Framework Error]: Property \"${propName}\" is a reserved keyword.`);\n    }\n    validateEventName(propName);\n    if (Object.getOwnPropertyDescriptor(this, propName)?.get) {\n      throw new Error(`[Framework Error]: Property \"${propName}\" is already bound to a Signal.`);\n    }\n    let value = initialValue;\n    if (this.hasOwnProperty(propName)) {\n      value = (this as any)[propName];\n      delete (this as any)[propName];\n    }\n    const s = signal(value);\n    Object.defineProperty(this, propName, {\n      get: () => s.get(),\n      set: (v: T) => s.set(v),\n      enumerable: true,\n      configurable: true,\n    });\n\n    return s;\n  }\n\n  /**\n   * Creates an output emitter.\n   * @param eventName The name of the event to emit.\n   * @returns An object with an emit method.\n   */\n  protected output<T>(eventName: string): Emitter<T> {\n    validateEventName(eventName);\n    return {\n      emit: (value: T) => this.dispatchCustomEvent(eventName, value),\n    };\n  }\n\n  /**\n   * Creates a two-way binding between a property and a signal.\n   * Use set() to only update the value internally, and emit() to update and notify parent component.\n   * @param propName The name of the property to bind.\n   * @param initialValue The initial value of the property.\n   * @returns An object with get, set, and emit methods.\n   */\n  protected inputOutput<T>(propName: string, initialValue: T): SignalEmitter<T> {\n    const s = this.input(propName, initialValue);\n    const eventName = `${propName}-change`;\n    return {\n      get: () => s.get(),\n      set: (v: T) => s.set(v),\n      emit: (v: T) => {\n        s.set(v);\n        this.dispatchCustomEvent(eventName, v);\n      },\n    };\n  }\n\n  protected dispatchCustomEvent(eventName: string, value: unknown): void {\n    this.dispatchEvent(\n      new CustomEvent(eventName, {\n        detail: value,\n        bubbles: false,\n      })\n    );\n  }\n}\n","import type { SignalState } from '../reactivity';\nimport { Component } from './component';\nimport type { AttributeInput, SignalEmitter } from './types';\n\n/**\n * Base class for componentents that meant to be used as custom elements outside the framework.\n * It provides a way to bind attributes.\n */\nexport abstract class WebComponent extends Component {\n  private attributeHandlers: Record<string, (value: string | null) => void> = {};\n\n  /**\n   * Invoked when one of the custom element's attributes is added, removed, or changed.\n   * Always call super.attributeChangedCallback() if you override this method.\n   * @param name The name of the attribute.\n   * @param _oldValue The old value of the attribute.\n   * @param newValue The new value of the attribute.\n   * @see https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements#responding_to_attribute_changes\n   */\n  public attributeChangedCallback(name: string, _oldValue: string, newValue: string) {\n    this.attributeHandlers[name]?.(newValue);\n  }\n\n  /**\n   * Creates an input that is bound to an attribute.\n   * @param config The configuration for the input.\n   * @returns A signal that can be used to get or set the input value.\n   */\n  protected attributeInput<T>(config: AttributeInput<T>): SignalState<T> {\n    const i = this.input(config.name, config.initialValue);\n    const observed = (this.constructor as any).observedAttributes;\n    if (!Array.isArray(observed) || !observed.includes(config.name)) {\n      throw new Error(`[Framework Error]: observedAttributes must contain \"${config.name}\".`);\n    }\n    let fromAttribute = true;\n    let fromSignal = false;\n    // Attribute to Signal\n    this.attributeHandlers[config.name] = (value: string | null) => {\n      if (fromSignal) {\n        fromSignal = false;\n        return;\n      }\n      fromAttribute = true;\n      i.set(config.fromString(value));\n    };\n    // Signal to Attribute\n    this.effect(() => {\n      const v = i.get();\n      if (fromAttribute) {\n        fromAttribute = false;\n        return;\n      }\n      fromSignal = true;\n      const value = config.toString(v);\n      if (value === null) {\n        this.removeAttribute(config.name);\n      } else {\n        this.setAttribute(config.name, value);\n      }\n    });\n\n    return i;\n  }\n\n  /**\n   * Creates an input/output that is bound to an attribute.\n   * @param config The configuration for the input/output.\n   * @returns A signal emitter that can be used to get or set the input/output value.\n   */\n  protected attributeInputOutput<T>(config: AttributeInput<T>): SignalEmitter<T> {\n    const s = this.attributeInput(config);\n    const eventName = `${config.name}-change`;\n    return {\n      get: () => s.get(),\n      set: (v: T) => s.set(v),\n      emit: (v: T) => {\n        s.set(v);\n        this.dispatchCustomEvent(eventName, v);\n      },\n    };\n  }\n}\n","import type { Destroy } from '../di';\nimport { type SignalComputed, computed, signal } from '../reactivity';\n\n/**\n * Manages a collection of \"portals\". A portal is a mechanism to render a content\n * at a different location in the DOM tree. This service acts as a centralized,\n * reactive registry for these portal elements.\n */\nexport class PortalService implements Destroy {\n  /**\n   * A Signal that holds the current state of all registered portals\n   * as a key-value map, where the key is the portal's unique identifier and\n   * the value is the Node to be rendered.\n   */\n  private portals = signal<Record<string, Node>>({});\n\n  /** @inheritdoc */\n  public destroy() {\n    this.portals.set({});\n  }\n\n  /**\n   * Registers or updates a Node for a given portal key.\n   * @param key A unique string identifier for the portal.\n   * @param node The Node to be associated with the portal key.\n   */\n  public update(key: string, node: Node) {\n    this.portals.set({\n      ...this.portals.get(),\n      [key]: node,\n    });\n  }\n\n  /**\n   * Removes a portal from the registry.\n   * @param key The unique string identifier of the portal to unregister.\n   */\n  public remove(key: string) {\n    const portals = { ...this.portals.get() };\n    if (portals[key]) {\n      delete portals[key];\n      this.portals.set(portals);\n    }\n  }\n\n  /**\n   * Retrieves a Signal that emits the Node for a specific portal key\n   * whenever it changes.\n   * @param key The unique string identifier of the portal to observe.\n   * @returns A Signal that returns the Node or `undefined` if the key is not registered.\n   */\n  public get(key: string): SignalComputed<Node | undefined> {\n    return computed(() => this.portals.get()[key]);\n  }\n}\n","import { WebComponent, html } from '../components';\nimport { inject } from '../di';\nimport { PortalService } from './portal.service';\n\n/**\n * A component that acts as a rendering target for a portal.\n *\n * It subscribes to the `PortalService` with a specific key and renders the `Node` associated with that key. This allows for rendering\n * content from anywhere in the application into the location of this component.\n */\nexport class PortalOutComponent extends WebComponent {\n  /** The custom element tag name for this component. */\n  public static tag = 'croqueta-portal-out';\n  public static observedAttributes = ['key'];\n\n  /** Input property for the portal identifier. */\n  private keySignal = this.attributeInput<string | null>({ name: 'key', initialValue: null, fromString: (v) => v });\n\n  /** An instance of the PortalService, retrieved from the dependency injector. */\n  private service = inject(PortalService);\n\n  constructor() {\n    super({ shadow: 'none' });\n  }\n\n  public connectedCallback() {\n    this.effect(() => {\n      const key = this.keySignal.get();\n      const node = key ? this.service.get(key).get() : undefined;\n      if (node) {\n        this.root.replaceChildren(node);\n      } else {\n        this.root.replaceChildren();\n      }\n    });\n    super.connectedCallback();\n  }\n\n  /**\n   * Renders the Node received from the PortalService. If no Node is\n   * registered for the key, it renders a default fallback text.\n   * @returns The DocumentFragment to be rendered.\n   */\n  protected render(): Node {\n    return html``;\n  }\n}\n","import { WebComponent, html } from '../components';\nimport { inject } from '../di';\nimport { PortalService } from './portal.service';\n\n/**\n * A component that acts as a rendering source for a portal.\n *\n * It captures all its child nodes and registers them in the `PortalService` under the provided `key`. This allows for rendering\n * the content of this component into the location of a `PortalOutComponent` anywhere in the application.\n */\nexport class PortalInComponent extends WebComponent {\n  public static tag = 'croqueta-portal-in';\n  public static observedAttributes = ['key'];\n\n  /** Input property for the portal identifier. */\n  private keySignal = this.attributeInput<string | null>({ name: 'key', initialValue: null, fromString: (v) => v });\n  private service = inject(PortalService);\n\n  constructor() {\n    super({ shadow: 'none' });\n  }\n\n  override connectedCallback(): void {\n    let prevKey: string | null = null;\n    const nodes = [...this.childNodes];\n    this.effect(() => {\n      const key = this.keySignal.get();\n      if (prevKey && prevKey !== key) {\n        this.service.remove(prevKey);\n      }\n      if (key && prevKey !== key && nodes.length) {\n        const node = document.createDocumentFragment();\n        node.append(...nodes);\n        this.service.update(key, node);\n      }\n      prevKey = key;\n    });\n    super.connectedCallback();\n  }\n\n  override disconnectedCallback(): void {\n    const key = this.keySignal.get();\n    if (key) {\n      this.service.remove(key);\n    }\n    super.disconnectedCallback();\n  }\n\n  protected render() {\n    return html``;\n  }\n}\n","import { provide } from '../di';\nimport { LinkComponent } from './components/link.component';\nimport { Router } from './router';\nimport type { RouterOptions } from './types';\n\n/**\n * Initializes router service and declares the router link component for testing purposes\n * @param options\n */\nexport function provideRouter(options: RouterOptions) {\n  provide(Router, () => new Router(options));\n  customElements.define('router-link', LinkComponent, { extends: 'a' });\n}\n","import type { Destroy } from '../di';\n\n/**\n * Manages the hierarchy of router outlets in the application.\n * It keeps track of nested outlets to ensure correct component rendering order.\n */\nexport class Outlet implements Destroy {\n  private stack: HTMLElement[] = [];\n\n  /**\n   * Registers a new router outlet element.\n   * @param element The outlet element to register.\n   * @returns The depth index of the registered outlet.\n   */\n  public register(element: HTMLElement) {\n    // const parent = this.stack[this.stack.length - 1];\n    // if (parent && !parent.contains(element)) {\n    //   throw new Error('Duplicated router');\n    // }\n    this.stack.push(element);\n    return this.stack.length - 1;\n  }\n\n  /**\n   * Unregisters a router outlet element and all its children.\n   * @param element The outlet element to unregister.\n   */\n  public unregister(element: HTMLElement) {\n    const index = this.stack.indexOf(element);\n    this.stack = this.stack.slice(0, index);\n  }\n\n  /**\n   * Cleans up the outlet stack.\n   */\n  public destroy(): void {\n    this.stack = [];\n  }\n}\n","import { Component, html, registerComponent } from '../../components';\nimport { inject } from '../../di';\nimport { computed, signal } from '../../reactivity';\nimport type { PartialRequired } from '../../types';\nimport { Outlet } from '../outlet';\nimport { Router } from '../router';\nimport type { ActivatedRoute } from '../types';\n\ntype ActivatedComponent = PartialRequired<ActivatedRoute, 'component'>;\n\n/**\n * A component that serves as the main outlet for the application's router.\n * It renders the component associated with the current active route.\n *\n * This component dynamically renders the content managed by the `RouterService`.\n * The `RouterService` is responsible for listening to path changes and updating the 'router'\n * portal with the appropriate component's view.\n *\n * @example\n * ```html\n * <croqueta-router></croqueta-router>\n * ```\n */\nexport class RouterComponent extends Component {\n  public static tag = 'croqueta-router';\n\n  private router = inject(Router);\n  private outlet = inject(Outlet);\n  private activatedComponent = signal<ActivatedComponent | undefined>(undefined);\n\n  public override connectedCallback(): void {\n    const level = this.outlet.register(this);\n    super.connectedCallback();\n    this.effect(() => {\n      const active = this.router.activatedRoutes.get();\n      const found = active.filter((a) => !!a.component).at(level) as ActivatedComponent | undefined;\n      this.activatedComponent.set(found);\n    });\n  }\n\n  public override disconnectedCallback(): void {\n    this.outlet.unregister(this);\n    super.disconnectedCallback();\n  }\n\n  protected render(): Node {\n    const node = computed<Node>(() => {\n      const activated = this.activatedComponent.get();\n      if (activated?.component) {\n        registerComponent(activated.component);\n        const el = document.createElement(activated.component.tag);\n        if (activated.params) {\n          Object.assign(el, activated.params);\n        }\n        if (activated.data) {\n          Object.assign(el, activated.data);\n        }\n        return el;\n      }\n      return document.createTextNode('');\n    });\n    return html`${node}`;\n  }\n}\n","import { signal } from '../../reactivity';\nimport type { RouterStrategy } from './router-strategy.interface';\n\n/**\n * A routing strategy that uses the URL hash (`#`) for client-side navigation.\n * This strategy listens for `hashchange` events to react to URL changes.\n *\n * @example\n * ```ts\n * const hashStrategy = new HashRouterStrategy();\n * ```\n */\nexport class HashRouterStrategy implements RouterStrategy {\n  /**\n   * A Signal that holds the current URL path (the part after the '#') whenever it changes.\n   * It is initialized with the root path `/`.\n   */\n  public path = signal('/');\n\n  /**\n   * Initializes the strategy by setting up a listener for the `hashchange` event\n   * and performing an initial hash check to set the initial path.\n   */\n  constructor() {\n    window.addEventListener('hashchange', this.onHashChange);\n    this.onHashChange();\n  }\n\n  /**\n   * Cleans up resources by removing the `hashchange` event listener.\n   */\n  public destroy(): void {\n    window.removeEventListener('hashchange', this.onHashChange);\n  }\n\n  /**\n   * Navigates to a new path by setting `window.location.hash`.\n   * This action will trigger a `hashchange` event, which is then handled by `onHashChange`.\n   * @param path The new path to navigate to (e.g., '/home').\n   */\n  public async navigate(path: string): Promise<void> {\n    window.location.hash = path;\n  }\n\n  /**\n   * Generates a URL-friendly href string for a given application path.\n   * For this strategy, it prepends a `#` to the path.\n   * @param path The application path.\n   * @returns The formatted href string (e.g., '#/home').\n   */\n  public getHref(path: string): string {\n    return `#${path}`;\n  }\n\n  private onHashChange = (): void => {\n    const path = window.location.hash.slice(1);\n    if (!path) {\n      window.location.hash = '/';\n      return;\n    }\n    if (this.path.get() !== path) {\n      this.path.set(path);\n    }\n  };\n}\n","import { signal } from '../../reactivity';\nimport type { RouterStrategy } from './router-strategy.interface';\n\n/**\n * A routing strategy that uses the browser's History API (`pushState`) for clean, path-based URLs.\n * This strategy listens for `popstate` events to handle browser back/forward navigation.\n *\n * @example\n * ```ts\n * const pathStrategy = new PathRouterStrategy();\n * ```\n */\nexport class PathRouterStrategy implements RouterStrategy {\n  /**\n   * A Signal that holds the current URL path whenever it changes.\n   * It is initialized with the current path at the time of instantiation.\n   */\n  public path = signal('/');\n\n  /**\n   * Initializes the strategy by setting up a listener for the `popstate` event\n   * and performing an initial state check to get the current path.\n   */\n  constructor() {\n    window.addEventListener('popstate', this.onPopState);\n    void this.onPopState();\n  }\n\n  /**\n   * Cleans up resources by removing the `popstate` event listener.\n   */\n  public destroy(): void {\n    window.removeEventListener('popstate', this.onPopState);\n  }\n\n  /**\n   * Navigates to a new path using `history.pushState`.\n   * Since `pushState` does not trigger a `popstate` event, it manually calls `onPopState`\n   * to ensure the application state is updated.\n   * @param path The new path to navigate to (e.g., '/products/123').\n   */\n  public async navigate(path: string): Promise<void> {\n    history.pushState({}, '', path);\n    return this.onPopState(); // pushState doesn't trigger popstate, so we call it manually\n  }\n\n  /**\n   * Generates a URL-friendly href string for a given application path.\n   * For this strategy, it's simply the path itself.\n   * @param path The application path.\n   * @returns The same path, as no special formatting is needed.\n   */\n  public getHref(path: string): string {\n    return path;\n  }\n\n  private onPopState = async (): Promise<void> => {\n    const path = window.location.pathname;\n    if (!path) {\n      await this.navigate('/');\n      return;\n    }\n    if (this.path.get() !== path) {\n      this.path.set(path);\n    }\n  };\n}\n","import type { Selector } from './types';\n\n/**\n * Creates a memoized selector function to retrieve a top-level feature state\n * from the global state object. This is the primary way to select a specific\n * slice of the state tree.\n *\n * @template T The type of the feature state.\n * @param key The key of the feature state in the global state object.\n * @returns A memoized selector function that takes the global state and returns\n * the feature state of type `T`.\n *\n * @example\n * const selectCounterState = createFeatureSelector<{ count: number }>('counter');\n * const state = { counter: { count: 5 } };\n * const counterState = selectCounterState(state); // returns { count: 5 }\n */\nexport function createFeatureSelector<T extends object>(key: string): Selector<T> {\n  return (state: Record<string, any>) => state[key];\n}\n\n/**\n * Creates a memoized selector that computes a derived value from other selectors.\n * The projector function is only re-evaluated if the input values from the\n * selectors have changed, making it efficient for complex state derivations.\n * @param selector1 A sequence of selector functions.\n * @param projector A function that takes the results of the selectors and computes the derived state.\n */\nexport function createSelector<S1, Result>(selector1: Selector<S1>, projector: (s1: S1) => Result): Selector<Result>;\nexport function createSelector<S1, S2, Result>(\n  selector1: Selector<S1>,\n  selector2: Selector<S2>,\n  projector: (s1: S1, s2: S2) => Result\n): Selector<Result>;\nexport function createSelector<S1, S2, S3, Result>(\n  selector1: Selector<S1>,\n  selector2: Selector<S2>,\n  selector3: Selector<S3>,\n  projector: (s1: S1, s2: S2, s3: S3) => Result\n): Selector<Result>;\n/**\n * Creates a memoized selector that computes a derived value from an arbitrary\n * number of other selectors.\n *\n * @param args A sequence of selector functions, followed by a projector function.\n * @returns A new memoized selector that returns the derived state.\n *\n * @example\n * const selectCount = createSelector(selectCounterState, state => state.count);\n */\nexport function createSelector(...args: any[]): Selector<any> {\n  const selectors = args.slice(0, args.length - 1);\n  const projector = args[args.length - 1];\n  return (state: any) => {\n    const inputs = selectors.map((selector) => selector(state));\n    return projector(...inputs);\n  };\n}\n","import type { Actions, Selector, StoreFeatureConfig, StoreFeatureConfigWithSelectors } from './types';\n\n/**\n * Creates a strongly-typed feature configuration object.\n * This helper allows for automatic inference of action and selector types,\n * eliminating the need for explicit `typeof` in variable declarations.\n *\n * @template S The type of the state for this feature.\n * @template A The type of the action creator dictionary.\n * @template Selectors The type of the selector dictionary.\n * @param config The feature configuration object.\n * @returns The same configuration object with inferred types.\n */\nexport function createFeature<S extends object, A extends Actions>(config: StoreFeatureConfig<S, A>): StoreFeatureConfig<S, A>;\nexport function createFeature<S extends object, A extends Actions, Selectors extends Record<string, Selector<unknown>>>(\n  config: StoreFeatureConfigWithSelectors<S, A, Selectors>\n): StoreFeatureConfigWithSelectors<S, A, Selectors>;\nexport function createFeature(config: any): any {\n  return config;\n}\n"],"mappings":"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"}