{"version":3,"sources":["../../../../src/lib/AreDynamic/AreDynamic.component.ts"],"names":[],"mappings":";;;;;AAgDO,IAAM,UAAA,GAAN,cAAyB,GAAA,CAAI;AAAA,EAA7B,WAAA,GAAA;AAAA,IAAA,KAAA,CAAA,GAAA,SAAA,CAAA;AAEH,IAAA,IAAA,CAAA,KAAA,GAA2C;AAAA,MACvC,SAAA,EAAW,EAAE,IAAA,EAAM,QAAA,EAAU,SAAS,EAAA,EAAG;AAAA,MACzC,OAAO,EAAE,IAAA,EAAM,QAAA,EAAU,OAAA,EAAS,EAAC;AAAE,KACzC;AAAA,EAAA;AAAA,EAGA,SAA6B,IAAA,EAAqB;AAC9C,IAAA,IAAA,CAAK,WAAW,EAAE,CAAA;AAAA,EACtB;AAAA,EAGA,KAAyB,KAAA,EAAuB;AAC5C,IAAA,KAAA,CAAM,IAAI,EAAE,SAAA,EAAW,IAAI,KAAA,EAAO,IAAI,CAAA;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASU,WAAW,IAAA,EAAsB;AACvC,IAAA,OAAO,iBAAA,CAAkB,YAAY,IAAI,CAAA;AAAA,EAC7C;AAAA,EAGA,MAAM,OAAA,CACkB,IAAA,EACA,KAAA,EACP;AACb,IAAA,MAAM,OAAO,MAAA,CAAO,KAAA,CAAM,GAAA,CAAI,WAAW,KAAK,EAAE,CAAA;AAMhD,IAAA,IAAI,CAAC,IAAA,EAAM;AACP,MAAA;AAAA,IACJ;AAEA,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,UAAA,CAAW,IAAI,CAAA;AAQhC,IAAA,IAAI,IAAA,CAAK,QAAA,CAAS,CAAC,CAAA,EAAG,SAAS,GAAA,EAAK;AAChC,MAAA;AAAA,IACJ;AAEA,IAAA,IAAA,CAAK,UAAA,CAAW,CAAA,CAAA,EAAI,GAAG,CAAA,kBAAA,EAAqB,GAAG,CAAA,CAAA,CAAG,CAAA;AAClD,IAAA,MAAM,KAAK,MAAA,EAAO;AAAA,EACtB;AACJ;AAlDI,eAAA,CAAA;AAAA,EADC,GAAA,CAAI,QAAA;AAAA,EACK,4BAAS,QAAQ,CAAA;AAAA,CAAA,EARlB,UAAA,CAQT,SAAA,EAAA,UAAA,EAAA,CAAA,CAAA;AAKA,eAAA,CAAA;AAAA,EADC,GAAA,CAAI,IAAA;AAAA,EACC,4BAAS,QAAQ,CAAA;AAAA,CAAA,EAbd,UAAA,CAaT,SAAA,EAAA,MAAA,EAAA,CAAA,CAAA;AAgBM,eAAA,CAAA;AAAA,EADL,GAAA,CAAI,YAAA;AAAA,EAEA,4BAAS,QAAQ,CAAA,CAAA;AAAA,EACjB,4BAAS,QAAQ,CAAA;AAAA,CAAA,EA/Bb,UAAA,CA6BH,SAAA,EAAA,SAAA,EAAA,CAAA,CAAA;AA7BG,UAAA,GAAN,eAAA,CAAA;AAAA,EAJN,QAAQ,MAAA,CAAO;AAAA,IACZ,SAAA,EAAW,YAAA;AAAA,IACX,WAAA,EAAa;AAAA,GAChB;AAAA,CAAA,EACY,UAAA,CAAA","file":"AreDynamic.component.mjs","sourcesContent":["import { A_Caller, A_FormatterHelper, A_Inject } from '@adaas/a-concept';\nimport { A_Frame } from '@adaas/a-frame/core';\nimport { Are, ArePropDefinition, AreNode, AreStore } from '@adaas/are';\n\n/**\n * AreDynamic — renders a component chosen at **runtime by name**, the same way\n * {@link AreRoot} renders a routed component, but driven by a prop instead of a\n * signal vector.\n *\n * ## Why a post-mount hook (not a template)\n *\n * The `component` name and its `props` arrive as **props**, which the ARE\n * compiler injects during the *compile* phase — AFTER `@Are.Template`/`@Are.Data`\n * run. So the concrete tag is unknown at template time. Once the props are\n * available in `@Are.onAfterMount`, this mirrors `AreRoot.onSignal`:\n *\n *   1. resolve `component` → the concrete kebab tag (see {@link resolveTag});\n *   2. `node.setContent(`<tag :props=\"props\"></tag>`)`; the `:props` binding is\n *      evaluated against THIS component's store (where `props` was injected),\n *      so it reactively re-injects into the concrete component's own store;\n *   3. `await node.render()` — the engine's `tokenize → init → load → transform\n *      → compile → mount` pipeline for the new child subtree. `render()` is\n *      idempotent (it clears any previous subtree first), so a props change that\n *      swaps the concrete tag rebuilds cleanly with no duplicate/stale children.\n *\n * ## Use inside a `$for`\n *\n * The canonical use is one `<are-dynamic>` per item inside a store-backed\n * `$for`, so every item mounts an independent, real Are component chosen by\n * `item.component`. `@Are.onAfterMount` re-runs on EVERY (re)mount — including\n * when an `AreRoot` outlet STASHES the subtree (unmount, keep in `AreRootCache`)\n * and later RESTORES it (`child.mount()`) on a tab switch. The concrete child\n * survives the stash, so the \"already mounted\" guard below skips the rebuild on\n * restore (a per-item perf win; mirrors `AreRoot` / `LazyOutlet`).\n *\n * ## Custom name→tag resolution\n *\n * By default `component` is resolved with `A_FormatterHelper.toKebabCase` — the\n * exact convention the engine uses to register and look up component tags (same\n * as `AreRoot`). Applications that address components by a short alias (e.g. a\n * chat message `component: 'card'`) subclass `AreDynamic` and override\n * {@link resolveTag} to map the alias to the concrete tag; all lifecycle\n * behaviour is inherited unchanged.\n */\n@A_Frame.Define({\n    namespace: 'a-are-html',\n    description: 'Renders a component chosen at runtime by name. Receives a `component` (name) and a `props` payload; resolves the concrete tag (kebab-case by default) and mounts it via the engine pipeline (mirrors AreRoot, driven by a prop). Designed to be used inside a $for to render a heterogeneous list of components.',\n})\nexport class AreDynamic extends Are {\n\n    props: Record<string, ArePropDefinition> = {\n        component: { type: 'string', default: '' },\n        props: { type: 'object', default: {} },\n    };\n\n    @Are.Template\n    template(@A_Inject(A_Caller) node: AreNode): void {\n        node.setContent('');\n    }\n\n    @Are.Data\n    data(@A_Inject(AreStore) store: AreStore): void {\n        store.set({ component: '', props: {} });\n    }\n\n    /**\n     * Resolve the `component` prop value to the concrete engine tag.\n     *\n     * Default: `A_FormatterHelper.toKebabCase(name)` — the convention the engine\n     * uses to register component tags (same as `AreRoot`). Override to plug in\n     * an application-specific alias→tag map.\n     */\n    protected resolveTag(name: string): string {\n        return A_FormatterHelper.toKebabCase(name);\n    }\n\n    @Are.onAfterMount\n    async onMount(\n        @A_Inject(A_Caller) node: AreNode,\n        @A_Inject(AreStore) store: AreStore,\n    ): Promise<void> {\n        const name = String(store.get('component') ?? '');\n\n        // A `$for` clones this component per item via `cloneWithScope()`, which\n        // leaves the ORIGINAL element as a detached anchor with a fresh scope\n        // and the default (empty) `component`. A blank name means \"nothing to\n        // render\", so bail out before touching the tree.\n        if (!name) {\n            return;\n        }\n\n        const tag = this.resolveTag(name);\n\n        // `@Are.onAfterMount` re-runs on EVERY (re)mount — including when an\n        // `AreRoot` outlet stashes this subtree into `AreRootCache` and later\n        // restores it (`child.mount()`). The concrete child built on the first\n        // mount survives the stash, so on restore it is already present and its\n        // DOM is re-applied from the preserved scene plan. Skip the rebuild when\n        // the right child is already mounted (mirrors `AreRoot` / `LazyOutlet`).\n        if (node.children[0]?.type === tag) {\n            return;\n        }\n\n        node.setContent(`<${tag} :props=\"props\"></${tag}>`);\n        await node.render();\n    }\n}\n"]}