{"version":3,"sources":["../../../../src/lib/AreRoot/AreRoot.component.ts"],"names":[],"mappings":"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","file":"AreRoot.component.mjs","sourcesContent":["import { A_Caller, A_Context, A_FormatterHelper, A_Inject, A_TYPES__Ctor } from \"@adaas/a-concept\";\nimport { A_Frame } from \"@adaas/a-frame/core\";\nimport { A_Logger } from \"@adaas/a-utils/a-logger\";\nimport { A_Signal, A_SignalState, A_SignalVector } from \"@adaas/a-utils/a-signal\";\nimport { Are, AreNode, AreSignals, AreSignalsMeta, AreSignalsContext } from \"@adaas/are\";\nimport { AreRoute } from \"@adaas/are-html/signals/AreRoute.signal\";\nimport { AreRootCache, AreRootCacheEntry } from \"./AreRootCache.context\";\n\n\n@A_Frame.Define({\n    namespace: 'a-are-html',\n    description: 'The AreRoot component serves as the foundational entry point for the A-Concept Rendering Engine (ARE). It is responsible for initializing the rendering process, managing the root node of the component tree, and handling signal-based rendering logic. The AreRoot component processes incoming signals to determine which child components to render, allowing for dynamic and responsive UI updates based on application state and user interactions.'\n})\nexport class AreRoot extends Are {\n\n    @Are.Template\n    async template(\n        @A_Inject(A_Caller) root: AreNode,\n        @A_Inject(A_Logger) logger: A_Logger,\n        @A_Inject(AreSignalsContext) signalsContext?: AreSignalsContext,\n        @A_Inject(A_SignalState) signalState?: A_SignalState,\n    ) {\n\n        const rootId = root.id;\n\n        // No routing config for this root — but still honour body content or\n        // a 'default' attribute if one is present on the markup.\n        if (signalsContext && !signalsContext.hasRoot(rootId)) {\n            if (!root.content?.trim()) {\n                // Fallback: legacy default= attribute\n                const defaultMatch = root.markup?.match(/\\bdefault=[\"']([^\"']*)[\"']/);\n                const defaultComponent = defaultMatch?.[1];\n                if (defaultComponent) {\n                    root.setContent(`<${defaultComponent}></${defaultComponent}>`);\n                }\n            }\n            // Body content (or none) — tokenizer picks it up without intervention\n            return;\n        }\n\n        // Select from the ACCUMULATED signal state (every signal dispatched so\n        // far), not just the current URL route. Outlets keyed on domain signals\n        // (e.g. a primary-display selector) must reflect the live vector the\n        // moment they mount — even when they mount AFTER the routing signal was\n        // dispatched (a nested outlet inside a just-rendered parent). Using the\n        // same vector + lookup as onSignal keeps initial render and subsequent\n        // updates consistent.\n        const initialVector = this.buildInitialVector(signalState);\n        const renderTarget = this.matchComponent(rootId, initialVector, signalsContext);\n\n        let componentName: string | undefined = renderTarget?.name\n            ? A_FormatterHelper.toKebabCase(renderTarget.name)\n            : undefined;\n\n        // 3. Fall back to body content (the nodes already placed inside the\n        //    <are-root> tag act as the default).  No setContent() call needed —\n        //    the tokenizer will process root.content as-is.\n        if (!componentName) {\n            if (root.content?.trim()) {\n                return;\n            }\n        }\n        // 3.5. Fall back to AreSignalsContext default component for this root.\n        if (!componentName) {\n            const defaultComp = signalsContext?.getDefault(rootId);\n            if (defaultComp?.name) {\n                componentName = A_FormatterHelper.toKebabCase(defaultComp.name);\n            }\n        }\n        // 4. Last resort: legacy default= attribute on the markup.\n        if (!componentName) {\n            const defaultMatch = root.markup?.match(/\\bdefault=[\"']([^\"']*)[\"']/);\n            componentName = defaultMatch?.[1];\n        }\n\n        if (!componentName) {\n            logger.warning('AreRoot: No component found for initial render. Provide body content, a route condition, or a \"default\" attribute.');\n            return;\n        }\n\n        root.setContent(`<${componentName}></${componentName}>`);\n    }\n\n\n    @Are.Signal\n    async onSignal(\n        @A_Inject(A_Caller) root: AreNode,\n        @A_Inject(A_SignalVector) vector: A_SignalVector,\n        @A_Inject(A_Logger) logger: A_Logger,\n        @A_Inject(AreSignalsContext) signalsContext?: AreSignalsContext,\n        @A_Inject(AreRootCache) cache?: AreRootCache,\n    ) {\n        const rootId = root.id;\n\n        // No routing config for this root — signals do not affect its content\n        if (signalsContext && !signalsContext.hasRoot(rootId)) {\n            return;\n        }\n\n        // Resolve the target component for the incoming vector using the SAME\n        // lookup the initial template render uses (root-id conditions first,\n        // then the global pool-filtered meta map).\n        const renderTarget = this.matchComponent(rootId, vector, signalsContext);\n\n        const def = signalsContext?.getDefault(rootId);\n        const componentName = renderTarget?.name\n            ? A_FormatterHelper.toKebabCase(renderTarget.name)\n            : def?.name\n                ? A_FormatterHelper.toKebabCase(def.name)\n                : undefined;\n\n        // No matching condition for this signal vector and no default — clear the outlet.\n        if (!componentName) {\n            for (const child of [...root.children]) {\n                this.stashChild(root, child, signalsContext, cache);\n            }\n            root.setContent('');\n            return;\n        }\n\n        // Guard: if the outlet already shows the same component, do nothing.\n        // Prevents infinite remount loops when a non-routing signal carries a\n        // stale routing signal in the accumulated A_SignalState vector.\n        // node.type is the kebab-case tag name — the most direct and reliable\n        // identifier (no constructor-name resolution, no proxy wrapping issues).\n        const currentChild = root.children[0] as AreNode | undefined;\n        if (currentChild?.type === componentName) {\n            return;\n        }\n\n        // Stash the currently displayed children so routing back to them can be\n        // re-injected instantly from the cache (they are unmounted + detached but\n        // NOT destroyed). Falls back to full teardown when no cache is available.\n        for (const child of [...root.children]) {\n            this.stashChild(root, child, signalsContext, cache);\n        }\n\n        root.setContent(`<${componentName}></${componentName}>`);\n\n        // Fast path: a previously rendered subtree for this component is cached —\n        // re-attach it and re-mount from the preserved scene plan, skipping the\n        // expensive tokenize/init/load/transform/compile pipeline.\n        const cached = cache?.take(root.id, componentName);\n        if (cached) {\n            this.restoreChild(root, cached, signalsContext);\n            return;\n        }\n\n        // Slow path: build the component subtree from scratch.\n        root.tokenize();\n\n        for (let i = 0; i < root.children.length; i++) {\n            const child = root.children[i];\n            child.init();\n\n            const res = child.load();\n            if (res instanceof Promise) {\n                await res;\n            }\n            child.transform();\n\n            child.compile();\n            // The initial mount is atomic (synchronous): the routed subtree is\n            // rendered in one uninterrupted pass so no update can observe a\n            // partially mounted tree. The await is a harmless no-op here.\n            await child.mount();\n        }\n    }\n\n    /**\n     * Resolves the component a vector should render for the given root, mirroring\n     * the priority used everywhere in the routing system:\n     *   1. Root-specific conditions registered on AreSignalsContext.\n     *   2. The global AreSignalsMeta map, restricted to this outlet's pool.\n     *\n     * Passing the pool *into* the meta lookup is critical: without it, the first\n     * globally matching component wins and may belong to a different outlet\n     * (e.g. AisRequirementsPanel for the meta-outlet matching\n     * AisEditorCursorScope) — the pool check would then reject it and the outlet\n     * would fall back to its default, hiding a valid in-pool match (e.g.\n     * AisDiagramTab matching AisSetPrimaryDisplay).\n     *\n     * Returns `undefined` when nothing matches — callers decide whether to use a\n     * configured default, body content, or clear the outlet.\n     */\n    protected matchComponent(\n        rootId: string,\n        vector: A_SignalVector | undefined,\n        signalsContext?: AreSignalsContext,\n    ): A_TYPES__Ctor<Are> | undefined {\n        if (!vector) return undefined;\n\n        // 1. Root-specific conditions.\n        let renderTarget = signalsContext?.findComponentByVector(rootId, vector);\n\n        // 2. Global pool-filtered meta map.\n        if (!renderTarget) {\n            const signalsMeta = A_Context.meta<AreSignalsMeta>(AreSignals);\n            const pool = signalsContext?.getComponentById(rootId);\n            const metaTarget = signalsMeta?.findComponentByVector(\n                vector,\n                pool?.length ? pool : undefined,\n                rootId,\n            );\n            if (metaTarget && (!pool?.length || pool.includes(metaTarget))) {\n                renderTarget = metaTarget;\n            }\n        }\n\n        return renderTarget as A_TYPES__Ctor<Are> | undefined;\n    }\n\n    /**\n     * Builds the vector used for the INITIAL render. It is seeded from the\n     * accumulated signal state (every signal dispatched on the bus so far) so a\n     * freshly-mounted outlet reflects the live application state immediately,\n     * not just on the next signal tick. The current URL route is appended when\n     * no AreRoute is already present in the state, so route-driven outlets still\n     * resolve on the very first paint (before AreRouteWatcher has dispatched).\n     */\n    protected buildInitialVector(signalState?: A_SignalState): A_SignalVector {\n        const signals: A_Signal[] = [];\n\n        if (signalState) {\n            for (const signal of signalState.toVector()) {\n                if (signal) signals.push(signal);\n            }\n        }\n\n        if (!signals.some(signal => signal instanceof AreRoute)) {\n            try {\n                const currentRoute = AreRoute.default();\n                if (currentRoute) signals.push(currentRoute);\n            } catch {\n                // Non-browser environment (no document) — route is simply absent.\n            }\n        }\n\n        return new A_SignalVector(signals);\n    }\n\n    /**\n     * Detach a displayed child subtree from the outlet and stash it in the cache\n     * for fast re-injection later. The subtree is unmounted (its scene plan is\n     * preserved) and deregistered from the root scope, but NOT destroyed. The\n     * nodes that were subscribed to the signal bus are unsubscribed while cached\n     * so the detached DOM never reacts to signals, and recorded so they can be\n     * re-subscribed verbatim on restore.\n     *\n     * When no cache is available, or the LRU evicts an entry, the affected\n     * subtree is fully destroyed.\n     */\n    protected stashChild(\n        root: AreNode,\n        child: AreNode,\n        signalsContext: AreSignalsContext | undefined,\n        cache: AreRootCache | undefined,\n    ): void {\n        const tag = child.type;\n\n        child.unmount();\n\n        // Collect exactly the nodes that are currently subscribed within this\n        // subtree, then unsubscribe them. Without this, AreSignals keeps\n        // delivering vectors to a detached subtree that would update reverted\n        // DOM (unmount does not deactivate the scene).\n        const subscribers = signalsContext\n            ? this.collectSubscribers(child, signalsContext)\n            : [];\n        for (const node of subscribers) {\n            signalsContext?.unsubscribe(node);\n        }\n\n        // Deregister from the root scope (the \"deregister node from parent\").\n        root.removeChild(child);\n\n        if (!cache) {\n            void child.destroy();\n            return;\n        }\n\n        const evicted = cache.put(root.id, tag, { node: child, subscribers });\n        for (const entry of evicted) {\n            // Evicted entries are already unmounted + unsubscribed + detached.\n            void entry.node.destroy();\n        }\n    }\n\n    /**\n     * Re-attach a cached subtree to the outlet and re-mount it from its preserved\n     * scene plan, re-subscribing exactly the nodes that were subscribed before it\n     * was cached.\n     */\n    protected restoreChild(\n        root: AreNode,\n        entry: AreRootCacheEntry,\n        signalsContext: AreSignalsContext | undefined,\n    ): void {\n        const child = entry.node;\n\n        root.addChild(child);\n\n        for (const node of entry.subscribers) {\n            signalsContext?.subscribe(node);\n        }\n\n        child.mount();\n    }\n\n    /**\n     * Walk a subtree and collect the nodes currently registered as signal\n     * subscribers. Mirrors the subscription performed at init time in\n     * AreHTMLLifecycle (component nodes and root nodes) without depending on the\n     * concrete node classes — it simply intersects the subtree with the live\n     * subscriber registry.\n     */\n    protected collectSubscribers(\n        node: AreNode,\n        signalsContext: AreSignalsContext,\n    ): AreNode[] {\n        const result: AreNode[] = [];\n        const queue: AreNode[] = [node];\n        while (queue.length > 0) {\n            const current = queue.shift()!;\n            if (signalsContext.subscribers.has(current)) {\n                result.push(current);\n            }\n            queue.push(...current.children);\n        }\n        return result;\n    }\n}\n"]}