@adaas/are-html 0.0.13 → 0.0.15
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/dist/browser/index.mjs +24 -2
- package/dist/browser/index.mjs.map +1 -1
- package/dist/node/lib/AreRoot/AreRoot.component.js +24 -2
- package/dist/node/lib/AreRoot/AreRoot.component.js.map +1 -1
- package/dist/node/lib/AreRoot/AreRoot.component.mjs +24 -2
- package/dist/node/lib/AreRoot/AreRoot.component.mjs.map +1 -1
- package/package.json +3 -3
- package/src/lib/AreRoot/AreRoot.component.ts +36 -5
|
@@ -47,7 +47,13 @@ exports.AreRoot = class AreRoot extends are.Are {
|
|
|
47
47
|
let renderTarget = signalsContext?.findComponentByVector(rootId, initialVector);
|
|
48
48
|
if (!renderTarget) {
|
|
49
49
|
const signalsMeta = aConcept.A_Context.meta(are.AreSignals);
|
|
50
|
-
|
|
50
|
+
const metaTarget = signalsMeta?.findComponentByVector(initialVector);
|
|
51
|
+
if (metaTarget) {
|
|
52
|
+
const pool = signalsContext?.getComponentById(rootId);
|
|
53
|
+
if (!pool?.length || pool.includes(metaTarget)) {
|
|
54
|
+
renderTarget = metaTarget;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
51
57
|
}
|
|
52
58
|
if (renderTarget?.name) {
|
|
53
59
|
componentName = aConcept.A_FormatterHelper.toKebabCase(renderTarget.name);
|
|
@@ -58,6 +64,12 @@ exports.AreRoot = class AreRoot extends are.Are {
|
|
|
58
64
|
return;
|
|
59
65
|
}
|
|
60
66
|
}
|
|
67
|
+
if (!componentName) {
|
|
68
|
+
const defaultComp = signalsContext?.getDefault(rootId);
|
|
69
|
+
if (defaultComp?.name) {
|
|
70
|
+
componentName = aConcept.A_FormatterHelper.toKebabCase(defaultComp.name);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
61
73
|
if (!componentName) {
|
|
62
74
|
const defaultMatch = root.markup?.match(/\bdefault=["']([^"']*)["']/);
|
|
63
75
|
componentName = defaultMatch?.[1];
|
|
@@ -76,12 +88,22 @@ exports.AreRoot = class AreRoot extends are.Are {
|
|
|
76
88
|
let renderTarget = signalsContext?.findComponentByVector(rootId, vector);
|
|
77
89
|
if (!renderTarget) {
|
|
78
90
|
const signalsMeta = aConcept.A_Context.meta(are.AreSignals);
|
|
79
|
-
|
|
91
|
+
const metaTarget = signalsMeta?.findComponentByVector(vector);
|
|
92
|
+
if (metaTarget) {
|
|
93
|
+
const pool = signalsContext?.getComponentById(rootId);
|
|
94
|
+
if (!pool?.length || pool.includes(metaTarget)) {
|
|
95
|
+
renderTarget = metaTarget;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
80
98
|
}
|
|
81
99
|
const componentName = renderTarget?.name ? aConcept.A_FormatterHelper.toKebabCase(renderTarget.name) : store.get("default");
|
|
82
100
|
if (!componentName) {
|
|
83
101
|
return;
|
|
84
102
|
}
|
|
103
|
+
const currentChild = root.children[0];
|
|
104
|
+
if (currentChild?.type === componentName) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
85
107
|
root.setContent(`<${componentName}></${componentName}>`);
|
|
86
108
|
for (let i = 0; i < root.children.length; i++) {
|
|
87
109
|
const child = root.children[i];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/lib/AreRoot/AreRoot.component.ts"],"names":["AreRoot","Are","AreRoute","A_SignalVector","A_Context","AreSignals","A_FormatterHelper","A_Caller","A_Logger","AreSignalsContext","AreStore","A_Frame"],"mappings":";;;;;;;;;;;;;;;;;;;;AAYaA,eAAA,GAAN,sBAAsBC,OAAA,CAAI;AAAA,EAA1B,WAAA,GAAA;AAAA,IAAA,KAAA,CAAA,GAAA,SAAA,CAAA;AAEH,IAAA,IAAA,CAAA,KAAA,GAA2C;AAAA,MACvC,OAAA,EAAS;AAAA,QACL,IAAA,EAAM,QAAA;AAAA,QACN,OAAA,EAAS;AAAA;AACb,KACJ;AAAA,EAAA;AAAA,EAIA,MAAM,QAAA,CACkB,IAAA,EACA,MAAA,EACS,cAAA,EAC/B;AAEE,IAAA,MAAM,SAAS,IAAA,CAAK,EAAA;AAIpB,IAAA,IAAI,cAAA,IAAkB,CAAC,cAAA,CAAe,OAAA,CAAQ,MAAM,CAAA,EAAG;AACnD,MAAA,IAAI,CAAC,IAAA,CAAK,OAAA,EAAS,IAAA,EAAK,EAAG;AAEvB,QAAA,MAAM,YAAA,GAAe,IAAA,CAAK,MAAA,EAAQ,KAAA,CAAM,4BAA4B,CAAA;AACpE,QAAA,MAAM,gBAAA,GAAmB,eAAe,CAAC,CAAA;AACzC,QAAA,IAAI,gBAAA,EAAkB;AAClB,UAAA,IAAA,CAAK,UAAA,CAAW,CAAA,CAAA,EAAI,gBAAgB,CAAA,GAAA,EAAM,gBAAgB,CAAA,CAAA,CAAG,CAAA;AAAA,QACjE;AAAA,MACJ;AAEA,MAAA;AAAA,IACJ;AAEA,IAAA,MAAM,YAAA,GAAeC,yBAAS,OAAA,EAAQ;AAEtC,IAAA,IAAI,aAAA;AAEJ,IAAA,IAAI,YAAA,EAAc;AACd,MAAA,MAAM,aAAA,GAAgB,IAAIC,sBAAA,CAAe,CAAC,YAAY,CAAC,CAAA;AAGvD,MAAA,IAAI,YAAA,GAAe,cAAA,EAAgB,qBAAA,CAAsB,MAAA,EAAQ,aAAa,CAAA;AAG9E,MAAA,IAAI,CAAC,YAAA,EAAc;AACf,QAAA,MAAM,WAAA,GAAcC,kBAAA,CAAU,IAAA,CAAqBC,cAAU,CAAA;AAC7D,QAAA,YAAA,GAAe,WAAA,EAAa,sBAAsB,aAAa,CAAA;AAAA,MACnE;AAEA,MAAA,IAAI,cAAc,IAAA,EAAM;AACpB,QAAA,aAAA,GAAgBC,0BAAA,CAAkB,WAAA,CAAY,YAAA,CAAa,IAAI,CAAA;AAAA,MACnE;AAAA,IACJ;AAKA,IAAA,IAAI,CAAC,aAAA,EAAe;AAChB,MAAA,IAAI,IAAA,CAAK,OAAA,EAAS,IAAA,EAAK,EAAG;AACtB,QAAA;AAAA,MACJ;AAAA,IACJ;AAGA,IAAA,IAAI,CAAC,aAAA,EAAe;AAChB,MAAA,MAAM,YAAA,GAAe,IAAA,CAAK,MAAA,EAAQ,KAAA,CAAM,4BAA4B,CAAA;AACpE,MAAA,aAAA,GAAgB,eAAe,CAAC,CAAA;AAAA,IACpC;AAEA,IAAA,IAAI,CAAC,aAAA,EAAe;AAChB,MAAA,MAAA,CAAO,QAAQ,oHAAoH,CAAA;AACnI,MAAA;AAAA,IACJ;AAEA,IAAA,IAAA,CAAK,UAAA,CAAW,CAAA,CAAA,EAAI,aAAa,CAAA,GAAA,EAAM,aAAa,CAAA,CAAA,CAAG,CAAA;AAAA,EAC3D;AAAA,EAIA,MAAM,QAAA,CACkB,IAAA,EACM,MAAA,EACN,KAAA,EACA,QACS,cAAA,EAC/B;AACE,IAAA,MAAM,SAAS,IAAA,CAAK,EAAA;AAGpB,IAAA,IAAI,cAAA,IAAkB,CAAC,cAAA,CAAe,OAAA,CAAQ,MAAM,CAAA,EAAG;AACnD,MAAA;AAAA,IACJ;AAGA,IAAA,IAAI,YAAA,GAAe,cAAA,EAAgB,qBAAA,CAAsB,MAAA,EAAQ,MAAM,CAAA;AAGvE,IAAA,IAAI,CAAC,YAAA,EAAc;AACf,MAAA,MAAM,WAAA,GAAcF,kBAAA,CAAU,IAAA,CAAqBC,cAAU,CAAA;AAC7D,MAAA,YAAA,GAAe,WAAA,EAAa,sBAAsB,MAAM,CAAA;AAAA,IAC5D;AAEA,IAAA,MAAM,aAAA,GAAgB,YAAA,EAAc,IAAA,GAC9BC,0BAAA,CAAkB,WAAA,CAAY,aAAa,IAAI,CAAA,GAC/C,KAAA,CAAM,GAAA,CAAI,SAAS,CAAA;AAIzB,IAAA,IAAI,CAAC,aAAA,EAAe;AAChB,MAAA;AAAA,IACJ;AAEA,IAAA,IAAA,CAAK,UAAA,CAAW,CAAA,CAAA,EAAI,aAAa,CAAA,GAAA,EAAM,aAAa,CAAA,CAAA,CAAG,CAAA;AAKvD,IAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,IAAA,CAAK,QAAA,CAAS,QAAQ,CAAA,EAAA,EAAK;AAC3C,MAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,QAAA,CAAS,CAAC,CAAA;AAC7B,MAAA,cAAA,EAAgB,YAAY,KAAK,CAAA;AACjC,MAAA,KAAA,CAAM,OAAA,EAAQ;AACd,MAAA,KAAA,CAAM,OAAA,EAAQ;AACd,MAAA,IAAA,CAAK,YAAY,KAAK,CAAA;AAAA,IAC1B;AAGA,IAAA,IAAA,CAAK,QAAA,EAAS;AAEd,IAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,IAAA,CAAK,QAAA,CAAS,QAAQ,CAAA,EAAA,EAAK;AAC3C,MAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,QAAA,CAAS,CAAC,CAAA;AAC7B,MAAA,KAAA,CAAM,IAAA,EAAK;AAEX,MAAA,MAAM,GAAA,GAAM,MAAM,IAAA,EAAK;AACvB,MAAA,IAAI,eAAe,OAAA,EAAS;AACxB,QAAA,MAAM,GAAA;AAAA,MACV;AACA,MAAA,KAAA,CAAM,SAAA,EAAU;AAEhB,MAAA,KAAA,CAAM,OAAA,EAAQ;AACd,MAAA,KAAA,CAAM,KAAA,EAAM;AAAA,IAChB;AAAA,EACJ;AACJ;AApIU,eAAA,CAAA;AAAA,EADLL,OAAA,CAAI,QAAA;AAAA,EAEA,qCAASM,iBAAQ,CAAA,CAAA;AAAA,EACjB,qCAASC,gBAAQ,CAAA,CAAA;AAAA,EACjB,qCAASC,qBAAiB,CAAA;AAAA,CAAA,EAdtBT,eAAA,CAWH,SAAA,EAAA,UAAA,EAAA,CAAA,CAAA;AAqEA,eAAA,CAAA;AAAA,EADLC,OAAA,CAAI,MAAA;AAAA,EAEA,qCAASM,iBAAQ,CAAA,CAAA;AAAA,EACjB,qCAASJ,sBAAc,CAAA,CAAA;AAAA,EACvB,qCAASO,YAAQ,CAAA,CAAA;AAAA,EACjB,qCAASF,gBAAQ,CAAA,CAAA;AAAA,EACjB,qCAASC,qBAAiB,CAAA;AAAA,CAAA,EArFtBT,eAAA,CAgFH,SAAA,EAAA,UAAA,EAAA,CAAA,CAAA;AAhFGA,eAAA,GAAN,eAAA,CAAA;AAAA,EAJNW,aAAQ,MAAA,CAAO;AAAA,IACZ,SAAA,EAAW,YAAA;AAAA,IACX,WAAA,EAAa;AAAA,GAChB;AAAA,CAAA,EACYX,eAAA,CAAA","file":"AreRoot.component.js","sourcesContent":["import { A_Caller, A_Context, A_FormatterHelper, A_Inject, } from \"@adaas/a-concept\";\nimport { A_Frame } from \"@adaas/a-frame/core\";\nimport { A_Logger } from \"@adaas/a-utils/a-logger\";\nimport { A_SignalVector } from \"@adaas/a-utils/a-signal\";\nimport { Are, ArePropDefinition, AreStore, AreNode, AreSignals, AreSignalsMeta, AreSignalsContext } from \"@adaas/are\";\nimport { AreRoute } from \"@adaas/are-html/signals/AreRoute.signal\";\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 props: Record<string, ArePropDefinition> = {\n default: {\n type: 'string',\n default: '',\n }\n }\n\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 ) {\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 const currentRoute = AreRoute.default();\n\n let componentName: string | undefined;\n\n if (currentRoute) {\n const initialVector = new A_SignalVector([currentRoute]);\n\n // 1. Lookup via AreSignalsContext (per root-id conditions)\n let renderTarget = signalsContext?.findComponentByVector(rootId, initialVector);\n\n // 2. Fall back to global AreSignalsMeta\n if (!renderTarget) {\n const signalsMeta = A_Context.meta<AreSignalsMeta>(AreSignals);\n renderTarget = signalsMeta?.findComponentByVector(initialVector);\n }\n\n if (renderTarget?.name) {\n componentName = A_FormatterHelper.toKebabCase(renderTarget.name);\n }\n }\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\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(AreStore) store: AreStore<{ default: string }>,\n @A_Inject(A_Logger) logger: A_Logger,\n @A_Inject(AreSignalsContext) signalsContext?: AreSignalsContext,\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 // 1. Try root-specific lookup via AreSignalsContext (keyed by the are-root's id attribute)\n let renderTarget = signalsContext?.findComponentByVector(rootId, vector);\n\n // 2. Fall back to global AreSignalsMeta lookup\n if (!renderTarget) {\n const signalsMeta = A_Context.meta<AreSignalsMeta>(AreSignals);\n renderTarget = signalsMeta?.findComponentByVector(vector);\n }\n\n const componentName = renderTarget?.name\n ? A_FormatterHelper.toKebabCase(renderTarget.name)\n : store.get('default');\n\n // No matching condition for this signal vector (e.g. AreInit before any route).\n // Keep the current outlet content and do nothing.\n if (!componentName) {\n return;\n }\n\n root.setContent(`<${componentName}></${componentName}>`);\n\n // Unsubscribe old children BEFORE destroying them.\n // Without this, AreSignals.handleSignalVector keeps iterating stale\n // (scope-less) nodes on every subsequent signal and throws an error.\n for (let i = 0; i < root.children.length; i++) {\n const child = root.children[i];\n signalsContext?.unsubscribe(child);\n child.unmount();\n child.destroy();\n root.removeChild(child);\n }\n\n\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 child.mount();\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/AreRoot/AreRoot.component.ts"],"names":["AreRoot","Are","AreRoute","A_SignalVector","A_Context","AreSignals","A_FormatterHelper","A_Caller","A_Logger","AreSignalsContext","AreStore","A_Frame"],"mappings":";;;;;;;;;;;;;;;;;;;;AAYaA,eAAA,GAAN,sBAAsBC,OAAA,CAAI;AAAA,EAA1B,WAAA,GAAA;AAAA,IAAA,KAAA,CAAA,GAAA,SAAA,CAAA;AAEH,IAAA,IAAA,CAAA,KAAA,GAA2C;AAAA,MACvC,OAAA,EAAS;AAAA,QACL,IAAA,EAAM,QAAA;AAAA,QACN,OAAA,EAAS;AAAA;AACb,KACJ;AAAA,EAAA;AAAA,EAIA,MAAM,QAAA,CACkB,IAAA,EACA,MAAA,EACS,cAAA,EAC/B;AAEE,IAAA,MAAM,SAAS,IAAA,CAAK,EAAA;AAIpB,IAAA,IAAI,cAAA,IAAkB,CAAC,cAAA,CAAe,OAAA,CAAQ,MAAM,CAAA,EAAG;AACnD,MAAA,IAAI,CAAC,IAAA,CAAK,OAAA,EAAS,IAAA,EAAK,EAAG;AAEvB,QAAA,MAAM,YAAA,GAAe,IAAA,CAAK,MAAA,EAAQ,KAAA,CAAM,4BAA4B,CAAA;AACpE,QAAA,MAAM,gBAAA,GAAmB,eAAe,CAAC,CAAA;AACzC,QAAA,IAAI,gBAAA,EAAkB;AAClB,UAAA,IAAA,CAAK,UAAA,CAAW,CAAA,CAAA,EAAI,gBAAgB,CAAA,GAAA,EAAM,gBAAgB,CAAA,CAAA,CAAG,CAAA;AAAA,QACjE;AAAA,MACJ;AAEA,MAAA;AAAA,IACJ;AAEA,IAAA,MAAM,YAAA,GAAeC,yBAAS,OAAA,EAAQ;AAEtC,IAAA,IAAI,aAAA;AAEJ,IAAA,IAAI,YAAA,EAAc;AACd,MAAA,MAAM,aAAA,GAAgB,IAAIC,sBAAA,CAAe,CAAC,YAAY,CAAC,CAAA;AAGvD,MAAA,IAAI,YAAA,GAAe,cAAA,EAAgB,qBAAA,CAAsB,MAAA,EAAQ,aAAa,CAAA;AAG9E,MAAA,IAAI,CAAC,YAAA,EAAc;AACf,QAAA,MAAM,WAAA,GAAcC,kBAAA,CAAU,IAAA,CAAqBC,cAAU,CAAA;AAC7D,QAAA,MAAM,UAAA,GAAa,WAAA,EAAa,qBAAA,CAAsB,aAAa,CAAA;AACnE,QAAA,IAAI,UAAA,EAAY;AACZ,UAAA,MAAM,IAAA,GAAO,cAAA,EAAgB,gBAAA,CAAiB,MAAM,CAAA;AACpD,UAAA,IAAI,CAAC,IAAA,EAAM,MAAA,IAAU,IAAA,CAAK,QAAA,CAAS,UAAU,CAAA,EAAG;AAC5C,YAAA,YAAA,GAAe,UAAA;AAAA,UACnB;AAAA,QACJ;AAAA,MACJ;AAEA,MAAA,IAAI,cAAc,IAAA,EAAM;AACpB,QAAA,aAAA,GAAgBC,0BAAA,CAAkB,WAAA,CAAY,YAAA,CAAa,IAAI,CAAA;AAAA,MACnE;AAAA,IACJ;AAKA,IAAA,IAAI,CAAC,aAAA,EAAe;AAChB,MAAA,IAAI,IAAA,CAAK,OAAA,EAAS,IAAA,EAAK,EAAG;AACtB,QAAA;AAAA,MACJ;AAAA,IACJ;AAEA,IAAA,IAAI,CAAC,aAAA,EAAe;AAChB,MAAA,MAAM,WAAA,GAAc,cAAA,EAAgB,UAAA,CAAW,MAAM,CAAA;AACrD,MAAA,IAAI,aAAa,IAAA,EAAM;AACnB,QAAA,aAAA,GAAgBA,0BAAA,CAAkB,WAAA,CAAY,WAAA,CAAY,IAAI,CAAA;AAAA,MAClE;AAAA,IACJ;AAEA,IAAA,IAAI,CAAC,aAAA,EAAe;AAChB,MAAA,MAAM,YAAA,GAAe,IAAA,CAAK,MAAA,EAAQ,KAAA,CAAM,4BAA4B,CAAA;AACpE,MAAA,aAAA,GAAgB,eAAe,CAAC,CAAA;AAAA,IACpC;AAEA,IAAA,IAAI,CAAC,aAAA,EAAe;AAChB,MAAA,MAAA,CAAO,QAAQ,oHAAoH,CAAA;AACnI,MAAA;AAAA,IACJ;AAEA,IAAA,IAAA,CAAK,UAAA,CAAW,CAAA,CAAA,EAAI,aAAa,CAAA,GAAA,EAAM,aAAa,CAAA,CAAA,CAAG,CAAA;AAAA,EAC3D;AAAA,EAIA,MAAM,QAAA,CACkB,IAAA,EACM,MAAA,EACN,KAAA,EACA,QACS,cAAA,EAC/B;AACE,IAAA,MAAM,SAAS,IAAA,CAAK,EAAA;AAGpB,IAAA,IAAI,cAAA,IAAkB,CAAC,cAAA,CAAe,OAAA,CAAQ,MAAM,CAAA,EAAG;AACnD,MAAA;AAAA,IACJ;AAGA,IAAA,IAAI,YAAA,GAAe,cAAA,EAAgB,qBAAA,CAAsB,MAAA,EAAQ,MAAM,CAAA;AAMvE,IAAA,IAAI,CAAC,YAAA,EAAc;AACf,MAAA,MAAM,WAAA,GAAcF,kBAAA,CAAU,IAAA,CAAqBC,cAAU,CAAA;AAC7D,MAAA,MAAM,UAAA,GAAa,WAAA,EAAa,qBAAA,CAAsB,MAAM,CAAA;AAC5D,MAAA,IAAI,UAAA,EAAY;AACZ,QAAA,MAAM,IAAA,GAAO,cAAA,EAAgB,gBAAA,CAAiB,MAAM,CAAA;AACpD,QAAA,IAAI,CAAC,IAAA,EAAM,MAAA,IAAU,IAAA,CAAK,QAAA,CAAS,UAAU,CAAA,EAAG;AAC5C,UAAA,YAAA,GAAe,UAAA;AAAA,QACnB;AAAA,MACJ;AAAA,IACJ;AAEA,IAAA,MAAM,aAAA,GAAgB,YAAA,EAAc,IAAA,GAC9BC,0BAAA,CAAkB,WAAA,CAAY,aAAa,IAAI,CAAA,GAC/C,KAAA,CAAM,GAAA,CAAI,SAAS,CAAA;AAIzB,IAAA,IAAI,CAAC,aAAA,EAAe;AAChB,MAAA;AAAA,IACJ;AAOA,IAAA,MAAM,YAAA,GAAe,IAAA,CAAK,QAAA,CAAS,CAAC,CAAA;AACpC,IAAA,IAAI,YAAA,EAAc,SAAS,aAAA,EAAe;AACtC,MAAA;AAAA,IACJ;AAEA,IAAA,IAAA,CAAK,UAAA,CAAW,CAAA,CAAA,EAAI,aAAa,CAAA,GAAA,EAAM,aAAa,CAAA,CAAA,CAAG,CAAA;AAKvD,IAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,IAAA,CAAK,QAAA,CAAS,QAAQ,CAAA,EAAA,EAAK;AAC3C,MAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,QAAA,CAAS,CAAC,CAAA;AAC7B,MAAA,cAAA,EAAgB,YAAY,KAAK,CAAA;AACjC,MAAA,KAAA,CAAM,OAAA,EAAQ;AACd,MAAA,KAAA,CAAM,OAAA,EAAQ;AACd,MAAA,IAAA,CAAK,YAAY,KAAK,CAAA;AAAA,IAC1B;AAGA,IAAA,IAAA,CAAK,QAAA,EAAS;AAEd,IAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,IAAA,CAAK,QAAA,CAAS,QAAQ,CAAA,EAAA,EAAK;AAC3C,MAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,QAAA,CAAS,CAAC,CAAA;AAC7B,MAAA,KAAA,CAAM,IAAA,EAAK;AAEX,MAAA,MAAM,GAAA,GAAM,MAAM,IAAA,EAAK;AACvB,MAAA,IAAI,eAAe,OAAA,EAAS;AACxB,QAAA,MAAM,GAAA;AAAA,MACV;AACA,MAAA,KAAA,CAAM,SAAA,EAAU;AAEhB,MAAA,KAAA,CAAM,OAAA,EAAQ;AACd,MAAA,KAAA,CAAM,KAAA,EAAM;AAAA,IAChB;AAAA,EACJ;AACJ;AAnKU,eAAA,CAAA;AAAA,EADLL,OAAA,CAAI,QAAA;AAAA,EAEA,qCAASM,iBAAQ,CAAA,CAAA;AAAA,EACjB,qCAASC,gBAAQ,CAAA,CAAA;AAAA,EACjB,qCAASC,qBAAiB,CAAA;AAAA,CAAA,EAdtBT,eAAA,CAWH,SAAA,EAAA,UAAA,EAAA,CAAA,CAAA;AAiFA,eAAA,CAAA;AAAA,EADLC,OAAA,CAAI,MAAA;AAAA,EAEA,qCAASM,iBAAQ,CAAA,CAAA;AAAA,EACjB,qCAASJ,sBAAc,CAAA,CAAA;AAAA,EACvB,qCAASO,YAAQ,CAAA,CAAA;AAAA,EACjB,qCAASF,gBAAQ,CAAA,CAAA;AAAA,EACjB,qCAASC,qBAAiB,CAAA;AAAA,CAAA,EAjGtBT,eAAA,CA4FH,SAAA,EAAA,UAAA,EAAA,CAAA,CAAA;AA5FGA,eAAA,GAAN,eAAA,CAAA;AAAA,EAJNW,aAAQ,MAAA,CAAO;AAAA,IACZ,SAAA,EAAW,YAAA;AAAA,IACX,WAAA,EAAa;AAAA,GAChB;AAAA,CAAA,EACYX,eAAA,CAAA","file":"AreRoot.component.js","sourcesContent":["import { A_Caller, A_Context, A_FormatterHelper, A_Inject, } from \"@adaas/a-concept\";\nimport { A_Frame } from \"@adaas/a-frame/core\";\nimport { A_Logger } from \"@adaas/a-utils/a-logger\";\nimport { A_SignalVector } from \"@adaas/a-utils/a-signal\";\nimport { Are, ArePropDefinition, AreStore, AreNode, AreSignals, AreSignalsMeta, AreSignalsContext } from \"@adaas/are\";\nimport { AreRoute } from \"@adaas/are-html/signals/AreRoute.signal\";\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 props: Record<string, ArePropDefinition> = {\n default: {\n type: 'string',\n default: '',\n }\n }\n\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 ) {\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 const currentRoute = AreRoute.default();\n\n let componentName: string | undefined;\n\n if (currentRoute) {\n const initialVector = new A_SignalVector([currentRoute]);\n\n // 1. Lookup via AreSignalsContext (per root-id conditions)\n let renderTarget = signalsContext?.findComponentByVector(rootId, initialVector);\n\n // 2. Fall back to global AreSignalsMeta, pool-filtered\n if (!renderTarget) {\n const signalsMeta = A_Context.meta<AreSignalsMeta>(AreSignals);\n const metaTarget = signalsMeta?.findComponentByVector(initialVector);\n if (metaTarget) {\n const pool = signalsContext?.getComponentById(rootId);\n if (!pool?.length || pool.includes(metaTarget)) {\n renderTarget = metaTarget;\n }\n }\n }\n\n if (renderTarget?.name) {\n componentName = A_FormatterHelper.toKebabCase(renderTarget.name);\n }\n }\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(AreStore) store: AreStore<{ default: string }>,\n @A_Inject(A_Logger) logger: A_Logger,\n @A_Inject(AreSignalsContext) signalsContext?: AreSignalsContext,\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 // 1. Try root-specific lookup via AreSignalsContext (keyed by the are-root's id attribute)\n let renderTarget = signalsContext?.findComponentByVector(rootId, vector);\n\n // 2. Fall back to global AreSignalsMeta lookup, but only accept the\n // result if it belongs to this outlet's pool (when a pool is defined).\n // This prevents a meta-registered component for one outlet from being\n // accidentally rendered in a different outlet sharing the same signal.\n if (!renderTarget) {\n const signalsMeta = A_Context.meta<AreSignalsMeta>(AreSignals);\n const metaTarget = signalsMeta?.findComponentByVector(vector);\n if (metaTarget) {\n const pool = signalsContext?.getComponentById(rootId);\n if (!pool?.length || pool.includes(metaTarget)) {\n renderTarget = metaTarget;\n }\n }\n }\n\n const componentName = renderTarget?.name\n ? A_FormatterHelper.toKebabCase(renderTarget.name)\n : store.get('default');\n\n // No matching condition for this signal vector (e.g. AreInit before any route).\n // Keep the current outlet content and do nothing.\n if (!componentName) {\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 root.setContent(`<${componentName}></${componentName}>`);\n\n // Unsubscribe old children BEFORE destroying them.\n // Without this, AreSignals.handleSignalVector keeps iterating stale\n // (scope-less) nodes on every subsequent signal and throws an error.\n for (let i = 0; i < root.children.length; i++) {\n const child = root.children[i];\n signalsContext?.unsubscribe(child);\n child.unmount();\n child.destroy();\n root.removeChild(child);\n }\n\n\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 child.mount();\n }\n }\n}\n"]}
|
|
@@ -35,7 +35,13 @@ let AreRoot = class extends Are {
|
|
|
35
35
|
let renderTarget = signalsContext?.findComponentByVector(rootId, initialVector);
|
|
36
36
|
if (!renderTarget) {
|
|
37
37
|
const signalsMeta = A_Context.meta(AreSignals);
|
|
38
|
-
|
|
38
|
+
const metaTarget = signalsMeta?.findComponentByVector(initialVector);
|
|
39
|
+
if (metaTarget) {
|
|
40
|
+
const pool = signalsContext?.getComponentById(rootId);
|
|
41
|
+
if (!pool?.length || pool.includes(metaTarget)) {
|
|
42
|
+
renderTarget = metaTarget;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
39
45
|
}
|
|
40
46
|
if (renderTarget?.name) {
|
|
41
47
|
componentName = A_FormatterHelper.toKebabCase(renderTarget.name);
|
|
@@ -46,6 +52,12 @@ let AreRoot = class extends Are {
|
|
|
46
52
|
return;
|
|
47
53
|
}
|
|
48
54
|
}
|
|
55
|
+
if (!componentName) {
|
|
56
|
+
const defaultComp = signalsContext?.getDefault(rootId);
|
|
57
|
+
if (defaultComp?.name) {
|
|
58
|
+
componentName = A_FormatterHelper.toKebabCase(defaultComp.name);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
49
61
|
if (!componentName) {
|
|
50
62
|
const defaultMatch = root.markup?.match(/\bdefault=["']([^"']*)["']/);
|
|
51
63
|
componentName = defaultMatch?.[1];
|
|
@@ -64,12 +76,22 @@ let AreRoot = class extends Are {
|
|
|
64
76
|
let renderTarget = signalsContext?.findComponentByVector(rootId, vector);
|
|
65
77
|
if (!renderTarget) {
|
|
66
78
|
const signalsMeta = A_Context.meta(AreSignals);
|
|
67
|
-
|
|
79
|
+
const metaTarget = signalsMeta?.findComponentByVector(vector);
|
|
80
|
+
if (metaTarget) {
|
|
81
|
+
const pool = signalsContext?.getComponentById(rootId);
|
|
82
|
+
if (!pool?.length || pool.includes(metaTarget)) {
|
|
83
|
+
renderTarget = metaTarget;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
68
86
|
}
|
|
69
87
|
const componentName = renderTarget?.name ? A_FormatterHelper.toKebabCase(renderTarget.name) : store.get("default");
|
|
70
88
|
if (!componentName) {
|
|
71
89
|
return;
|
|
72
90
|
}
|
|
91
|
+
const currentChild = root.children[0];
|
|
92
|
+
if (currentChild?.type === componentName) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
73
95
|
root.setContent(`<${componentName}></${componentName}>`);
|
|
74
96
|
for (let i = 0; i < root.children.length; i++) {
|
|
75
97
|
const child = root.children[i];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"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, } from \"@adaas/a-concept\";\nimport { A_Frame } from \"@adaas/a-frame/core\";\nimport { A_Logger } from \"@adaas/a-utils/a-logger\";\nimport { A_SignalVector } from \"@adaas/a-utils/a-signal\";\nimport { Are, ArePropDefinition, AreStore, AreNode, AreSignals, AreSignalsMeta, AreSignalsContext } from \"@adaas/are\";\nimport { AreRoute } from \"@adaas/are-html/signals/AreRoute.signal\";\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 props: Record<string, ArePropDefinition> = {\n default: {\n type: 'string',\n default: '',\n }\n }\n\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 ) {\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 const currentRoute = AreRoute.default();\n\n let componentName: string | undefined;\n\n if (currentRoute) {\n const initialVector = new A_SignalVector([currentRoute]);\n\n // 1. Lookup via AreSignalsContext (per root-id conditions)\n let renderTarget = signalsContext?.findComponentByVector(rootId, initialVector);\n\n // 2. Fall back to global AreSignalsMeta\n if (!renderTarget) {\n const signalsMeta = A_Context.meta<AreSignalsMeta>(AreSignals);\n renderTarget = signalsMeta?.findComponentByVector(initialVector);\n }\n\n if (renderTarget?.name) {\n componentName = A_FormatterHelper.toKebabCase(renderTarget.name);\n }\n }\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\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(AreStore) store: AreStore<{ default: string }>,\n @A_Inject(A_Logger) logger: A_Logger,\n @A_Inject(AreSignalsContext) signalsContext?: AreSignalsContext,\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 // 1. Try root-specific lookup via AreSignalsContext (keyed by the are-root's id attribute)\n let renderTarget = signalsContext?.findComponentByVector(rootId, vector);\n\n // 2. Fall back to global AreSignalsMeta lookup\n if (!renderTarget) {\n const signalsMeta = A_Context.meta<AreSignalsMeta>(AreSignals);\n renderTarget = signalsMeta?.findComponentByVector(vector);\n }\n\n const componentName = renderTarget?.name\n ? A_FormatterHelper.toKebabCase(renderTarget.name)\n : store.get('default');\n\n // No matching condition for this signal vector (e.g. AreInit before any route).\n // Keep the current outlet content and do nothing.\n if (!componentName) {\n return;\n }\n\n root.setContent(`<${componentName}></${componentName}>`);\n\n // Unsubscribe old children BEFORE destroying them.\n // Without this, AreSignals.handleSignalVector keeps iterating stale\n // (scope-less) nodes on every subsequent signal and throws an error.\n for (let i = 0; i < root.children.length; i++) {\n const child = root.children[i];\n signalsContext?.unsubscribe(child);\n child.unmount();\n child.destroy();\n root.removeChild(child);\n }\n\n\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 child.mount();\n }\n }\n}\n"]}
|
|
1
|
+
{"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, } from \"@adaas/a-concept\";\nimport { A_Frame } from \"@adaas/a-frame/core\";\nimport { A_Logger } from \"@adaas/a-utils/a-logger\";\nimport { A_SignalVector } from \"@adaas/a-utils/a-signal\";\nimport { Are, ArePropDefinition, AreStore, AreNode, AreSignals, AreSignalsMeta, AreSignalsContext } from \"@adaas/are\";\nimport { AreRoute } from \"@adaas/are-html/signals/AreRoute.signal\";\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 props: Record<string, ArePropDefinition> = {\n default: {\n type: 'string',\n default: '',\n }\n }\n\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 ) {\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 const currentRoute = AreRoute.default();\n\n let componentName: string | undefined;\n\n if (currentRoute) {\n const initialVector = new A_SignalVector([currentRoute]);\n\n // 1. Lookup via AreSignalsContext (per root-id conditions)\n let renderTarget = signalsContext?.findComponentByVector(rootId, initialVector);\n\n // 2. Fall back to global AreSignalsMeta, pool-filtered\n if (!renderTarget) {\n const signalsMeta = A_Context.meta<AreSignalsMeta>(AreSignals);\n const metaTarget = signalsMeta?.findComponentByVector(initialVector);\n if (metaTarget) {\n const pool = signalsContext?.getComponentById(rootId);\n if (!pool?.length || pool.includes(metaTarget)) {\n renderTarget = metaTarget;\n }\n }\n }\n\n if (renderTarget?.name) {\n componentName = A_FormatterHelper.toKebabCase(renderTarget.name);\n }\n }\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(AreStore) store: AreStore<{ default: string }>,\n @A_Inject(A_Logger) logger: A_Logger,\n @A_Inject(AreSignalsContext) signalsContext?: AreSignalsContext,\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 // 1. Try root-specific lookup via AreSignalsContext (keyed by the are-root's id attribute)\n let renderTarget = signalsContext?.findComponentByVector(rootId, vector);\n\n // 2. Fall back to global AreSignalsMeta lookup, but only accept the\n // result if it belongs to this outlet's pool (when a pool is defined).\n // This prevents a meta-registered component for one outlet from being\n // accidentally rendered in a different outlet sharing the same signal.\n if (!renderTarget) {\n const signalsMeta = A_Context.meta<AreSignalsMeta>(AreSignals);\n const metaTarget = signalsMeta?.findComponentByVector(vector);\n if (metaTarget) {\n const pool = signalsContext?.getComponentById(rootId);\n if (!pool?.length || pool.includes(metaTarget)) {\n renderTarget = metaTarget;\n }\n }\n }\n\n const componentName = renderTarget?.name\n ? A_FormatterHelper.toKebabCase(renderTarget.name)\n : store.get('default');\n\n // No matching condition for this signal vector (e.g. AreInit before any route).\n // Keep the current outlet content and do nothing.\n if (!componentName) {\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 root.setContent(`<${componentName}></${componentName}>`);\n\n // Unsubscribe old children BEFORE destroying them.\n // Without this, AreSignals.handleSignalVector keeps iterating stale\n // (scope-less) nodes on every subsequent signal and throws an error.\n for (let i = 0; i < root.children.length; i++) {\n const child = root.children[i];\n signalsContext?.unsubscribe(child);\n child.unmount();\n child.destroy();\n root.removeChild(child);\n }\n\n\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 child.mount();\n }\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adaas/are-html",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.15",
|
|
4
4
|
"description": "A-Concept Rendering Engine (ARE) is a powerful rendering engine designed to work seamlessly with the A-Concept framework. This library provides an HTML engine implementation of ARE, enabling developers to create dynamic and interactive user interfaces for web applications using standard HTML syntax.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"a-concept",
|
|
@@ -85,13 +85,13 @@
|
|
|
85
85
|
"@adaas/a-concept": "^0.3.17",
|
|
86
86
|
"@adaas/a-frame": "^0.1.2",
|
|
87
87
|
"@adaas/a-utils": "^0.3.24",
|
|
88
|
-
"@adaas/are": "^0.0.
|
|
88
|
+
"@adaas/are": "^0.0.16"
|
|
89
89
|
},
|
|
90
90
|
"devDependencies": {
|
|
91
91
|
"@adaas/a-concept": "^0.3.17",
|
|
92
92
|
"@adaas/a-frame": "^0.1.2",
|
|
93
93
|
"@adaas/a-utils": "^0.3.24",
|
|
94
|
-
"@adaas/are": "^0.0.
|
|
94
|
+
"@adaas/are": "^0.0.16",
|
|
95
95
|
"@types/chai": "^4.3.14",
|
|
96
96
|
"@types/jest": "^29.5.12",
|
|
97
97
|
"@types/mocha": "^10.0.6",
|
|
@@ -54,10 +54,16 @@ export class AreRoot extends Are {
|
|
|
54
54
|
// 1. Lookup via AreSignalsContext (per root-id conditions)
|
|
55
55
|
let renderTarget = signalsContext?.findComponentByVector(rootId, initialVector);
|
|
56
56
|
|
|
57
|
-
// 2. Fall back to global AreSignalsMeta
|
|
57
|
+
// 2. Fall back to global AreSignalsMeta, pool-filtered
|
|
58
58
|
if (!renderTarget) {
|
|
59
59
|
const signalsMeta = A_Context.meta<AreSignalsMeta>(AreSignals);
|
|
60
|
-
|
|
60
|
+
const metaTarget = signalsMeta?.findComponentByVector(initialVector);
|
|
61
|
+
if (metaTarget) {
|
|
62
|
+
const pool = signalsContext?.getComponentById(rootId);
|
|
63
|
+
if (!pool?.length || pool.includes(metaTarget)) {
|
|
64
|
+
renderTarget = metaTarget;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
61
67
|
}
|
|
62
68
|
|
|
63
69
|
if (renderTarget?.name) {
|
|
@@ -73,7 +79,13 @@ export class AreRoot extends Are {
|
|
|
73
79
|
return;
|
|
74
80
|
}
|
|
75
81
|
}
|
|
76
|
-
|
|
82
|
+
// 3.5. Fall back to AreSignalsContext default component for this root.
|
|
83
|
+
if (!componentName) {
|
|
84
|
+
const defaultComp = signalsContext?.getDefault(rootId);
|
|
85
|
+
if (defaultComp?.name) {
|
|
86
|
+
componentName = A_FormatterHelper.toKebabCase(defaultComp.name);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
77
89
|
// 4. Last resort: legacy default= attribute on the markup.
|
|
78
90
|
if (!componentName) {
|
|
79
91
|
const defaultMatch = root.markup?.match(/\bdefault=["']([^"']*)["']/);
|
|
@@ -107,10 +119,19 @@ export class AreRoot extends Are {
|
|
|
107
119
|
// 1. Try root-specific lookup via AreSignalsContext (keyed by the are-root's id attribute)
|
|
108
120
|
let renderTarget = signalsContext?.findComponentByVector(rootId, vector);
|
|
109
121
|
|
|
110
|
-
// 2. Fall back to global AreSignalsMeta lookup
|
|
122
|
+
// 2. Fall back to global AreSignalsMeta lookup, but only accept the
|
|
123
|
+
// result if it belongs to this outlet's pool (when a pool is defined).
|
|
124
|
+
// This prevents a meta-registered component for one outlet from being
|
|
125
|
+
// accidentally rendered in a different outlet sharing the same signal.
|
|
111
126
|
if (!renderTarget) {
|
|
112
127
|
const signalsMeta = A_Context.meta<AreSignalsMeta>(AreSignals);
|
|
113
|
-
|
|
128
|
+
const metaTarget = signalsMeta?.findComponentByVector(vector);
|
|
129
|
+
if (metaTarget) {
|
|
130
|
+
const pool = signalsContext?.getComponentById(rootId);
|
|
131
|
+
if (!pool?.length || pool.includes(metaTarget)) {
|
|
132
|
+
renderTarget = metaTarget;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
114
135
|
}
|
|
115
136
|
|
|
116
137
|
const componentName = renderTarget?.name
|
|
@@ -123,6 +144,16 @@ export class AreRoot extends Are {
|
|
|
123
144
|
return;
|
|
124
145
|
}
|
|
125
146
|
|
|
147
|
+
// Guard: if the outlet already shows the same component, do nothing.
|
|
148
|
+
// Prevents infinite remount loops when a non-routing signal carries a
|
|
149
|
+
// stale routing signal in the accumulated A_SignalState vector.
|
|
150
|
+
// node.type is the kebab-case tag name — the most direct and reliable
|
|
151
|
+
// identifier (no constructor-name resolution, no proxy wrapping issues).
|
|
152
|
+
const currentChild = root.children[0] as AreNode | undefined;
|
|
153
|
+
if (currentChild?.type === componentName) {
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
|
|
126
157
|
root.setContent(`<${componentName}></${componentName}>`);
|
|
127
158
|
|
|
128
159
|
// Unsubscribe old children BEFORE destroying them.
|