@adaas/are-html 0.0.21 → 0.0.23

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.
Files changed (154) hide show
  1. package/.conf/tsconfig.base.json +1 -0
  2. package/.conf/tsconfig.browser.json +1 -0
  3. package/.conf/tsconfig.node.json +1 -0
  4. package/dist/browser/index.d.mts +214 -3
  5. package/dist/browser/index.mjs +787 -201
  6. package/dist/browser/index.mjs.map +1 -1
  7. package/dist/node/{AreBinding.attribute-doUvtOjc.d.mts → AreBinding.attribute-BWzEIw6H.d.mts} +45 -0
  8. package/dist/node/{AreBinding.attribute-Bm5LlOyE.d.ts → AreBinding.attribute-GpT-5Qmf.d.ts} +45 -0
  9. package/dist/node/attributes/AreBinding.attribute.d.mts +1 -1
  10. package/dist/node/attributes/AreBinding.attribute.d.ts +1 -1
  11. package/dist/node/attributes/AreDirective.attribute.d.mts +1 -1
  12. package/dist/node/attributes/AreDirective.attribute.d.ts +1 -1
  13. package/dist/node/attributes/AreEvent.attribute.d.mts +1 -1
  14. package/dist/node/attributes/AreEvent.attribute.d.ts +1 -1
  15. package/dist/node/attributes/AreStatic.attribute.d.mts +1 -1
  16. package/dist/node/attributes/AreStatic.attribute.d.ts +1 -1
  17. package/dist/node/directives/AreDirectiveFor.directive.d.mts +55 -2
  18. package/dist/node/directives/AreDirectiveFor.directive.d.ts +55 -2
  19. package/dist/node/directives/AreDirectiveFor.directive.js +141 -12
  20. package/dist/node/directives/AreDirectiveFor.directive.js.map +1 -1
  21. package/dist/node/directives/AreDirectiveFor.directive.mjs +141 -12
  22. package/dist/node/directives/AreDirectiveFor.directive.mjs.map +1 -1
  23. package/dist/node/directives/AreDirectiveIf.directive.d.mts +1 -1
  24. package/dist/node/directives/AreDirectiveIf.directive.d.ts +1 -1
  25. package/dist/node/directives/AreDirectiveShow.directive.d.mts +1 -1
  26. package/dist/node/directives/AreDirectiveShow.directive.d.ts +1 -1
  27. package/dist/node/engine/AreHTML.compiler.d.mts +1 -1
  28. package/dist/node/engine/AreHTML.compiler.d.ts +1 -1
  29. package/dist/node/engine/AreHTML.compiler.js +4 -0
  30. package/dist/node/engine/AreHTML.compiler.js.map +1 -1
  31. package/dist/node/engine/AreHTML.compiler.mjs +4 -0
  32. package/dist/node/engine/AreHTML.compiler.mjs.map +1 -1
  33. package/dist/node/engine/AreHTML.constants.d.mts +33 -1
  34. package/dist/node/engine/AreHTML.constants.d.ts +33 -1
  35. package/dist/node/engine/AreHTML.constants.js +166 -0
  36. package/dist/node/engine/AreHTML.constants.js.map +1 -1
  37. package/dist/node/engine/AreHTML.constants.mjs +165 -1
  38. package/dist/node/engine/AreHTML.constants.mjs.map +1 -1
  39. package/dist/node/engine/AreHTML.context.d.mts +66 -0
  40. package/dist/node/engine/AreHTML.context.d.ts +66 -0
  41. package/dist/node/engine/AreHTML.context.js +98 -0
  42. package/dist/node/engine/AreHTML.context.js.map +1 -1
  43. package/dist/node/engine/AreHTML.context.mjs +98 -0
  44. package/dist/node/engine/AreHTML.context.mjs.map +1 -1
  45. package/dist/node/engine/AreHTML.interpreter.d.mts +3 -0
  46. package/dist/node/engine/AreHTML.interpreter.d.ts +3 -0
  47. package/dist/node/engine/AreHTML.interpreter.js +66 -10
  48. package/dist/node/engine/AreHTML.interpreter.js.map +1 -1
  49. package/dist/node/engine/AreHTML.interpreter.mjs +66 -10
  50. package/dist/node/engine/AreHTML.interpreter.mjs.map +1 -1
  51. package/dist/node/engine/AreHTML.lifecycle.d.mts +2 -2
  52. package/dist/node/engine/AreHTML.lifecycle.d.ts +2 -2
  53. package/dist/node/engine/AreHTML.lifecycle.js +32 -4
  54. package/dist/node/engine/AreHTML.lifecycle.js.map +1 -1
  55. package/dist/node/engine/AreHTML.lifecycle.mjs +32 -4
  56. package/dist/node/engine/AreHTML.lifecycle.mjs.map +1 -1
  57. package/dist/node/engine/AreHTML.tokenizer.d.mts +1 -1
  58. package/dist/node/engine/AreHTML.tokenizer.d.ts +1 -1
  59. package/dist/node/engine/AreHTML.tokenizer.js +7 -1
  60. package/dist/node/engine/AreHTML.tokenizer.js.map +1 -1
  61. package/dist/node/engine/AreHTML.tokenizer.mjs +7 -1
  62. package/dist/node/engine/AreHTML.tokenizer.mjs.map +1 -1
  63. package/dist/node/engine/AreHTML.transformer.d.mts +1 -1
  64. package/dist/node/engine/AreHTML.transformer.d.ts +1 -1
  65. package/dist/node/helpers/AreScheduler.helper.d.mts +39 -0
  66. package/dist/node/helpers/AreScheduler.helper.d.ts +39 -0
  67. package/dist/node/helpers/AreScheduler.helper.js +40 -0
  68. package/dist/node/helpers/AreScheduler.helper.js.map +1 -0
  69. package/dist/node/helpers/AreScheduler.helper.mjs +40 -0
  70. package/dist/node/helpers/AreScheduler.helper.mjs.map +1 -0
  71. package/dist/node/index.d.mts +4 -3
  72. package/dist/node/index.d.ts +4 -3
  73. package/dist/node/index.js +7 -0
  74. package/dist/node/index.mjs +1 -0
  75. package/dist/node/instructions/AddStaticHTML.instruction.d.mts +8 -0
  76. package/dist/node/instructions/AddStaticHTML.instruction.d.ts +8 -0
  77. package/dist/node/instructions/AddStaticHTML.instruction.js +31 -0
  78. package/dist/node/instructions/AddStaticHTML.instruction.js.map +1 -0
  79. package/dist/node/instructions/AddStaticHTML.instruction.mjs +24 -0
  80. package/dist/node/instructions/AddStaticHTML.instruction.mjs.map +1 -0
  81. package/dist/node/instructions/AreHTML.instructions.constants.d.mts +1 -0
  82. package/dist/node/instructions/AreHTML.instructions.constants.d.ts +1 -0
  83. package/dist/node/instructions/AreHTML.instructions.constants.js +1 -0
  84. package/dist/node/instructions/AreHTML.instructions.constants.js.map +1 -1
  85. package/dist/node/instructions/AreHTML.instructions.constants.mjs +1 -0
  86. package/dist/node/instructions/AreHTML.instructions.constants.mjs.map +1 -1
  87. package/dist/node/instructions/AreHTML.instructions.types.d.mts +9 -1
  88. package/dist/node/instructions/AreHTML.instructions.types.d.ts +9 -1
  89. package/dist/node/lib/AreDirective/AreDirective.component.d.mts +1 -1
  90. package/dist/node/lib/AreDirective/AreDirective.component.d.ts +1 -1
  91. package/dist/node/lib/AreDirective/AreDirective.types.d.mts +1 -1
  92. package/dist/node/lib/AreDirective/AreDirective.types.d.ts +1 -1
  93. package/dist/node/lib/AreHTML/AreHTML.tokenizer.d.mts +1 -1
  94. package/dist/node/lib/AreHTML/AreHTML.tokenizer.d.ts +1 -1
  95. package/dist/node/lib/AreHTMLAttribute/AreHTML.attribute.d.mts +1 -1
  96. package/dist/node/lib/AreHTMLAttribute/AreHTML.attribute.d.ts +1 -1
  97. package/dist/node/lib/AreHTMLNode/AreHTMLNode.d.mts +1 -1
  98. package/dist/node/lib/AreHTMLNode/AreHTMLNode.d.ts +1 -1
  99. package/dist/node/lib/AreHTMLNode/AreHTMLNode.js +51 -0
  100. package/dist/node/lib/AreHTMLNode/AreHTMLNode.js.map +1 -1
  101. package/dist/node/lib/AreHTMLNode/AreHTMLNode.mjs +51 -0
  102. package/dist/node/lib/AreHTMLNode/AreHTMLNode.mjs.map +1 -1
  103. package/dist/node/lib/AreRoot/AreRoot.component.js +1 -1
  104. package/dist/node/lib/AreRoot/AreRoot.component.js.map +1 -1
  105. package/dist/node/lib/AreRoot/AreRoot.component.mjs +1 -1
  106. package/dist/node/lib/AreRoot/AreRoot.component.mjs.map +1 -1
  107. package/dist/node/nodes/AreComment.d.mts +1 -1
  108. package/dist/node/nodes/AreComment.d.ts +1 -1
  109. package/dist/node/nodes/AreComponent.d.mts +1 -1
  110. package/dist/node/nodes/AreComponent.d.ts +1 -1
  111. package/dist/node/nodes/AreInterpolation.d.mts +1 -1
  112. package/dist/node/nodes/AreInterpolation.d.ts +1 -1
  113. package/dist/node/nodes/AreRoot.d.mts +1 -1
  114. package/dist/node/nodes/AreRoot.d.ts +1 -1
  115. package/dist/node/nodes/AreText.d.mts +1 -1
  116. package/dist/node/nodes/AreText.d.ts +1 -1
  117. package/examples/dashboard/concept.ts +1 -1
  118. package/examples/dashboard/dist/index.html +1 -1
  119. package/examples/dashboard/dist/{mq19zxz4-mnlgmd.js → mqiw5sqa-ypckmj.js} +2275 -1323
  120. package/examples/dashboard/src/concept.ts +3 -2
  121. package/examples/for-perf/concept.ts +45 -0
  122. package/examples/for-perf/containers/UI.container.ts +161 -0
  123. package/examples/for-perf/dist/index.html +270 -0
  124. package/examples/for-perf/dist/mqj1mpf2-z4aokv.js +15664 -0
  125. package/examples/for-perf/dist/mqj1mpff-4fr7mw.js +15664 -0
  126. package/examples/for-perf/public/index.html +270 -0
  127. package/examples/for-perf/src/components/PerfApp.component.ts +37 -0
  128. package/examples/for-perf/src/components/PerfControls.component.ts +34 -0
  129. package/examples/for-perf/src/components/PerfGrid.component.ts +225 -0
  130. package/examples/for-perf/src/components/PerfHeader.component.ts +34 -0
  131. package/examples/for-perf/src/components/PerfStats.component.ts +43 -0
  132. package/examples/for-perf/src/concept.ts +94 -0
  133. package/examples/jumpstart/dist/index.html +1 -1
  134. package/examples/jumpstart/dist/{mq7hqrxy-4kus50.js → mq7mgf58-vbf07e.js} +269 -91
  135. package/examples/signal-routing/dist/index.html +1 -1
  136. package/examples/signal-routing/dist/{mq7k53th-qiwy4x.js → mqiwo23h-bhcolu.js} +2090 -1430
  137. package/jest.config.ts +1 -0
  138. package/package.json +10 -9
  139. package/src/directives/AreDirectiveFor.directive.ts +233 -19
  140. package/src/engine/AreHTML.compiler.ts +13 -0
  141. package/src/engine/AreHTML.constants.ts +142 -0
  142. package/src/engine/AreHTML.context.ts +112 -0
  143. package/src/engine/AreHTML.interpreter.ts +114 -13
  144. package/src/engine/AreHTML.lifecycle.ts +91 -7
  145. package/src/engine/AreHTML.tokenizer.ts +30 -1
  146. package/src/helpers/AreScheduler.helper.ts +61 -0
  147. package/src/index.ts +1 -0
  148. package/src/instructions/AddStaticHTML.instruction.ts +23 -0
  149. package/src/instructions/AreHTML.instructions.constants.ts +1 -0
  150. package/src/instructions/AreHTML.instructions.types.ts +9 -0
  151. package/src/lib/AreHTMLNode/AreHTMLNode.ts +74 -0
  152. package/src/lib/AreRoot/AreRoot.component.ts +4 -1
  153. package/tests/StaticIsland.test.ts +115 -0
  154. package/tsconfig.json +1 -0
