{"version":3,"file":"index.mjs","names":[],"sources":["../src/constants.ts","../src/utils/util.ts","../src/index.ts"],"sourcesContent":["export const GLOBAL_CONTEXT_KEY = '__GLOBAL_CONTEXT__';\n","export const isBrowser = typeof window !== 'undefined';\n","import { GLOBAL_CONTEXT_KEY } from './constants';\nimport { isBrowser } from './utils/util';\n\n/**\n * Parameters for mounting a component instance.\n * @property {Element} element - The DOM element to mount the component into.\n * @property {string} componentName - The name of the component to mount.\n */\nexport type MountParams = {\n  element: Element;\n  componentName: string;\n};\n\n/**\n * Function signature for mounting a component instance.\n * @param {MountParams} params - The parameters for mounting.\n */\nexport type MountFunction = (params: MountParams) => void | Promise<void>;\n\n/**\n * Registry for a component version.\n * @property {MountFunction} mountFunction - The function to mount the component.\n * @property {Record<string, any>} [manifest] - Optional manifest for the component version.\n */\ntype ComponentRegistry = {\n  mountFunction: MountFunction;\n  manifest?: Record<string, any>;\n};\n\n/**\n * Options for registering a component.\n * @property {string} componentName - The name of the component.\n * @property {string} version - The version of the component.\n * @property {MountFunction} mountFunction - The function to mount the component.\n * @property {boolean} [autoMount] - Whether to auto-mount on registration when not in global context. Defaults to true.\n */\nexport type RegisterComponentOptions = {\n  componentName: string;\n  version: string;\n  mountFunction: MountFunction;\n  autoMount?: boolean;\n};\n\n/**\n * Orchestrates registration and mounting of components by name and version.\n * Implements a singleton pattern.\n */\nclass ComponentOrchestrator {\n  private static instance: ComponentOrchestrator;\n  private componentMap: Map<string, Map<string, ComponentRegistry>> = new Map();\n  private pendingResolves: Map<string, ((...args: any[]) => void)[]> = new Map();\n\n  private constructor() {}\n\n  /**\n   * Returns the singleton instance of ComponentOrchestrator.\n   */\n  public static getInstance(): ComponentOrchestrator {\n    if (!ComponentOrchestrator.instance) {\n      ComponentOrchestrator.instance = new ComponentOrchestrator();\n    }\n    return ComponentOrchestrator.instance;\n  }\n\n  /**\n   * Ensures a component entry exists in the map for the given name.\n   * @param {string} componentName - The name of the component.\n   * @returns {Map<string, ComponentRegistry>} The version map for the component.\n   */\n  private ensureComponentEntry(componentName: string) {\n    if (!this.componentMap.has(componentName)) {\n      this.componentMap.set(componentName, new Map());\n    }\n    return this.componentMap.get(componentName)!;\n  }\n\n  /**\n   * Adds or overwrites a component version in the registry.\n   * @param {string} componentName - The name of the component.\n   * @param {string} version - The version of the component.\n   * @param {ComponentRegistry} registry - The registry object for the version.\n   */\n  public addComponent(componentName: string, version: string, registry: ComponentRegistry): void {\n    const versionMap = this.ensureComponentEntry(componentName);\n\n    if (versionMap.has(version)) {\n      console.warn(\n        `Component ${componentName} with version ${version} is already registered. Overwriting existing version.`,\n      );\n    }\n\n    versionMap.set(version, registry);\n\n    // if someone was waiting for this component → resolve\n    const key = `${componentName}@${version}`;\n    const resolves = this.pendingResolves.get(key);\n    if (resolves) {\n      resolves.forEach((resolveFn) => resolveFn(registry));\n      this.pendingResolves.delete(key);\n    }\n  }\n\n  /**\n   * Mounts all DOM instances of a component for a given name and version.\n   * @param {string} componentName - The name of the component.\n   * @param {string} version - The version of the component.\n   */\n  public mountComponentInstances(componentName: string, version: string): void {\n    if (!isBrowser) return;\n\n    const versionMap = this.componentMap.get(componentName);\n    if (!versionMap) {\n      console.warn(`Component ${componentName} is not registered.`);\n      return;\n    }\n\n    const registry = versionMap.get(version);\n    if (!registry) {\n      console.warn(`Version ${version} of component ${componentName} is not registered.`);\n      return;\n    }\n\n    const { mountFunction } = registry;\n    const componentElements = document.querySelectorAll(\n      `div[data-component-name=\"${componentName}\"]`,\n    ) as NodeListOf<HTMLElement>;\n\n    componentElements.forEach((element) => {\n      if (element.dataset.mounted === 'true') {\n        return;\n      }\n\n      this.mountElement(mountFunction, element, componentName);\n    });\n  }\n\n  /**\n   * Mounts a single specific element without querying the document.\n   * Useful when the host framework already knows which element to mount.\n   * @param {string} componentName - The name of the component.\n   * @param {string} version - The version of the component.\n   * @param {HTMLElement} element - The specific DOM element to mount.\n   * @returns {Promise<void>} Resolves when mount succeeds, rejects on failure.\n   */\n  public async mountSingleElement(componentName: string, version: string, element: HTMLElement): Promise<void> {\n    if (!isBrowser) return;\n\n    const versionMap = this.componentMap.get(componentName);\n    if (!versionMap) {\n      throw new Error(`Component ${componentName} is not registered.`);\n    }\n\n    const registry = versionMap.get(version);\n    if (!registry) {\n      throw new Error(`Version ${version} of component ${componentName} is not registered.`);\n    }\n\n    if (element.dataset.mounted === 'true') {\n      return;\n    }\n\n    try {\n      await registry.mountFunction({ element, componentName });\n      element.dataset.mounted = 'true';\n    } catch (error) {\n      element.dataset.mounted = 'error';\n      throw error;\n    }\n  }\n\n  /**\n   * Internal helper to mount an element with error handling.\n   */\n  private mountElement(mountFunction: MountFunction, element: HTMLElement, componentName: string): void {\n    try {\n      const result = mountFunction({ element, componentName });\n      if (result && typeof (result as Promise<void>).catch === 'function') {\n        (result as Promise<void>)\n          .then(() => {\n            element.dataset.mounted = 'true';\n          })\n          .catch((error) => {\n            element.dataset.mounted = 'error';\n            console.error(`Failed to mount component ${componentName}:`, error);\n          });\n      } else {\n        element.dataset.mounted = 'true';\n      }\n    } catch (error) {\n      element.dataset.mounted = 'error';\n      console.error(`Failed to mount component ${componentName}:`, error);\n    }\n  }\n\n  /**\n   * Registers a component and mounts it if __GLOBAL_CONTEXT_KEY is not present. (supporting legacy behavior)\n   * @param {RegisterComponentOptions} options - The registration options.\n   */\n  public registerComponent(options: RegisterComponentOptions): void {\n    const { componentName, version, mountFunction, autoMount = true } = options;\n\n    this.addComponent(componentName, version, { mountFunction });\n\n    if (!autoMount) return;\n\n    const globalContextPresent =\n      isBrowser &&\n      (GLOBAL_CONTEXT_KEY in window ||\n        (window.top !== undefined && window.top !== null && GLOBAL_CONTEXT_KEY in window.top));\n\n    if (isBrowser && !globalContextPresent) {\n      this.mountComponentInstances(componentName, version);\n    }\n  }\n\n  /**\n   * Gets the mount function for a component version.\n   * @param {string} componentName - The name of the component.\n   * @param {string} version - The version of the component.\n   * @returns {MountFunction | undefined} The mount function, if registered.\n   */\n  public getComponentMount(componentName: string, version: string) {\n    return this.componentMap.get(componentName)?.get(version)?.mountFunction;\n  }\n\n  /**\n   * Gets the manifest for a component version.\n   * @param {string} componentName - The name of the component.\n   * @param {string} version - The version of the component.\n   * @returns {Record<string, any> | undefined} The manifest, if set.\n   */\n  public getComponentManifest(componentName: string, version: string) {\n    return this.componentMap.get(componentName)?.get(version)?.manifest;\n  }\n\n  /**\n   * Sets the manifest for a component version.\n   * @param {string} componentName - The name of the component.\n   * @param {string} version - The version of the component.\n   * @param {Record<string, any>} manifest - The manifest object to set.\n   */\n  public setComponentManifest(componentName: string, version: string, manifest: Record<string, any>) {\n    const versionMap = this.componentMap.get(componentName);\n    if (!versionMap) {\n      console.warn(`Component ${componentName} is not registered. Cannot set manifest.`);\n      return;\n    }\n\n    const registry = versionMap.get(version);\n    if (registry) {\n      registry.manifest = manifest;\n    } else {\n      console.warn(`Component ${componentName} version ${version} is not registered. Cannot set manifest.`);\n    }\n  }\n\n  /**\n   * Gets the entire component map.\n   * @returns {Map<string, Map<string, ComponentRegistry>>} The component map.\n   */\n  public getComponentsMap() {\n    return this.componentMap;\n  }\n\n  /**\n   * Promise that waits for component registration to resolve timing issues when registering components in the componentMap.\n   * @param componentName - The component you are waiting for\n   * @param version - The version you are waiting for\n   * @returns {Promise<Pick<RegisterComponentOptions, 'componentName' & 'version'>>}\n   */\n  public waitForComponentRegistration(\n    componentName: string,\n    version: string,\n    timeoutMs?: number,\n  ): Promise<Pick<RegisterComponentOptions, 'componentName' | 'version'>> {\n    if (this.componentMap.get(componentName)?.has(version)) {\n      return Promise.resolve({ componentName, version });\n    }\n\n    const key = `${componentName}@${version}`;\n    return new Promise<Pick<RegisterComponentOptions, 'componentName' | 'version'>>((resolve, reject) => {\n      let timeoutId: ReturnType<typeof setTimeout> | undefined;\n\n      const resolveFn = () => {\n        if (timeoutId) clearTimeout(timeoutId);\n        resolve({ componentName, version });\n      };\n\n      if (!this.pendingResolves.has(key)) {\n        this.pendingResolves.set(key, []);\n      }\n      this.pendingResolves.get(key)!.push(resolveFn);\n\n      if (timeoutMs !== undefined && timeoutMs > 0) {\n        timeoutId = setTimeout(() => {\n          const resolves = this.pendingResolves.get(key);\n          if (resolves) {\n            const idx = resolves.indexOf(resolveFn);\n            if (idx !== -1) resolves.splice(idx, 1);\n            if (resolves.length === 0) this.pendingResolves.delete(key);\n          }\n          reject(\n            new Error(`Timed out waiting for component ${componentName}@${version} to register (${timeoutMs}ms).`),\n          );\n        }, timeoutMs);\n      }\n    });\n  }\n}\n\n// Singleton instance\nconst componentOrchestratorInstance = ComponentOrchestrator.getInstance();\n\n/**\n * Gets the mount function for a component version.\n * @param {string} componentName - The name of the component.\n * @param {string} version - The version of the component.\n * @returns {MountFunction | undefined} The mount function, if registered.\n */\nexport const getComponentMount = (componentName: string, version: string) =>\n  componentOrchestratorInstance.getComponentMount(componentName, version);\n\n/**\n * Gets the manifest for a component version.\n * @param {string} componentName - The name of the component.\n * @param {string} version - The version of the component.\n * @returns {Record<string, any> | undefined} The manifest, if set.\n */\nexport const getComponentManifest = (componentName: string, version: string) =>\n  componentOrchestratorInstance.getComponentManifest(componentName, version);\n\n/**\n * Adds or overwrites a component version in the registry.\n * @param {string} componentName - The name of the component.\n * @param {string} version - The version of the component.\n * @param {ComponentRegistry} registry - The registry object for the version.\n */\nexport const addComponent = (componentName: string, version: string, registry: ComponentRegistry) =>\n  componentOrchestratorInstance.addComponent(componentName, version, registry);\n\n/**\n * Gets the entire component map.\n * @returns {Map<string, Map<string, ComponentRegistry>>} The component map.\n */\nexport const getComponentMap = () => componentOrchestratorInstance.getComponentsMap();\n\n/**\n * Registers a component and mounts it if not in the global context.\n * @param {RegisterComponentOptions} options - The registration options.\n */\nexport const registerComponent = (options: RegisterComponentOptions) =>\n  componentOrchestratorInstance.registerComponent(options);\n\n/**\n * Sets the manifest for a component version.\n * @param {string} componentName - The name of the component.\n * @param {string} version - The version of the component.\n * @param {Record<string, any>} manifest - The manifest object to set.\n */\nexport const setComponentManifest = (componentName: string, version: string, manifest: Record<string, any>) =>\n  componentOrchestratorInstance.setComponentManifest(componentName, version, manifest);\n\n/**\n * Mounts all DOM instances of a component for a given name and version.\n * @param {string} componentName - The name of the component.\n * @param {string} version - The version of the component.\n */\nexport const mountComponentInstances = (componentName: string, version: string) =>\n  componentOrchestratorInstance.mountComponentInstances(componentName, version);\n\n/**\n * Mounts a single specific element without querying the document.\n * @param {string} componentName - The name of the component.\n * @param {string} version - The version of the component.\n * @param {HTMLElement} element - The specific DOM element to mount.\n * @returns {Promise<void>} Resolves when mount succeeds, rejects on failure.\n */\nexport const mountSingleElement = (componentName: string, version: string, element: HTMLElement) =>\n  componentOrchestratorInstance.mountSingleElement(componentName, version, element);\n\n/**\n * Promise that waits for component registration to resolve timing issues when registering components in the componentMap.\n * @param componentName - The component you are waiting for\n * @param version - The version you are waiting for\n * @param timeoutMs - Optional timeout in ms. If provided and registration doesn't happen in time, the promise rejects.\n * @returns {Promise<Pick<RegisterComponentOptions, 'componentName' & 'version'>>}\n */\nexport const waitForComponentRegistration = (componentName: string, version: string, timeoutMs?: number) =>\n  componentOrchestratorInstance.waitForComponentRegistration(componentName, version, timeoutMs);\n"],"mappings":"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"}