@adaas/are-html 0.0.20 → 0.0.21
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.d.mts +161 -5
- package/dist/browser/index.mjs +357 -55
- package/dist/browser/index.mjs.map +1 -1
- package/dist/node/directives/AreDirectiveFor.directive.d.mts +7 -0
- package/dist/node/directives/AreDirectiveFor.directive.d.ts +7 -0
- package/dist/node/directives/AreDirectiveFor.directive.js +17 -2
- package/dist/node/directives/AreDirectiveFor.directive.js.map +1 -1
- package/dist/node/directives/AreDirectiveFor.directive.mjs +17 -2
- package/dist/node/directives/AreDirectiveFor.directive.mjs.map +1 -1
- package/dist/node/directives/AreDirectiveShow.directive.d.mts +32 -0
- package/dist/node/directives/AreDirectiveShow.directive.d.ts +32 -0
- package/dist/node/directives/AreDirectiveShow.directive.js +81 -0
- package/dist/node/directives/AreDirectiveShow.directive.js.map +1 -0
- package/dist/node/directives/AreDirectiveShow.directive.mjs +71 -0
- package/dist/node/directives/AreDirectiveShow.directive.mjs.map +1 -0
- package/dist/node/engine/AreHTML.engine.d.mts +2 -1
- package/dist/node/engine/AreHTML.engine.d.ts +2 -1
- package/dist/node/engine/AreHTML.engine.js +8 -2
- package/dist/node/engine/AreHTML.engine.js.map +1 -1
- package/dist/node/engine/AreHTML.engine.mjs +8 -2
- package/dist/node/engine/AreHTML.engine.mjs.map +1 -1
- package/dist/node/engine/AreHTML.interpreter.d.mts +3 -0
- package/dist/node/engine/AreHTML.interpreter.d.ts +3 -0
- package/dist/node/engine/AreHTML.interpreter.js +29 -0
- package/dist/node/engine/AreHTML.interpreter.js.map +1 -1
- package/dist/node/engine/AreHTML.interpreter.mjs +29 -0
- package/dist/node/engine/AreHTML.interpreter.mjs.map +1 -1
- package/dist/node/index.d.mts +4 -1
- package/dist/node/index.d.ts +4 -1
- package/dist/node/index.js +21 -0
- package/dist/node/index.mjs +3 -0
- package/dist/node/instructions/AreHTML.instructions.constants.d.mts +1 -0
- package/dist/node/instructions/AreHTML.instructions.constants.d.ts +1 -0
- package/dist/node/instructions/AreHTML.instructions.constants.js +2 -1
- package/dist/node/instructions/AreHTML.instructions.constants.js.map +1 -1
- package/dist/node/instructions/AreHTML.instructions.constants.mjs +2 -1
- package/dist/node/instructions/AreHTML.instructions.constants.mjs.map +1 -1
- package/dist/node/instructions/AreHTML.instructions.types.d.mts +9 -1
- package/dist/node/instructions/AreHTML.instructions.types.d.ts +9 -1
- package/dist/node/instructions/HideElement.instruction.d.mts +13 -0
- package/dist/node/instructions/HideElement.instruction.d.ts +13 -0
- package/dist/node/instructions/HideElement.instruction.js +31 -0
- package/dist/node/instructions/HideElement.instruction.js.map +1 -0
- package/dist/node/instructions/HideElement.instruction.mjs +24 -0
- package/dist/node/instructions/HideElement.instruction.mjs.map +1 -0
- package/dist/node/lib/AreRoot/AreRoot.component.d.mts +57 -3
- package/dist/node/lib/AreRoot/AreRoot.component.d.ts +57 -3
- package/dist/node/lib/AreRoot/AreRoot.component.js +137 -48
- package/dist/node/lib/AreRoot/AreRoot.component.js.map +1 -1
- package/dist/node/lib/AreRoot/AreRoot.component.mjs +139 -50
- package/dist/node/lib/AreRoot/AreRoot.component.mjs.map +1 -1
- package/dist/node/lib/AreRoot/AreRootCache.context.d.mts +58 -0
- package/dist/node/lib/AreRoot/AreRootCache.context.d.ts +58 -0
- package/dist/node/lib/AreRoot/AreRootCache.context.js +106 -0
- package/dist/node/lib/AreRoot/AreRootCache.context.js.map +1 -0
- package/dist/node/lib/AreRoot/AreRootCache.context.mjs +99 -0
- package/dist/node/lib/AreRoot/AreRootCache.context.mjs.map +1 -0
- package/examples/jumpstart/dist/index.html +1 -1
- package/examples/jumpstart/dist/{mq1a0fv0-ccgtz6.js → mq7hqrxy-4kus50.js} +629 -433
- package/examples/signal-routing/dist/index.html +1 -1
- package/examples/signal-routing/dist/{mq1bzrik-4lec86.js → mq7k53th-qiwy4x.js} +903 -486
- package/examples/signal-routing/src/components/SettingsPage.component.ts +39 -0
- package/examples/signal-routing/src/concept.ts +2 -0
- package/package.json +3 -3
- package/src/directives/AreDirectiveFor.directive.ts +44 -2
- package/src/directives/AreDirectiveShow.directive.ts +127 -0
- package/src/engine/AreHTML.engine.ts +11 -1
- package/src/engine/AreHTML.interpreter.ts +50 -0
- package/src/index.ts +3 -0
- package/src/instructions/AreHTML.instructions.constants.ts +1 -0
- package/src/instructions/AreHTML.instructions.types.ts +9 -0
- package/src/instructions/HideElement.instruction.ts +29 -0
- package/src/lib/AreRoot/AreRoot.component.ts +201 -71
- package/src/lib/AreRoot/AreRootCache.context.ts +133 -0
package/dist/browser/index.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import { A_Logger } from '@adaas/a-utils/a-logger';
|
|
|
5
5
|
import { A_ExecutionContext } from '@adaas/a-utils/a-execution';
|
|
6
6
|
import { A_Route } from '@adaas/a-utils/a-route';
|
|
7
7
|
import { A_ServiceFeatures } from '@adaas/a-utils/a-service';
|
|
8
|
-
import { A_SignalVector } from '@adaas/a-utils/a-signal';
|
|
8
|
+
import { A_SignalState, A_SignalVector } from '@adaas/a-utils/a-signal';
|
|
9
9
|
|
|
10
10
|
var __defProp = Object.defineProperty;
|
|
11
11
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -207,7 +207,8 @@ var AreHTMLInstructions = {
|
|
|
207
207
|
AddStyle: "_AreHTML_AddStyle",
|
|
208
208
|
AddListener: "_AreHTML_AddListener",
|
|
209
209
|
AddInterpolation: "_AreHTML_AddInterpolation",
|
|
210
|
-
AddComment: "_AreHTML_AddComment"
|
|
210
|
+
AddComment: "_AreHTML_AddComment",
|
|
211
|
+
HideElement: "_AreHTML_HideElement"
|
|
211
212
|
};
|
|
212
213
|
|
|
213
214
|
// src/instructions/AddComment.instruction.ts
|
|
@@ -268,6 +269,7 @@ var AreDirectiveFor = class extends AreDirective {
|
|
|
268
269
|
const owner = attribute.owner;
|
|
269
270
|
const currentChildren = [...owner.children];
|
|
270
271
|
attribute.value = newArray;
|
|
272
|
+
const attached = this.isAttached(owner);
|
|
271
273
|
const computeKey = this.makeKeyFn(key, index, trackExpr);
|
|
272
274
|
const childByKey = /* @__PURE__ */ new Map();
|
|
273
275
|
const remaining = /* @__PURE__ */ new Set();
|
|
@@ -301,15 +303,29 @@ var AreDirectiveFor = class extends AreDirective {
|
|
|
301
303
|
}
|
|
302
304
|
}
|
|
303
305
|
for (const child of remaining) {
|
|
304
|
-
child.unmount();
|
|
306
|
+
if (attached) child.unmount();
|
|
305
307
|
owner.removeChild(child);
|
|
306
308
|
}
|
|
307
309
|
for (const child of newOnes) {
|
|
308
310
|
child.transform();
|
|
309
311
|
child.compile();
|
|
310
|
-
child.mount();
|
|
312
|
+
if (attached) child.mount();
|
|
311
313
|
}
|
|
312
314
|
}
|
|
315
|
+
/**
|
|
316
|
+
* Walks the node's ancestor chain (inclusive) and reports whether the
|
|
317
|
+
* whole path is currently active — i.e. the subtree is actually rendered
|
|
318
|
+
* into the DOM. A single inactive ancestor scene (e.g. a `$if` whose
|
|
319
|
+
* condition is false) means the subtree is detached.
|
|
320
|
+
*/
|
|
321
|
+
isAttached(node) {
|
|
322
|
+
let current = node;
|
|
323
|
+
while (current) {
|
|
324
|
+
if (current.scene?.isInactive) return false;
|
|
325
|
+
current = current.parent;
|
|
326
|
+
}
|
|
327
|
+
return true;
|
|
328
|
+
}
|
|
313
329
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
314
330
|
// ── Helpers ──────────────────────────────────────────────────────────────────
|
|
315
331
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
@@ -556,6 +572,79 @@ AreDirectiveIf = __decorateClass([
|
|
|
556
572
|
}),
|
|
557
573
|
AreDirective.Priority(2)
|
|
558
574
|
], AreDirectiveIf);
|
|
575
|
+
var HideElementInstruction = class extends AreMutation {
|
|
576
|
+
constructor(parent, props) {
|
|
577
|
+
if ("aseid" in props) {
|
|
578
|
+
super(props);
|
|
579
|
+
} else {
|
|
580
|
+
super(AreHTMLInstructions.HideElement, parent, props);
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
};
|
|
584
|
+
HideElementInstruction = __decorateClass([
|
|
585
|
+
A_Frame.Define({
|
|
586
|
+
namespace: "a-are-html",
|
|
587
|
+
description: 'Toggles the visibility of an existing element by setting its inline display to "none" on apply and restoring the previous inline display on revert. Used by the $show directive to hide/show an element without unmounting it, preserving its subtree, listeners and scene state.'
|
|
588
|
+
})
|
|
589
|
+
], HideElementInstruction);
|
|
590
|
+
var AreDirectiveShow = class extends AreDirective {
|
|
591
|
+
transform(attribute, logger, ...args) {
|
|
592
|
+
logger.debug(`[Transform] directive $SHOW for <${attribute.owner.aseid.toString()}> (no structural change)`);
|
|
593
|
+
}
|
|
594
|
+
compile(attribute, store, scene, syntax, directiveContext, ...args) {
|
|
595
|
+
const visible = !!syntax.evaluate(attribute.content, store, {
|
|
596
|
+
...directiveContext?.scope || {}
|
|
597
|
+
});
|
|
598
|
+
attribute.value = visible;
|
|
599
|
+
const hide = new HideElementInstruction(scene.host, {});
|
|
600
|
+
attribute.cache = hide;
|
|
601
|
+
if (!visible)
|
|
602
|
+
scene.plan(hide);
|
|
603
|
+
}
|
|
604
|
+
update(attribute, store, scene, syntax, directiveContext, ...args) {
|
|
605
|
+
const previous = !!attribute.value;
|
|
606
|
+
const next = !!syntax.evaluate(attribute.content, store, {
|
|
607
|
+
...directiveContext?.scope || {}
|
|
608
|
+
});
|
|
609
|
+
attribute.value = next;
|
|
610
|
+
if (previous === next) return;
|
|
611
|
+
const hide = attribute.cache;
|
|
612
|
+
if (!hide) return;
|
|
613
|
+
if (next)
|
|
614
|
+
scene.unPlan(hide);
|
|
615
|
+
else
|
|
616
|
+
scene.plan(hide);
|
|
617
|
+
attribute.owner.interpret();
|
|
618
|
+
}
|
|
619
|
+
};
|
|
620
|
+
__decorateClass([
|
|
621
|
+
AreDirective.Transform,
|
|
622
|
+
__decorateParam(0, A_Inject(A_Caller)),
|
|
623
|
+
__decorateParam(1, A_Inject(A_Logger))
|
|
624
|
+
], AreDirectiveShow.prototype, "transform", 1);
|
|
625
|
+
__decorateClass([
|
|
626
|
+
AreDirective.Compile,
|
|
627
|
+
__decorateParam(0, A_Inject(A_Caller)),
|
|
628
|
+
__decorateParam(1, A_Inject(AreStore)),
|
|
629
|
+
__decorateParam(2, A_Inject(AreScene)),
|
|
630
|
+
__decorateParam(3, A_Inject(AreSyntax)),
|
|
631
|
+
__decorateParam(4, A_Inject(AreDirectiveContext))
|
|
632
|
+
], AreDirectiveShow.prototype, "compile", 1);
|
|
633
|
+
__decorateClass([
|
|
634
|
+
AreDirective.Update,
|
|
635
|
+
__decorateParam(0, A_Inject(A_Caller)),
|
|
636
|
+
__decorateParam(1, A_Inject(AreStore)),
|
|
637
|
+
__decorateParam(2, A_Inject(AreScene)),
|
|
638
|
+
__decorateParam(3, A_Inject(AreSyntax)),
|
|
639
|
+
__decorateParam(4, A_Inject(AreDirectiveContext))
|
|
640
|
+
], AreDirectiveShow.prototype, "update", 1);
|
|
641
|
+
AreDirectiveShow = __decorateClass([
|
|
642
|
+
A_Frame.Define({
|
|
643
|
+
namespace: "a-are-html",
|
|
644
|
+
description: "Built-in $show directive. Toggles an element's visibility by flipping its inline display value based on a store expression, keeping the element mounted (subtree, listeners and scene state preserved) instead of unmounting it like $if."
|
|
645
|
+
}),
|
|
646
|
+
AreDirective.Priority(3)
|
|
647
|
+
], AreDirectiveShow);
|
|
559
648
|
var AddAttributeInstruction = class extends AreMutation {
|
|
560
649
|
constructor(parent, props) {
|
|
561
650
|
if ("aseid" in props) {
|
|
@@ -1486,6 +1575,19 @@ var AreHTMLInterpreter = class extends AreInterpreter {
|
|
|
1486
1575
|
console.log("Error removing attribute:", error);
|
|
1487
1576
|
}
|
|
1488
1577
|
}
|
|
1578
|
+
hideElement(mutation, context) {
|
|
1579
|
+
const element = context.getElementByInstruction(mutation.parent);
|
|
1580
|
+
if (!element || element.nodeType !== Node.ELEMENT_NODE) return;
|
|
1581
|
+
const el = element;
|
|
1582
|
+
mutation.cache = el.style.display;
|
|
1583
|
+
el.style.display = "none";
|
|
1584
|
+
}
|
|
1585
|
+
showElement(mutation, context) {
|
|
1586
|
+
const element = context.getElementByInstruction(mutation.parent);
|
|
1587
|
+
if (!element || element.nodeType !== Node.ELEMENT_NODE) return;
|
|
1588
|
+
const el = element;
|
|
1589
|
+
el.style.display = mutation.payload?.display ?? mutation.cache ?? "";
|
|
1590
|
+
}
|
|
1489
1591
|
addEventListener(mutation, context, store, syntax, directiveContext, logger) {
|
|
1490
1592
|
const element = context.getElementByInstruction(mutation.parent);
|
|
1491
1593
|
if (!element) {
|
|
@@ -1738,6 +1840,22 @@ __decorateClass([
|
|
|
1738
1840
|
__decorateParam(0, A_Inject(A_Caller)),
|
|
1739
1841
|
__decorateParam(1, A_Inject(AreHTMLEngineContext))
|
|
1740
1842
|
], AreHTMLInterpreter.prototype, "removeAttribute", 1);
|
|
1843
|
+
__decorateClass([
|
|
1844
|
+
A_Frame.Define({
|
|
1845
|
+
description: "Hide an element by setting inline display:none, caching its previous inline display value for restoration on revert."
|
|
1846
|
+
}),
|
|
1847
|
+
AreInterpreter.Apply(AreHTMLInstructions.HideElement),
|
|
1848
|
+
__decorateParam(0, A_Inject(A_Caller)),
|
|
1849
|
+
__decorateParam(1, A_Inject(AreHTMLEngineContext))
|
|
1850
|
+
], AreHTMLInterpreter.prototype, "hideElement", 1);
|
|
1851
|
+
__decorateClass([
|
|
1852
|
+
A_Frame.Define({
|
|
1853
|
+
description: "Restore an element hidden by a HideElement instruction back to its previous inline display value."
|
|
1854
|
+
}),
|
|
1855
|
+
AreInterpreter.Revert(AreHTMLInstructions.HideElement),
|
|
1856
|
+
__decorateParam(0, A_Inject(A_Caller)),
|
|
1857
|
+
__decorateParam(1, A_Inject(AreHTMLEngineContext))
|
|
1858
|
+
], AreHTMLInterpreter.prototype, "showElement", 1);
|
|
1741
1859
|
__decorateClass([
|
|
1742
1860
|
A_Frame.Define({
|
|
1743
1861
|
description: "Add an event listener to an HTML element based on the provided mutation instruction."
|
|
@@ -2003,6 +2121,97 @@ AreHTMLTransformer = __decorateClass([
|
|
|
2003
2121
|
description: "HTML-specific transformer extending AreTransformer. Handles directive-attribute structural rewrites before compilation \u2014 sorting directives by declared priority and expanding compound directive expressions \u2014 so the compiler receives a clean, ordered AreHTMLNode tree ready for instruction emission."
|
|
2004
2122
|
})
|
|
2005
2123
|
], AreHTMLTransformer);
|
|
2124
|
+
var AreRootCache = class extends A_Fragment {
|
|
2125
|
+
constructor(limit = 10) {
|
|
2126
|
+
super({ name: "AreRootCache" });
|
|
2127
|
+
/**
|
|
2128
|
+
* rootId -> (component tag -> cache entry). The inner Map preserves
|
|
2129
|
+
* insertion order which is used as the LRU recency order: the first key is
|
|
2130
|
+
* the least-recently-used entry, the last key the most-recently-used.
|
|
2131
|
+
*/
|
|
2132
|
+
this._cache = /* @__PURE__ */ new Map();
|
|
2133
|
+
this._limit = Math.max(0, Math.floor(limit));
|
|
2134
|
+
}
|
|
2135
|
+
/**
|
|
2136
|
+
* Maximum number of cached subtrees kept per root.
|
|
2137
|
+
*/
|
|
2138
|
+
get limit() {
|
|
2139
|
+
return this._limit;
|
|
2140
|
+
}
|
|
2141
|
+
bucket(rootId) {
|
|
2142
|
+
let bucket = this._cache.get(rootId);
|
|
2143
|
+
if (!bucket) {
|
|
2144
|
+
bucket = /* @__PURE__ */ new Map();
|
|
2145
|
+
this._cache.set(rootId, bucket);
|
|
2146
|
+
}
|
|
2147
|
+
return bucket;
|
|
2148
|
+
}
|
|
2149
|
+
/**
|
|
2150
|
+
* Whether a subtree for the given component tag is currently cached.
|
|
2151
|
+
*/
|
|
2152
|
+
has(rootId, tag) {
|
|
2153
|
+
return this.bucket(rootId).has(tag);
|
|
2154
|
+
}
|
|
2155
|
+
/**
|
|
2156
|
+
* Retrieve AND remove a cached subtree so it can become live again. Returns
|
|
2157
|
+
* `undefined` on a cache miss.
|
|
2158
|
+
*/
|
|
2159
|
+
take(rootId, tag) {
|
|
2160
|
+
const bucket = this.bucket(rootId);
|
|
2161
|
+
const entry = bucket.get(tag);
|
|
2162
|
+
if (entry) {
|
|
2163
|
+
bucket.delete(tag);
|
|
2164
|
+
}
|
|
2165
|
+
return entry;
|
|
2166
|
+
}
|
|
2167
|
+
/**
|
|
2168
|
+
* Stash a detached subtree under the given component tag. Returns any entries
|
|
2169
|
+
* that were evicted to honour the LRU limit (or replaced for the same tag) so
|
|
2170
|
+
* the caller can `destroy()` them.
|
|
2171
|
+
*/
|
|
2172
|
+
put(rootId, tag, entry) {
|
|
2173
|
+
const bucket = this.bucket(rootId);
|
|
2174
|
+
const evicted = [];
|
|
2175
|
+
const existing = bucket.get(tag);
|
|
2176
|
+
if (existing) {
|
|
2177
|
+
bucket.delete(tag);
|
|
2178
|
+
if (existing.node !== entry.node) {
|
|
2179
|
+
evicted.push(existing);
|
|
2180
|
+
}
|
|
2181
|
+
}
|
|
2182
|
+
bucket.set(tag, entry);
|
|
2183
|
+
while (bucket.size > this._limit) {
|
|
2184
|
+
const oldestKey = bucket.keys().next().value;
|
|
2185
|
+
if (oldestKey === void 0) {
|
|
2186
|
+
break;
|
|
2187
|
+
}
|
|
2188
|
+
const oldest = bucket.get(oldestKey);
|
|
2189
|
+
bucket.delete(oldestKey);
|
|
2190
|
+
evicted.push(oldest);
|
|
2191
|
+
}
|
|
2192
|
+
return evicted;
|
|
2193
|
+
}
|
|
2194
|
+
/**
|
|
2195
|
+
* Remove and return every cached entry for a root (e.g. on teardown) so the
|
|
2196
|
+
* caller can destroy them.
|
|
2197
|
+
*/
|
|
2198
|
+
clear(rootId) {
|
|
2199
|
+
const bucket = this._cache.get(rootId);
|
|
2200
|
+
if (!bucket) {
|
|
2201
|
+
return [];
|
|
2202
|
+
}
|
|
2203
|
+
const entries = [...bucket.values()];
|
|
2204
|
+
bucket.clear();
|
|
2205
|
+
this._cache.delete(rootId);
|
|
2206
|
+
return entries;
|
|
2207
|
+
}
|
|
2208
|
+
};
|
|
2209
|
+
AreRootCache = __decorateClass([
|
|
2210
|
+
A_Frame.Define({
|
|
2211
|
+
namespace: "a-are-html",
|
|
2212
|
+
description: "AreRootCache is a fragment that keeps a small per-root LRU of previously rendered are-root subtrees. When an are-root swaps the component it displays, the outgoing subtree is stashed here (unmounted + detached, but not destroyed) so that routing back to it can re-inject the preserved scene instantly instead of rebuilding from scratch."
|
|
2213
|
+
})
|
|
2214
|
+
], AreRootCache);
|
|
2006
2215
|
|
|
2007
2216
|
// src/engine/AreHTML.engine.ts
|
|
2008
2217
|
var AreHTMLEngine = class extends AreEngine {
|
|
@@ -2049,7 +2258,7 @@ var AreHTMLEngine = class extends AreEngine {
|
|
|
2049
2258
|
]
|
|
2050
2259
|
});
|
|
2051
2260
|
}
|
|
2052
|
-
async init(scope, signalContext) {
|
|
2261
|
+
async init(scope, signalContext, rootCache) {
|
|
2053
2262
|
this.package(scope, {
|
|
2054
2263
|
context: new AreHTMLEngineContext({}),
|
|
2055
2264
|
syntax: this.DefaultSyntax,
|
|
@@ -2063,6 +2272,10 @@ var AreHTMLEngine = class extends AreEngine {
|
|
|
2063
2272
|
signalContext = new AreSignalsContext();
|
|
2064
2273
|
scope.register(signalContext);
|
|
2065
2274
|
}
|
|
2275
|
+
if (!rootCache) {
|
|
2276
|
+
rootCache = new AreRootCache();
|
|
2277
|
+
scope.register(rootCache);
|
|
2278
|
+
}
|
|
2066
2279
|
}
|
|
2067
2280
|
rootElementMatcher(source, from, to, build) {
|
|
2068
2281
|
const rootTag = "are-root";
|
|
@@ -2172,7 +2385,8 @@ __decorateClass([
|
|
|
2172
2385
|
before: /.*/
|
|
2173
2386
|
}),
|
|
2174
2387
|
__decorateParam(0, A_Inject(A_Scope)),
|
|
2175
|
-
__decorateParam(1, A_Inject(AreSignalsContext))
|
|
2388
|
+
__decorateParam(1, A_Inject(AreSignalsContext)),
|
|
2389
|
+
__decorateParam(2, A_Inject(AreRootCache))
|
|
2176
2390
|
], AreHTMLEngine.prototype, "init", 1);
|
|
2177
2391
|
AreHTMLEngine = __decorateClass([
|
|
2178
2392
|
A_Frame.Define({
|
|
@@ -2181,7 +2395,7 @@ AreHTMLEngine = __decorateClass([
|
|
|
2181
2395
|
})
|
|
2182
2396
|
], AreHTMLEngine);
|
|
2183
2397
|
var AreRoot = class extends Are {
|
|
2184
|
-
async template(root, logger, signalsContext) {
|
|
2398
|
+
async template(root, logger, signalsContext, signalState) {
|
|
2185
2399
|
const rootId = root.id;
|
|
2186
2400
|
if (signalsContext && !signalsContext.hasRoot(rootId)) {
|
|
2187
2401
|
if (!root.content?.trim()) {
|
|
@@ -2193,26 +2407,9 @@ var AreRoot = class extends Are {
|
|
|
2193
2407
|
}
|
|
2194
2408
|
return;
|
|
2195
2409
|
}
|
|
2196
|
-
const
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
const initialVector = new A_SignalVector([currentRoute]);
|
|
2200
|
-
let renderTarget = signalsContext?.findComponentByVector(rootId, initialVector);
|
|
2201
|
-
if (!renderTarget) {
|
|
2202
|
-
const signalsMeta = A_Context.meta(AreSignals);
|
|
2203
|
-
const pool = signalsContext?.getComponentById(rootId);
|
|
2204
|
-
const metaTarget = signalsMeta?.findComponentByVector(
|
|
2205
|
-
initialVector,
|
|
2206
|
-
pool?.length ? pool : void 0
|
|
2207
|
-
);
|
|
2208
|
-
if (metaTarget && (!pool?.length || pool.includes(metaTarget))) {
|
|
2209
|
-
renderTarget = metaTarget;
|
|
2210
|
-
}
|
|
2211
|
-
}
|
|
2212
|
-
if (renderTarget?.name) {
|
|
2213
|
-
componentName = A_FormatterHelper.toKebabCase(renderTarget.name);
|
|
2214
|
-
}
|
|
2215
|
-
}
|
|
2410
|
+
const initialVector = this.buildInitialVector(signalState);
|
|
2411
|
+
const renderTarget = this.matchComponent(rootId, initialVector, signalsContext);
|
|
2412
|
+
let componentName = renderTarget?.name ? A_FormatterHelper.toKebabCase(renderTarget.name) : void 0;
|
|
2216
2413
|
if (!componentName) {
|
|
2217
2414
|
if (root.content?.trim()) {
|
|
2218
2415
|
return;
|
|
@@ -2234,32 +2431,17 @@ var AreRoot = class extends Are {
|
|
|
2234
2431
|
}
|
|
2235
2432
|
root.setContent(`<${componentName}></${componentName}>`);
|
|
2236
2433
|
}
|
|
2237
|
-
async onSignal(root, vector, logger, signalsContext) {
|
|
2434
|
+
async onSignal(root, vector, logger, signalsContext, cache) {
|
|
2238
2435
|
const rootId = root.id;
|
|
2239
2436
|
if (signalsContext && !signalsContext.hasRoot(rootId)) {
|
|
2240
2437
|
return;
|
|
2241
2438
|
}
|
|
2242
|
-
|
|
2243
|
-
if (!renderTarget) {
|
|
2244
|
-
const signalsMeta = A_Context.meta(AreSignals);
|
|
2245
|
-
const pool = signalsContext?.getComponentById(rootId);
|
|
2246
|
-
const metaTarget = signalsMeta?.findComponentByVector(
|
|
2247
|
-
vector,
|
|
2248
|
-
pool?.length ? pool : void 0
|
|
2249
|
-
);
|
|
2250
|
-
if (metaTarget && (!pool?.length || pool.includes(metaTarget))) {
|
|
2251
|
-
renderTarget = metaTarget;
|
|
2252
|
-
}
|
|
2253
|
-
}
|
|
2439
|
+
const renderTarget = this.matchComponent(rootId, vector, signalsContext);
|
|
2254
2440
|
const def = signalsContext?.getDefault(rootId);
|
|
2255
2441
|
const componentName = renderTarget?.name ? A_FormatterHelper.toKebabCase(renderTarget.name) : def?.name ? A_FormatterHelper.toKebabCase(def.name) : void 0;
|
|
2256
2442
|
if (!componentName) {
|
|
2257
|
-
for (
|
|
2258
|
-
|
|
2259
|
-
signalsContext?.unsubscribe(child);
|
|
2260
|
-
child.unmount();
|
|
2261
|
-
child.destroy();
|
|
2262
|
-
root.removeChild(child);
|
|
2443
|
+
for (const child of [...root.children]) {
|
|
2444
|
+
this.stashChild(root, child, signalsContext, cache);
|
|
2263
2445
|
}
|
|
2264
2446
|
root.setContent("");
|
|
2265
2447
|
return;
|
|
@@ -2268,13 +2450,14 @@ var AreRoot = class extends Are {
|
|
|
2268
2450
|
if (currentChild?.type === componentName) {
|
|
2269
2451
|
return;
|
|
2270
2452
|
}
|
|
2453
|
+
for (const child of [...root.children]) {
|
|
2454
|
+
this.stashChild(root, child, signalsContext, cache);
|
|
2455
|
+
}
|
|
2271
2456
|
root.setContent(`<${componentName}></${componentName}>`);
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
signalsContext
|
|
2275
|
-
|
|
2276
|
-
child.destroy();
|
|
2277
|
-
root.removeChild(child);
|
|
2457
|
+
const cached = cache?.take(root.id, componentName);
|
|
2458
|
+
if (cached) {
|
|
2459
|
+
this.restoreChild(root, cached, signalsContext);
|
|
2460
|
+
return;
|
|
2278
2461
|
}
|
|
2279
2462
|
root.tokenize();
|
|
2280
2463
|
for (let i = 0; i < root.children.length; i++) {
|
|
@@ -2289,19 +2472,138 @@ var AreRoot = class extends Are {
|
|
|
2289
2472
|
child.mount();
|
|
2290
2473
|
}
|
|
2291
2474
|
}
|
|
2475
|
+
/**
|
|
2476
|
+
* Resolves the component a vector should render for the given root, mirroring
|
|
2477
|
+
* the priority used everywhere in the routing system:
|
|
2478
|
+
* 1. Root-specific conditions registered on AreSignalsContext.
|
|
2479
|
+
* 2. The global AreSignalsMeta map, restricted to this outlet's pool.
|
|
2480
|
+
*
|
|
2481
|
+
* Passing the pool *into* the meta lookup is critical: without it, the first
|
|
2482
|
+
* globally matching component wins and may belong to a different outlet
|
|
2483
|
+
* (e.g. AisRequirementsPanel for the meta-outlet matching
|
|
2484
|
+
* AisEditorCursorScope) — the pool check would then reject it and the outlet
|
|
2485
|
+
* would fall back to its default, hiding a valid in-pool match (e.g.
|
|
2486
|
+
* AisDiagramTab matching AisSetPrimaryDisplay).
|
|
2487
|
+
*
|
|
2488
|
+
* Returns `undefined` when nothing matches — callers decide whether to use a
|
|
2489
|
+
* configured default, body content, or clear the outlet.
|
|
2490
|
+
*/
|
|
2491
|
+
matchComponent(rootId, vector, signalsContext) {
|
|
2492
|
+
if (!vector) return void 0;
|
|
2493
|
+
let renderTarget = signalsContext?.findComponentByVector(rootId, vector);
|
|
2494
|
+
if (!renderTarget) {
|
|
2495
|
+
const signalsMeta = A_Context.meta(AreSignals);
|
|
2496
|
+
const pool = signalsContext?.getComponentById(rootId);
|
|
2497
|
+
const metaTarget = signalsMeta?.findComponentByVector(
|
|
2498
|
+
vector,
|
|
2499
|
+
pool?.length ? pool : void 0,
|
|
2500
|
+
rootId
|
|
2501
|
+
);
|
|
2502
|
+
if (metaTarget && (!pool?.length || pool.includes(metaTarget))) {
|
|
2503
|
+
renderTarget = metaTarget;
|
|
2504
|
+
}
|
|
2505
|
+
}
|
|
2506
|
+
return renderTarget;
|
|
2507
|
+
}
|
|
2508
|
+
/**
|
|
2509
|
+
* Builds the vector used for the INITIAL render. It is seeded from the
|
|
2510
|
+
* accumulated signal state (every signal dispatched on the bus so far) so a
|
|
2511
|
+
* freshly-mounted outlet reflects the live application state immediately,
|
|
2512
|
+
* not just on the next signal tick. The current URL route is appended when
|
|
2513
|
+
* no AreRoute is already present in the state, so route-driven outlets still
|
|
2514
|
+
* resolve on the very first paint (before AreRouteWatcher has dispatched).
|
|
2515
|
+
*/
|
|
2516
|
+
buildInitialVector(signalState) {
|
|
2517
|
+
const signals = [];
|
|
2518
|
+
if (signalState) {
|
|
2519
|
+
for (const signal of signalState.toVector()) {
|
|
2520
|
+
if (signal) signals.push(signal);
|
|
2521
|
+
}
|
|
2522
|
+
}
|
|
2523
|
+
if (!signals.some((signal) => signal instanceof AreRoute)) {
|
|
2524
|
+
try {
|
|
2525
|
+
const currentRoute = AreRoute.default();
|
|
2526
|
+
if (currentRoute) signals.push(currentRoute);
|
|
2527
|
+
} catch {
|
|
2528
|
+
}
|
|
2529
|
+
}
|
|
2530
|
+
return new A_SignalVector(signals);
|
|
2531
|
+
}
|
|
2532
|
+
/**
|
|
2533
|
+
* Detach a displayed child subtree from the outlet and stash it in the cache
|
|
2534
|
+
* for fast re-injection later. The subtree is unmounted (its scene plan is
|
|
2535
|
+
* preserved) and deregistered from the root scope, but NOT destroyed. The
|
|
2536
|
+
* nodes that were subscribed to the signal bus are unsubscribed while cached
|
|
2537
|
+
* so the detached DOM never reacts to signals, and recorded so they can be
|
|
2538
|
+
* re-subscribed verbatim on restore.
|
|
2539
|
+
*
|
|
2540
|
+
* When no cache is available, or the LRU evicts an entry, the affected
|
|
2541
|
+
* subtree is fully destroyed.
|
|
2542
|
+
*/
|
|
2543
|
+
stashChild(root, child, signalsContext, cache) {
|
|
2544
|
+
const tag = child.type;
|
|
2545
|
+
child.unmount();
|
|
2546
|
+
const subscribers = signalsContext ? this.collectSubscribers(child, signalsContext) : [];
|
|
2547
|
+
for (const node of subscribers) {
|
|
2548
|
+
signalsContext?.unsubscribe(node);
|
|
2549
|
+
}
|
|
2550
|
+
root.removeChild(child);
|
|
2551
|
+
if (!cache) {
|
|
2552
|
+
void child.destroy();
|
|
2553
|
+
return;
|
|
2554
|
+
}
|
|
2555
|
+
const evicted = cache.put(root.id, tag, { node: child, subscribers });
|
|
2556
|
+
for (const entry of evicted) {
|
|
2557
|
+
void entry.node.destroy();
|
|
2558
|
+
}
|
|
2559
|
+
}
|
|
2560
|
+
/**
|
|
2561
|
+
* Re-attach a cached subtree to the outlet and re-mount it from its preserved
|
|
2562
|
+
* scene plan, re-subscribing exactly the nodes that were subscribed before it
|
|
2563
|
+
* was cached.
|
|
2564
|
+
*/
|
|
2565
|
+
restoreChild(root, entry, signalsContext) {
|
|
2566
|
+
const child = entry.node;
|
|
2567
|
+
root.addChild(child);
|
|
2568
|
+
for (const node of entry.subscribers) {
|
|
2569
|
+
signalsContext?.subscribe(node);
|
|
2570
|
+
}
|
|
2571
|
+
child.mount();
|
|
2572
|
+
}
|
|
2573
|
+
/**
|
|
2574
|
+
* Walk a subtree and collect the nodes currently registered as signal
|
|
2575
|
+
* subscribers. Mirrors the subscription performed at init time in
|
|
2576
|
+
* AreHTMLLifecycle (component nodes and root nodes) without depending on the
|
|
2577
|
+
* concrete node classes — it simply intersects the subtree with the live
|
|
2578
|
+
* subscriber registry.
|
|
2579
|
+
*/
|
|
2580
|
+
collectSubscribers(node, signalsContext) {
|
|
2581
|
+
const result = [];
|
|
2582
|
+
const queue = [node];
|
|
2583
|
+
while (queue.length > 0) {
|
|
2584
|
+
const current = queue.shift();
|
|
2585
|
+
if (signalsContext.subscribers.has(current)) {
|
|
2586
|
+
result.push(current);
|
|
2587
|
+
}
|
|
2588
|
+
queue.push(...current.children);
|
|
2589
|
+
}
|
|
2590
|
+
return result;
|
|
2591
|
+
}
|
|
2292
2592
|
};
|
|
2293
2593
|
__decorateClass([
|
|
2294
2594
|
Are.Template,
|
|
2295
2595
|
__decorateParam(0, A_Inject(A_Caller)),
|
|
2296
2596
|
__decorateParam(1, A_Inject(A_Logger)),
|
|
2297
|
-
__decorateParam(2, A_Inject(AreSignalsContext))
|
|
2597
|
+
__decorateParam(2, A_Inject(AreSignalsContext)),
|
|
2598
|
+
__decorateParam(3, A_Inject(A_SignalState))
|
|
2298
2599
|
], AreRoot.prototype, "template", 1);
|
|
2299
2600
|
__decorateClass([
|
|
2300
2601
|
Are.Signal,
|
|
2301
2602
|
__decorateParam(0, A_Inject(A_Caller)),
|
|
2302
2603
|
__decorateParam(1, A_Inject(A_SignalVector)),
|
|
2303
2604
|
__decorateParam(2, A_Inject(A_Logger)),
|
|
2304
|
-
__decorateParam(3, A_Inject(AreSignalsContext))
|
|
2605
|
+
__decorateParam(3, A_Inject(AreSignalsContext)),
|
|
2606
|
+
__decorateParam(4, A_Inject(AreRootCache))
|
|
2305
2607
|
], AreRoot.prototype, "onSignal", 1);
|
|
2306
2608
|
AreRoot = __decorateClass([
|
|
2307
2609
|
A_Frame.Define({
|
|
@@ -2372,6 +2674,6 @@ AreRouteWatcher = __decorateClass([
|
|
|
2372
2674
|
})
|
|
2373
2675
|
], AreRouteWatcher);
|
|
2374
2676
|
|
|
2375
|
-
export { AddAttributeInstruction, AddElementInstruction, AddInterpolationInstruction, AddListenerInstruction, AddStyleInstruction, AddTextInstruction, AreBindingAttribute, AreComment, AreComponentNode, AreDirective, AreDirectiveAttribute, AreDirectiveContext, AreDirectiveFeatures, AreDirectiveFor, AreDirectiveIf, AreDirectiveMeta, AreEventAttribute, AreHTMLAttribute, AreHTMLCompiler, AreHTMLEngine, AreHTMLEngineContext, AreHTMLInstructions, AreHTMLInterpreter, AreHTMLLifecycle, AreHTMLNode, AreHTMLTokenizer, AreHTMLTransformer, AreInterpolation, AreRoot, AreRootNode, AreRoute, AreRouteWatcher, AreStaticAttribute, AreStyle, AreText, BOOLEAN_ATTRIBUTES, IDL_FORM_PROPERTIES, LISTENER_OPTION_MODIFIERS, SVG_ATTRIBUTE_NS, SVG_NAMESPACE, VOID_ELEMENTS, isBooleanAttribute, isIDLFormProperty, isVoidElement, normalizeClassValue, normalizeStyleValue, parseEventName, toDOMString };
|
|
2677
|
+
export { AddAttributeInstruction, AddElementInstruction, AddInterpolationInstruction, AddListenerInstruction, AddStyleInstruction, AddTextInstruction, AreBindingAttribute, AreComment, AreComponentNode, AreDirective, AreDirectiveAttribute, AreDirectiveContext, AreDirectiveFeatures, AreDirectiveFor, AreDirectiveIf, AreDirectiveMeta, AreDirectiveShow, AreEventAttribute, AreHTMLAttribute, AreHTMLCompiler, AreHTMLEngine, AreHTMLEngineContext, AreHTMLInstructions, AreHTMLInterpreter, AreHTMLLifecycle, AreHTMLNode, AreHTMLTokenizer, AreHTMLTransformer, AreInterpolation, AreRoot, AreRootCache, AreRootNode, AreRoute, AreRouteWatcher, AreStaticAttribute, AreStyle, AreText, BOOLEAN_ATTRIBUTES, HideElementInstruction, IDL_FORM_PROPERTIES, LISTENER_OPTION_MODIFIERS, SVG_ATTRIBUTE_NS, SVG_NAMESPACE, VOID_ELEMENTS, isBooleanAttribute, isIDLFormProperty, isVoidElement, normalizeClassValue, normalizeStyleValue, parseEventName, toDOMString };
|
|
2376
2678
|
//# sourceMappingURL=index.mjs.map
|
|
2377
2679
|
//# sourceMappingURL=index.mjs.map
|