@@ -0,0 +1,94 @@
1
+ import { A_Concept, A_Context } from "@adaas/a-concept"
2
+ import { A_Config, ConfigReader } from "@adaas/a-utils/a-config";
3
+ import { A_Logger, A_LOGGER_ENV_KEYS } from "@adaas/a-utils/a-logger";
4
+ import { A_SignalBus, A_SignalState } from "@adaas/a-utils/a-signal";
5
+ import { A_Polyfill } from "@adaas/a-utils/a-polyfill";
6
+ import { AreRoot } from "src/lib/AreRoot/AreRoot.component";
7
+ import { AreHTMLEngine } from "src/engine/AreHTML.engine";
8
+ import { AreContainer, AreInit } from "@adaas/are";
9
+ import { AreRoute } from "@adaas/are";
10
+ import { AreHTMLEngineContext } from "src/engine/AreHTML.context";
11
+ import { AreDirectiveIf } from "src/directives/AreDirectiveIf.directive";
12
+ import { AreDirectiveFor } from "src/directives/AreDirectiveFor.directive";
13
+
14
+ import { PerfApp } from "./components/PerfApp.component";
15
+ import { PerfHeader } from "./components/PerfHeader.component";
16
+ import { PerfControls } from "./components/PerfControls.component";
17
+ import { PerfStats } from "./components/PerfStats.component";
18
+ import { PerfGrid } from "./components/PerfGrid.component";
19
+
20
+
21
+ (async () => {
22
+ try {
23
+
24
+ const container = new AreContainer({
25
+ name: 'ARE For-Perf',
26
+ components: [
27
+ // ----------------------------------
28
+ // UI Components
29
+ // ----------------------------------
30
+ PerfApp,
31
+ PerfHeader,
32
+ PerfControls,
33
+ PerfStats,
34
+ PerfGrid,
35
+ // ----------------------------------
36
+ // Directives
37
+ // ----------------------------------
38
+ AreDirectiveIf,
39
+ AreDirectiveFor,
40
+ // ----------------------------------
41
+ // Engine Components
42
+ // ----------------------------------
43
+ A_SignalBus,
44
+ // ----------------------------------
45
+ // Addons
46
+ // ----------------------------------
47
+ AreRoot,
48
+ ConfigReader,
49
+ AreHTMLEngine,
50
+ A_Logger,
51
+ ],
52
+ entities: [
53
+ AreInit,
54
+ AreRoute
55
+ ],
56
+ fragments: [
57
+ new A_SignalState([AreRoute]),
58
+ new AreHTMLEngineContext({
59
+ container: document
60
+ }),
61
+
62
+ new A_Config({
63
+ defaults: {
64
+ [A_LOGGER_ENV_KEYS.LOG_LEVEL]: 'error',
65
+ }
66
+ }),
67
+ ]
68
+ });
69
+
70
+ const concept = new A_Concept({
71
+ name: 'adaas-are-example-for-perf',
72
+ fragments: [new A_Config({
73
+ variables: ['CONFIG_VERBOSE', 'DEV_MODE'] as const,
74
+ defaults: {
75
+ CONFIG_VERBOSE: true,
76
+ DEV_MODE: true
77
+ }
78
+ })],
79
+ components: [A_Logger, ConfigReader, A_Polyfill],
80
+ containers: [container]
81
+ })
82
+
83
+ console.log('Building Concept...');
84
+ await concept.load();
85
+ console.log('✓ Concept loaded successfully.');
86
+ await concept.start();
87
+
88
+
89
+ } catch (error) {
90
+ const logger = A_Context.root.resolve<A_Logger>(A_Logger)!;
91
+ logger.error(error);
92
+ }
93
+
94
+ })();
@@ -98,7 +98,7 @@
98
98
  <list-component></list-component>
99
99
  </are-root>
100
100
 
101
- <script type="module" src="./mq7hqrxy-4kus50.js"></script>
101
+ <script type="module" src="./mq7mgf58-vbf07e.js"></script>
102
102
  </body>
103
103
 
104
104
  </html>
@@ -9665,7 +9665,26 @@ AreEvent = __decorateClass3([
9665
9665
  ], AreEvent);
9666
9666
  var _a131;
9667
9667
  var AreSignalsMeta = (_a131 = class extends z {
9668
- registerCondition(component, vector) {
9668
+ /**
9669
+ * Registers a condition vector for a component.
9670
+ *
9671
+ * @param component The component constructor to render when the condition matches.
9672
+ * @param vector The signal vector that activates the component.
9673
+ * @param root Optional root id. When provided, the condition only
9674
+ * applies to the outlet with that id (per-root targeting).
9675
+ * When omitted, the condition applies to ALL roots — this
9676
+ * is the original, root-agnostic behavior.
9677
+ */
9678
+ registerCondition(component, vector, root) {
9679
+ if (root) {
9680
+ const rootScopedConditions = this.get("rootScopedConditions") || /* @__PURE__ */ new Map();
9681
+ if (!rootScopedConditions.has(root)) {
9682
+ rootScopedConditions.set(root, /* @__PURE__ */ new Map());
9683
+ }
9684
+ rootScopedConditions.get(root).set(vector, component);
9685
+ this.set("rootScopedConditions", rootScopedConditions);
9686
+ return;
9687
+ }
9669
9688
  const vectorToComponent = this.get("vectorToComponent") || /* @__PURE__ */ new Map();
9670
9689
  const componentToVector = this.get("componentToVector") || /* @__PURE__ */ new Map();
9671
9690
  vectorToComponent.set(vector, component);
@@ -9690,33 +9709,55 @@ var AreSignalsMeta = (_a131 = class extends z {
9690
9709
  * @param vector The incoming signal vector.
9691
9710
  * @param allowed Optional set/array of component constructors to consider.
9692
9711
  * When omitted, every registered component is eligible.
9712
+ * @param root Optional root id. When provided, conditions registered
9713
+ * specifically for that root (via `@Are.Condition(vector,
9714
+ * { root })`) are considered FIRST and take priority over
9715
+ * global, root-agnostic conditions. Conditions scoped to a
9716
+ * DIFFERENT root are never returned here.
9693
9717
  */
9694
- findComponentByVector(vector, allowed) {
9718
+ findComponentByVector(vector, allowed, root) {
9695
9719
  if (!vector) return void 0;
9696
9720
  const allowedSet = allowed ? allowed instanceof Set ? allowed : new Set(allowed) : void 0;
9697
9721
  const isAllowed = /* @__PURE__ */ __name((component) => !allowedSet || allowedSet.has(component), "isAllowed");
9722
+ if (root) {
9723
+ const rootScoped = this.get("rootScopedConditions")?.get(root);
9724
+ if (rootScoped) {
9725
+ const match = this.matchInMap(rootScoped, vector, isAllowed);
9726
+ if (match) return match;
9727
+ }
9728
+ }
9698
9729
  const vectorToComponent = this.get("vectorToComponent");
9699
9730
  if (vectorToComponent) {
9700
- const component = vectorToComponent.get(vector);
9701
- if (component && isAllowed(component)) {
9731
+ return this.matchInMap(vectorToComponent, vector, isAllowed);
9732
+ }
9733
+ return void 0;
9734
+ }
9735
+ /**
9736
+ * Resolves the best component from a vector→component map using the
9737
+ * three-tier priority shared by all condition matching:
9738
+ * 1. Simple identity lookup (same vector instance).
9739
+ * 2. Full equivalence (`vector.equals`).
9740
+ * 3. Logical match (`vector.match`, order-independent).
9741
+ * 4. Inclusion (`vector.includes`, provided vector is a subset).
9742
+ */
9743
+ matchInMap(map, vector, isAllowed) {
9744
+ const direct = map.get(vector);
9745
+ if (direct && isAllowed(direct)) {
9746
+ return direct;
9747
+ }
9748
+ for (const [registeredVector, component] of map.entries()) {
9749
+ if (isAllowed(component) && vector.equals(registeredVector)) {
9702
9750
  return component;
9703
9751
  }
9704
9752
  }
9705
- if (vectorToComponent) {
9706
- for (const [registeredVector, component] of vectorToComponent.entries()) {
9707
- if (isAllowed(component) && vector.equals(registeredVector)) {
9708
- return component;
9709
- }
9710
- }
9711
- for (const [registeredVector, component] of vectorToComponent.entries()) {
9712
- if (isAllowed(component) && vector.match(registeredVector)) {
9713
- return component;
9714
- }
9753
+ for (const [registeredVector, component] of map.entries()) {
9754
+ if (isAllowed(component) && vector.match(registeredVector)) {
9755
+ return component;
9715
9756
  }
9716
- for (const [registeredVector, component] of vectorToComponent.entries()) {
9717
- if (isAllowed(component) && vector.includes(registeredVector)) {
9718
- return component;
9719
- }
9757
+ }
9758
+ for (const [registeredVector, component] of map.entries()) {
9759
+ if (isAllowed(component) && vector.includes(registeredVector)) {
9760
+ return component;
9720
9761
  }
9721
9762
  }
9722
9763
  return void 0;
@@ -9875,7 +9916,8 @@ var AreSignals = (_a133 = class extends O {
9875
9916
  logger?.debug("Emitting signal for root node:", vector);
9876
9917
  await root.emit(callScope);
9877
9918
  callScope.destroy();
9878
- for (const signal of vector) {
9919
+ const dispatchedSignals = scope.resolveFlatAll(A_Signal);
9920
+ for (const signal of dispatchedSignals) {
9879
9921
  if (!signal) continue;
9880
9922
  const ctor = signal.constructor;
9881
9923
  const typedFeatureName = AreSignalFeatureKey(ctor);
@@ -9999,7 +10041,7 @@ var Are = (_a135 = class extends O {
9999
10041
  super(...arguments);
10000
10042
  this.props = {};
10001
10043
  }
10002
- static Condition(signals) {
10044
+ static Condition(signals, options) {
10003
10045
  return function(target) {
10004
10046
  const componentMeta = c.meta(target);
10005
10047
  const signalsMeta = c.meta(AreSignals);
@@ -10016,7 +10058,7 @@ var Are = (_a135 = class extends O {
10016
10058
  }
10017
10059
  if (vector) {
10018
10060
  componentMeta.vector = vector;
10019
- signalsMeta.registerCondition(target, vector);
10061
+ signalsMeta.registerCondition(target, vector, options?.root);
10020
10062
  }
10021
10063
  return target;
10022
10064
  };
@@ -10639,7 +10681,10 @@ var AreStore = (_a140 = class extends A_ExecutionContext {
10639
10681
  constructor(aseid) {
10640
10682
  super(aseid.toString());
10641
10683
  this.dependencies = /* @__PURE__ */ new Map();
10684
+ this.watcherPaths = /* @__PURE__ */ new Map();
10642
10685
  this._keys = /* @__PURE__ */ new Set();
10686
+ this._batchDepth = 0;
10687
+ this._pendingNotify = /* @__PURE__ */ new Set();
10643
10688
  }
10644
10689
  /**
10645
10690
  * Allows to define a pure function that will be executed in the context of the store, so it can access the store's data and methods, but it won't have access to the component's scope or other features. This can be useful for example for defining a function that will update the store's data based on some logic, without having access to the component's scope or other features, so we can keep the store's logic separate from the component's logic.
@@ -10669,7 +10714,10 @@ var AreStore = (_a140 = class extends A_ExecutionContext {
10669
10714
  get keys() {
10670
10715
  return this._keys;
10671
10716
  }
10672
- watch(instruction) {
10717
+ watch(instruction, reevaluate = false) {
10718
+ if (reevaluate) {
10719
+ this.pruneWatcher(instruction);
10720
+ }
10673
10721
  const watchers = this.context.get("watchers") || /* @__PURE__ */ new Set();
10674
10722
  watchers.add(instruction);
10675
10723
  this.context.set("watchers", watchers);
@@ -10698,13 +10746,7 @@ var AreStore = (_a140 = class extends A_ExecutionContext {
10698
10746
  super.set(firstPart, result ? result[firstPart] : primaryObject);
10699
10747
  }
10700
10748
  }
10701
- const normChanged = this.normalizePath(String(key));
10702
- const prefix = normChanged + ".";
10703
- for (const [normRegistered, instructions] of this.dependencies) {
10704
- if (normRegistered === normChanged || normRegistered.startsWith(prefix) || normChanged.startsWith(normRegistered + ".")) {
10705
- this.notify(instructions);
10706
- }
10707
- }
10749
+ this.dispatch(this.collectAffected(String(key)));
10708
10750
  }
10709
10751
  set(param1, param2) {
10710
10752
  if (typeof param1 === "string" && param2 !== void 0) {
@@ -10728,7 +10770,15 @@ var AreStore = (_a140 = class extends A_ExecutionContext {
10728
10770
  if (!this.dependencies.has(normAncestor)) {
10729
10771
  this.dependencies.set(normAncestor, /* @__PURE__ */ new Set());
10730
10772
  }
10731
- this.watchers.forEach((watcher) => this.dependencies.get(normAncestor).add(watcher));
10773
+ this.watchers.forEach((watcher) => {
10774
+ this.dependencies.get(normAncestor).add(watcher);
10775
+ let paths = this.watcherPaths.get(watcher);
10776
+ if (!paths) {
10777
+ paths = /* @__PURE__ */ new Set();
10778
+ this.watcherPaths.set(watcher, paths);
10779
+ }
10780
+ paths.add(normAncestor);
10781
+ });
10732
10782
  }
10733
10783
  }
10734
10784
  const primaryObject = super.get(firstPart);
@@ -10737,19 +10787,15 @@ var AreStore = (_a140 = class extends A_ExecutionContext {
10737
10787
  }
10738
10788
  setAsObject(values) {
10739
10789
  const entires = Object.entries(values);
10790
+ const affected = /* @__PURE__ */ new Set();
10740
10791
  for (const [key, value] of entires) {
10741
10792
  this._keys.add(key);
10742
10793
  super.set(key, value);
10743
- const normChanged = this.normalizePath(String(key));
10744
- const prefix = normChanged + ".";
10745
- for (const [normRegistered, instructions] of this.dependencies) {
10746
- if (normRegistered === normChanged || // exact
10747
- normRegistered.startsWith(prefix) || // descendant
10748
- normChanged.startsWith(normRegistered + ".")) {
10749
- this.notify(instructions);
10750
- }
10794
+ for (const watcher of this.collectAffected(String(key))) {
10795
+ affected.add(watcher);
10751
10796
  }
10752
10797
  }
10798
+ this.dispatch(affected);
10753
10799
  return this;
10754
10800
  }
10755
10801
  setAsKeyValue(key, value) {
@@ -10758,15 +10804,7 @@ var AreStore = (_a140 = class extends A_ExecutionContext {
10758
10804
  const primaryObject = super.get(firstPart);
10759
10805
  const result = A_UtilsHelper.setBypath(primaryObject, pathPart.join("."), value);
10760
10806
  super.set(firstPart, result ? result[firstPart] : value);
10761
- const normChanged = this.normalizePath(String(key));
10762
- const prefix = normChanged + ".";
10763
- for (const [normRegistered, instructions] of this.dependencies) {
10764
- if (normRegistered === normChanged || // exact
10765
- normRegistered.startsWith(prefix) || // descendant
10766
- normChanged.startsWith(normRegistered + ".")) {
10767
- this.notify(instructions);
10768
- }
10769
- }
10807
+ this.dispatch(this.collectAffected(String(key)));
10770
10808
  return this;
10771
10809
  }
10772
10810
  /**
@@ -10781,19 +10819,92 @@ var AreStore = (_a140 = class extends A_ExecutionContext {
10781
10819
  */
10782
10820
  forceUpdate(key) {
10783
10821
  if (key === void 0) {
10822
+ const all = /* @__PURE__ */ new Set();
10784
10823
  for (const instructions of this.dependencies.values()) {
10785
- this.notify(instructions);
10824
+ for (const watcher of instructions) all.add(watcher);
10786
10825
  }
10826
+ this.dispatch(all);
10787
10827
  return this;
10788
10828
  }
10789
- const normChanged = this.normalizePath(String(key));
10829
+ this.dispatch(this.collectAffected(String(key)));
10830
+ return this;
10831
+ }
10832
+ /**
10833
+ * Runs `fn` with notifications deferred: every watcher affected by writes
10834
+ * performed inside `fn` is collected and notified exactly once when the
10835
+ * outermost batch completes. Nested `batch()` calls are coalesced into the
10836
+ * outermost flush. Use this to wrap a burst of `set()`/`drop()` calls that
10837
+ * logically belong together so each dependent renders only once (#4).
10838
+ */
10839
+ batch(fn) {
10840
+ this._batchDepth++;
10841
+ try {
10842
+ fn();
10843
+ } finally {
10844
+ this._batchDepth--;
10845
+ if (this._batchDepth === 0 && this._pendingNotify.size > 0) {
10846
+ const pending = this._pendingNotify;
10847
+ this._pendingNotify = /* @__PURE__ */ new Set();
10848
+ this.notify(pending);
10849
+ }
10850
+ }
10851
+ return this;
10852
+ }
10853
+ /**
10854
+ * Builds the deduplicated set of watchers affected by a change to
10855
+ * `changedKey`, using the same exact/descendant/ancestor path matching as
10856
+ * `set()`. Returning a single union Set guarantees each watcher appears at
10857
+ * most once regardless of how many of its registered paths matched (#3).
10858
+ */
10859
+ collectAffected(changedKey) {
10860
+ const normChanged = this.normalizePath(String(changedKey));
10790
10861
  const prefix = normChanged + ".";
10862
+ const affected = /* @__PURE__ */ new Set();
10791
10863
  for (const [normRegistered, instructions] of this.dependencies) {
10792
- if (normRegistered === normChanged || normRegistered.startsWith(prefix) || normChanged.startsWith(normRegistered + ".")) {
10793
- this.notify(instructions);
10864
+ if (normRegistered === normChanged || // exact
10865
+ normRegistered.startsWith(prefix) || // descendant
10866
+ normChanged.startsWith(normRegistered + ".")) {
10867
+ for (const instruction of instructions) affected.add(instruction);
10794
10868
  }
10795
10869
  }
10796
- return this;
10870
+ return affected;
10871
+ }
10872
+ /**
10873
+ * Notifies the given watchers now, or defers them to the batch flush when a
10874
+ * `batch()` is active. The incoming set is already deduplicated by
10875
+ * {@link collectAffected}.
10876
+ */
10877
+ dispatch(affected) {
10878
+ if (affected.size === 0) return;
10879
+ if (this._batchDepth > 0) {
10880
+ for (const watcher of affected) this._pendingNotify.add(watcher);
10881
+ return;
10882
+ }
10883
+ this.notify(affected);
10884
+ }
10885
+ /**
10886
+ * Removes a watcher from every dependency set it holds on THIS store (and,
10887
+ * best-effort, on ancestor stores reached via parent delegation in
10888
+ * `get()`), clearing the matching reverse-index entries. Called at the
10889
+ * start of each tracking window so a re-evaluating watcher does not keep
10890
+ * stale subscriptions (#5).
10891
+ */
10892
+ pruneWatcher(instruction) {
10893
+ const paths = this.watcherPaths.get(instruction);
10894
+ if (paths) {
10895
+ for (const path of paths) {
10896
+ const set = this.dependencies.get(path);
10897
+ if (set) {
10898
+ set.delete(instruction);
10899
+ if (set.size === 0) this.dependencies.delete(path);
10900
+ }
10901
+ }
10902
+ this.watcherPaths.delete(instruction);
10903
+ }
10904
+ try {
10905
+ this.parent?.pruneWatcher(instruction);
10906
+ } catch {
10907
+ }
10797
10908
  }
10798
10909
  /**
10799
10910
  * Notifies instructions — immediately or deferred if inside a batch.
@@ -10807,13 +10918,18 @@ var AreStore = (_a140 = class extends A_ExecutionContext {
10807
10918
  }
10808
10919
  }
10809
10920
  /**
10810
- * Removes an instruction from all dependency sets.
10811
- * Called when an instruction is reverted/destroyed.
10921
+ * Removes an instruction from all dependency sets on this store, clearing
10922
+ * its reverse-index entry and any pending batched notification. Called when
10923
+ * an instruction is reverted/destroyed so a torn-down node's watcher can
10924
+ * never be re-notified by a later `set()` (#1).
10812
10925
  */
10813
10926
  unregister(instruction) {
10814
- for (const instructions of this.dependencies.values()) {
10927
+ for (const [path, instructions] of this.dependencies) {
10815
10928
  instructions.delete(instruction);
10929
+ if (instructions.size === 0) this.dependencies.delete(path);
10816
10930
  }
10931
+ this.watcherPaths.delete(instruction);
10932
+ this._pendingNotify.delete(instruction);
10817
10933
  }
10818
10934
  /**
10819
10935
  * Normalizes a path once — reused in both get and set.
@@ -10941,7 +11057,7 @@ var AreInterpreter = (_a141 = class extends O {
10941
11057
  }
10942
11058
  updateInstruction(instruction, interpreter, store, scope, feature, ...args) {
10943
11059
  try {
10944
- store.watch(instruction);
11060
+ store.watch(instruction, true);
10945
11061
  feature.chain(interpreter, instruction.name + AreInstructionFeatures.Update, scope);
10946
11062
  store.unwatch(instruction);
10947
11063
  } catch (error) {
@@ -10952,7 +11068,9 @@ var AreInterpreter = (_a141 = class extends O {
10952
11068
  revertInstruction(instruction, interpreter, store, scope, feature, ...args) {
10953
11069
  try {
10954
11070
  feature.chain(interpreter, instruction.name + AreInstructionFeatures.Revert, scope);
11071
+ store.unregister(instruction);
10955
11072
  } catch (error) {
11073
+ store.unregister(instruction);
10956
11074
  throw error;
10957
11075
  }
10958
11076
  }
@@ -12107,7 +12225,7 @@ AreRootCache = __decorateClass([
12107
12225
 
12108
12226
  // src/lib/AreRoot/AreRoot.component.ts
12109
12227
  var AreRoot = class extends Are {
12110
- async template(root, logger, signalsContext) {
12228
+ async template(root, logger, signalsContext, signalState) {
12111
12229
  const rootId = root.id;
12112
12230
  if (signalsContext && !signalsContext.hasRoot(rootId)) {
12113
12231
  if (!root.content?.trim()) {
@@ -12119,26 +12237,9 @@ var AreRoot = class extends Are {
12119
12237
  }
12120
12238
  return;
12121
12239
  }
12122
- const currentRoute = AreRoute2.default();
12123
- let componentName;
12124
- if (currentRoute) {
12125
- const initialVector = new A_SignalVector([currentRoute]);
12126
- let renderTarget = signalsContext?.findComponentByVector(rootId, initialVector);
12127
- if (!renderTarget) {
12128
- const signalsMeta = c.meta(AreSignals);
12129
- const pool = signalsContext?.getComponentById(rootId);
12130
- const metaTarget = signalsMeta?.findComponentByVector(
12131
- initialVector,
12132
- pool?.length ? pool : void 0
12133
- );
12134
- if (metaTarget && (!pool?.length || pool.includes(metaTarget))) {
12135
- renderTarget = metaTarget;
12136
- }
12137
- }
12138
- if (renderTarget?.name) {
12139
- componentName = P.toKebabCase(renderTarget.name);
12140
- }
12141
- }
12240
+ const initialVector = this.buildInitialVector(signalState);
12241
+ const renderTarget = this.matchComponent(rootId, initialVector, signalsContext);
12242
+ let componentName = renderTarget?.name ? P.toKebabCase(renderTarget.name) : void 0;
12142
12243
  if (!componentName) {
12143
12244
  if (root.content?.trim()) {
12144
12245
  return;
@@ -12165,18 +12266,7 @@ var AreRoot = class extends Are {
12165
12266
  if (signalsContext && !signalsContext.hasRoot(rootId)) {
12166
12267
  return;
12167
12268
  }
12168
- let renderTarget = signalsContext?.findComponentByVector(rootId, vector);
12169
- if (!renderTarget) {
12170
- const signalsMeta = c.meta(AreSignals);
12171
- const pool = signalsContext?.getComponentById(rootId);
12172
- const metaTarget = signalsMeta?.findComponentByVector(
12173
- vector,
12174
- pool?.length ? pool : void 0
12175
- );
12176
- if (metaTarget && (!pool?.length || pool.includes(metaTarget))) {
12177
- renderTarget = metaTarget;
12178
- }
12179
- }
12269
+ const renderTarget = this.matchComponent(rootId, vector, signalsContext);
12180
12270
  const def = signalsContext?.getDefault(rootId);
12181
12271
  const componentName = renderTarget?.name ? P.toKebabCase(renderTarget.name) : def?.name ? P.toKebabCase(def.name) : void 0;
12182
12272
  if (!componentName) {
@@ -12212,6 +12302,63 @@ var AreRoot = class extends Are {
12212
12302
  child.mount();
12213
12303
  }
12214
12304
  }
12305
+ /**
12306
+ * Resolves the component a vector should render for the given root, mirroring
12307
+ * the priority used everywhere in the routing system:
12308
+ * 1. Root-specific conditions registered on AreSignalsContext.
12309
+ * 2. The global AreSignalsMeta map, restricted to this outlet's pool.
12310
+ *
12311
+ * Passing the pool *into* the meta lookup is critical: without it, the first
12312
+ * globally matching component wins and may belong to a different outlet
12313
+ * (e.g. AisRequirementsPanel for the meta-outlet matching
12314
+ * AisEditorCursorScope) — the pool check would then reject it and the outlet
12315
+ * would fall back to its default, hiding a valid in-pool match (e.g.
12316
+ * AisDiagramTab matching AisSetPrimaryDisplay).
12317
+ *
12318
+ * Returns `undefined` when nothing matches — callers decide whether to use a
12319
+ * configured default, body content, or clear the outlet.
12320
+ */
12321
+ matchComponent(rootId, vector, signalsContext) {
12322
+ if (!vector) return void 0;
12323
+ let renderTarget = signalsContext?.findComponentByVector(rootId, vector);
12324
+ if (!renderTarget) {
12325
+ const signalsMeta = c.meta(AreSignals);
12326
+ const pool = signalsContext?.getComponentById(rootId);
12327
+ const metaTarget = signalsMeta?.findComponentByVector(
12328
+ vector,
12329
+ pool?.length ? pool : void 0,
12330
+ rootId
12331
+ );
12332
+ if (metaTarget && (!pool?.length || pool.includes(metaTarget))) {
12333
+ renderTarget = metaTarget;
12334
+ }
12335
+ }
12336
+ return renderTarget;
12337
+ }
12338
+ /**
12339
+ * Builds the vector used for the INITIAL render. It is seeded from the
12340
+ * accumulated signal state (every signal dispatched on the bus so far) so a
12341
+ * freshly-mounted outlet reflects the live application state immediately,
12342
+ * not just on the next signal tick. The current URL route is appended when
12343
+ * no AreRoute is already present in the state, so route-driven outlets still
12344
+ * resolve on the very first paint (before AreRouteWatcher has dispatched).
12345
+ */
12346
+ buildInitialVector(signalState) {
12347
+ const signals = [];
12348
+ if (signalState) {
12349
+ for (const signal of signalState.toVector()) {
12350
+ if (signal) signals.push(signal);
12351
+ }
12352
+ }
12353
+ if (!signals.some((signal) => signal instanceof AreRoute2)) {
12354
+ try {
12355
+ const currentRoute = AreRoute2.default();
12356
+ if (currentRoute) signals.push(currentRoute);
12357
+ } catch {
12358
+ }
12359
+ }
12360
+ return new A_SignalVector(signals);
12361
+ }
12215
12362
  /**
12216
12363
  * Detach a displayed child subtree from the outlet and stash it in the cache
12217
12364
  * for fast re-injection later. The subtree is unmounted (its scene plan is
@@ -12278,7 +12425,8 @@ __decorateClass([
12278
12425
  Are.Template,
12279
12426
  __decorateParam(0, It(te)),
12280
12427
  __decorateParam(1, It(A_Logger)),
12281
- __decorateParam(2, It(AreSignalsContext))
12428
+ __decorateParam(2, It(AreSignalsContext)),
12429
+ __decorateParam(3, It(A_SignalState))
12282
12430
  ], AreRoot.prototype, "template", 1);
12283
12431
  __decorateClass([
12284
12432
  Are.Signal,
@@ -12303,7 +12451,8 @@ var AreHTMLInstructions = {
12303
12451
  AddStyle: "_AreHTML_AddStyle",
12304
12452
  AddListener: "_AreHTML_AddListener",
12305
12453
  AddInterpolation: "_AreHTML_AddInterpolation",
12306
- AddComment: "_AreHTML_AddComment"
12454
+ AddComment: "_AreHTML_AddComment",
12455
+ HideElement: "_AreHTML_HideElement"
12307
12456
  };
12308
12457
 
12309
12458
  // src/lib/AreDirective/AreDirective.context.ts
@@ -12788,6 +12937,19 @@ var AreHTMLInterpreter = class extends AreInterpreter {
12788
12937
  console.log("Error removing attribute:", error);
12789
12938
  }
12790
12939
  }
12940
+ hideElement(mutation, context) {
12941
+ const element = context.getElementByInstruction(mutation.parent);
12942
+ if (!element || element.nodeType !== Node.ELEMENT_NODE) return;
12943
+ const el = element;
12944
+ mutation.cache = el.style.display;
12945
+ el.style.display = "none";
12946
+ }
12947
+ showElement(mutation, context) {
12948
+ const element = context.getElementByInstruction(mutation.parent);
12949
+ if (!element || element.nodeType !== Node.ELEMENT_NODE) return;
12950
+ const el = element;
12951
+ el.style.display = mutation.payload?.display ?? mutation.cache ?? "";
12952
+ }
12791
12953
  addEventListener(mutation, context, store, syntax, directiveContext, logger) {
12792
12954
  const element = context.getElementByInstruction(mutation.parent);
12793
12955
  if (!element) {
@@ -13041,6 +13203,22 @@ __decorateClass([
13041
13203
  __decorateParam(0, It(te)),
13042
13204
  __decorateParam(1, It(AreHTMLEngineContext))
13043
13205
  ], AreHTMLInterpreter.prototype, "removeAttribute", 1);
13206
+ __decorateClass([
13207
+ R4.Define({
13208
+ description: "Hide an element by setting inline display:none, caching its previous inline display value for restoration on revert."
13209
+ }),
13210
+ AreInterpreter.Apply(AreHTMLInstructions.HideElement),
13211
+ __decorateParam(0, It(te)),
13212
+ __decorateParam(1, It(AreHTMLEngineContext))
13213
+ ], AreHTMLInterpreter.prototype, "hideElement", 1);
13214
+ __decorateClass([
13215
+ R4.Define({
13216
+ description: "Restore an element hidden by a HideElement instruction back to its previous inline display value."
13217
+ }),
13218
+ AreInterpreter.Revert(AreHTMLInstructions.HideElement),
13219
+ __decorateParam(0, It(te)),
13220
+ __decorateParam(1, It(AreHTMLEngineContext))
13221
+ ], AreHTMLInterpreter.prototype, "showElement", 1);
13044
13222
  __decorateClass([
13045
13223
  R4.Define({
13046
13224
  description: "Add an event listener to an HTML element based on the provided mutation instruction."
@@ -13,6 +13,6 @@
13
13
  <body>
14
14
  <are-root id="app"><app-shell></app-shell></are-root>
15
15
 
16
- <script type="module" src="./mq7k53th-qiwy4x.js"></script>
16
+ <script type="module" src="./mqiwo23h-bhcolu.js"></script>
17
17
  </body>
18
18
  </html>