@adaas/are-html 0.0.2 → 0.0.4

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 (200) hide show
  1. package/README.md +4 -4
  2. package/dist/browser/index.d.mts +88 -5
  3. package/dist/browser/index.mjs +542 -176
  4. package/dist/browser/index.mjs.map +1 -1
  5. package/dist/node/attributes/AreBinding.attribute.js +17 -4
  6. package/dist/node/attributes/AreBinding.attribute.js.map +1 -1
  7. package/dist/node/attributes/AreBinding.attribute.mjs +10 -3
  8. package/dist/node/attributes/AreBinding.attribute.mjs.map +1 -1
  9. package/dist/node/attributes/AreDirective.attribute.js +17 -4
  10. package/dist/node/attributes/AreDirective.attribute.js.map +1 -1
  11. package/dist/node/attributes/AreDirective.attribute.mjs +10 -3
  12. package/dist/node/attributes/AreDirective.attribute.mjs.map +1 -1
  13. package/dist/node/attributes/AreEvent.attribute.js +17 -4
  14. package/dist/node/attributes/AreEvent.attribute.js.map +1 -1
  15. package/dist/node/attributes/AreEvent.attribute.mjs +10 -3
  16. package/dist/node/attributes/AreEvent.attribute.mjs.map +1 -1
  17. package/dist/node/attributes/AreStatic.attribute.js +17 -4
  18. package/dist/node/attributes/AreStatic.attribute.js.map +1 -1
  19. package/dist/node/attributes/AreStatic.attribute.mjs +10 -3
  20. package/dist/node/attributes/AreStatic.attribute.mjs.map +1 -1
  21. package/dist/node/directives/AreDirectiveFor.directive.d.mts +8 -0
  22. package/dist/node/directives/AreDirectiveFor.directive.d.ts +8 -0
  23. package/dist/node/directives/AreDirectiveFor.directive.js +78 -33
  24. package/dist/node/directives/AreDirectiveFor.directive.js.map +1 -1
  25. package/dist/node/directives/AreDirectiveFor.directive.mjs +78 -33
  26. package/dist/node/directives/AreDirectiveFor.directive.mjs.map +1 -1
  27. package/dist/node/directives/AreDirectiveIf.directive.d.mts +18 -0
  28. package/dist/node/directives/AreDirectiveIf.directive.d.ts +18 -0
  29. package/dist/node/directives/AreDirectiveIf.directive.js +10 -3
  30. package/dist/node/directives/AreDirectiveIf.directive.js.map +1 -1
  31. package/dist/node/directives/AreDirectiveIf.directive.mjs +10 -3
  32. package/dist/node/directives/AreDirectiveIf.directive.mjs.map +1 -1
  33. package/dist/node/engine/AreHTML.compiler.d.mts +2 -2
  34. package/dist/node/engine/AreHTML.compiler.d.ts +2 -2
  35. package/dist/node/engine/AreHTML.compiler.js +57 -29
  36. package/dist/node/engine/AreHTML.compiler.js.map +1 -1
  37. package/dist/node/engine/AreHTML.compiler.mjs +58 -30
  38. package/dist/node/engine/AreHTML.compiler.mjs.map +1 -1
  39. package/dist/node/engine/AreHTML.constants.d.mts +53 -1
  40. package/dist/node/engine/AreHTML.constants.d.ts +53 -1
  41. package/dist/node/engine/AreHTML.constants.js +100 -0
  42. package/dist/node/engine/AreHTML.constants.js.map +1 -1
  43. package/dist/node/engine/AreHTML.constants.mjs +93 -0
  44. package/dist/node/engine/AreHTML.constants.mjs.map +1 -1
  45. package/dist/node/engine/AreHTML.context.d.mts +6 -2
  46. package/dist/node/engine/AreHTML.context.d.ts +6 -2
  47. package/dist/node/engine/AreHTML.context.js +42 -7
  48. package/dist/node/engine/AreHTML.context.js.map +1 -1
  49. package/dist/node/engine/AreHTML.context.mjs +35 -6
  50. package/dist/node/engine/AreHTML.context.mjs.map +1 -1
  51. package/dist/node/engine/AreHTML.engine.js +10 -7
  52. package/dist/node/engine/AreHTML.engine.js.map +1 -1
  53. package/dist/node/engine/AreHTML.engine.mjs +10 -7
  54. package/dist/node/engine/AreHTML.engine.mjs.map +1 -1
  55. package/dist/node/engine/AreHTML.interpreter.js +155 -43
  56. package/dist/node/engine/AreHTML.interpreter.js.map +1 -1
  57. package/dist/node/engine/AreHTML.interpreter.mjs +155 -43
  58. package/dist/node/engine/AreHTML.interpreter.mjs.map +1 -1
  59. package/dist/node/engine/AreHTML.lifecycle.js +17 -12
  60. package/dist/node/engine/AreHTML.lifecycle.js.map +1 -1
  61. package/dist/node/engine/AreHTML.lifecycle.mjs +9 -2
  62. package/dist/node/engine/AreHTML.lifecycle.mjs.map +1 -1
  63. package/dist/node/engine/AreHTML.tokenizer.js +14 -9
  64. package/dist/node/engine/AreHTML.tokenizer.js.map +1 -1
  65. package/dist/node/engine/AreHTML.tokenizer.mjs +10 -3
  66. package/dist/node/engine/AreHTML.tokenizer.mjs.map +1 -1
  67. package/dist/node/engine/AreHTML.transformer.js +13 -8
  68. package/dist/node/engine/AreHTML.transformer.js.map +1 -1
  69. package/dist/node/engine/AreHTML.transformer.mjs +9 -2
  70. package/dist/node/engine/AreHTML.transformer.mjs.map +1 -1
  71. package/dist/node/index.d.mts +2 -1
  72. package/dist/node/index.d.ts +2 -1
  73. package/dist/node/index.js +3 -3
  74. package/dist/node/index.mjs +1 -1
  75. package/dist/node/instructions/AddAttribute.instruction.js +3 -4
  76. package/dist/node/instructions/AddAttribute.instruction.js.map +1 -1
  77. package/dist/node/instructions/AddAttribute.instruction.mjs +3 -4
  78. package/dist/node/instructions/AddAttribute.instruction.mjs.map +1 -1
  79. package/dist/node/instructions/AddComment.instruction.js +3 -4
  80. package/dist/node/instructions/AddComment.instruction.js.map +1 -1
  81. package/dist/node/instructions/AddComment.instruction.mjs +3 -4
  82. package/dist/node/instructions/AddComment.instruction.mjs.map +1 -1
  83. package/dist/node/instructions/AddElement.instruction.js +3 -4
  84. package/dist/node/instructions/AddElement.instruction.js.map +1 -1
  85. package/dist/node/instructions/AddElement.instruction.mjs +3 -4
  86. package/dist/node/instructions/AddElement.instruction.mjs.map +1 -1
  87. package/dist/node/instructions/AddInterpolation.instruction.js +3 -4
  88. package/dist/node/instructions/AddInterpolation.instruction.js.map +1 -1
  89. package/dist/node/instructions/AddInterpolation.instruction.mjs +3 -4
  90. package/dist/node/instructions/AddInterpolation.instruction.mjs.map +1 -1
  91. package/dist/node/instructions/AddListener.instruction.js +3 -4
  92. package/dist/node/instructions/AddListener.instruction.js.map +1 -1
  93. package/dist/node/instructions/AddListener.instruction.mjs +3 -4
  94. package/dist/node/instructions/AddListener.instruction.mjs.map +1 -1
  95. package/dist/node/instructions/AddStyle.instruction.js +3 -4
  96. package/dist/node/instructions/AddStyle.instruction.js.map +1 -1
  97. package/dist/node/instructions/AddStyle.instruction.mjs +3 -4
  98. package/dist/node/instructions/AddStyle.instruction.mjs.map +1 -1
  99. package/dist/node/instructions/AddText.instruction.js +3 -4
  100. package/dist/node/instructions/AddText.instruction.js.map +1 -1
  101. package/dist/node/instructions/AddText.instruction.mjs +3 -4
  102. package/dist/node/instructions/AddText.instruction.mjs.map +1 -1
  103. package/dist/node/lib/AreDirective/AreDirective.component.js +5 -0
  104. package/dist/node/lib/AreDirective/AreDirective.component.js.map +1 -1
  105. package/dist/node/lib/AreDirective/AreDirective.component.mjs +5 -0
  106. package/dist/node/lib/AreDirective/AreDirective.component.mjs.map +1 -1
  107. package/dist/node/lib/AreHTMLAttribute/AreHTML.attribute.js +17 -4
  108. package/dist/node/lib/AreHTMLAttribute/AreHTML.attribute.js.map +1 -1
  109. package/dist/node/lib/AreHTMLAttribute/AreHTML.attribute.mjs +10 -3
  110. package/dist/node/lib/AreHTMLAttribute/AreHTML.attribute.mjs.map +1 -1
  111. package/dist/node/lib/AreHTMLNode/AreHTMLNode.js +3 -4
  112. package/dist/node/lib/AreHTMLNode/AreHTMLNode.js.map +1 -1
  113. package/dist/node/lib/AreHTMLNode/AreHTMLNode.mjs +3 -4
  114. package/dist/node/lib/AreHTMLNode/AreHTMLNode.mjs.map +1 -1
  115. package/dist/node/lib/AreRoot/AreRoot.component.js +3 -4
  116. package/dist/node/lib/AreRoot/AreRoot.component.js.map +1 -1
  117. package/dist/node/lib/AreRoot/AreRoot.component.mjs +3 -4
  118. package/dist/node/lib/AreRoot/AreRoot.component.mjs.map +1 -1
  119. package/dist/node/lib/{AreWatcher/AreWatcher.component.d.mts → AreRouteWatcher/AreRouteWatcher.component.d.mts} +2 -2
  120. package/dist/node/lib/{AreWatcher/AreWatcher.component.d.ts → AreRouteWatcher/AreRouteWatcher.component.d.ts} +2 -2
  121. package/dist/node/lib/{AreWatcher/AreWatcher.component.js → AreRouteWatcher/AreRouteWatcher.component.js} +9 -10
  122. package/dist/node/lib/AreRouteWatcher/AreRouteWatcher.component.js.map +1 -0
  123. package/dist/node/lib/{AreWatcher/AreWatcher.component.mjs → AreRouteWatcher/AreRouteWatcher.component.mjs} +10 -11
  124. package/dist/node/lib/AreRouteWatcher/AreRouteWatcher.component.mjs.map +1 -0
  125. package/dist/node/lib/AreStyle/AreStyle.context.js +17 -4
  126. package/dist/node/lib/AreStyle/AreStyle.context.js.map +1 -1
  127. package/dist/node/lib/AreStyle/AreStyle.context.mjs +10 -3
  128. package/dist/node/lib/AreStyle/AreStyle.context.mjs.map +1 -1
  129. package/dist/node/nodes/AreComment.js +17 -4
  130. package/dist/node/nodes/AreComment.js.map +1 -1
  131. package/dist/node/nodes/AreComment.mjs +10 -3
  132. package/dist/node/nodes/AreComment.mjs.map +1 -1
  133. package/dist/node/nodes/AreComponent.js +3 -4
  134. package/dist/node/nodes/AreComponent.js.map +1 -1
  135. package/dist/node/nodes/AreComponent.mjs +3 -4
  136. package/dist/node/nodes/AreComponent.mjs.map +1 -1
  137. package/dist/node/nodes/AreInterpolation.js +17 -4
  138. package/dist/node/nodes/AreInterpolation.js.map +1 -1
  139. package/dist/node/nodes/AreInterpolation.mjs +10 -3
  140. package/dist/node/nodes/AreInterpolation.mjs.map +1 -1
  141. package/dist/node/nodes/AreRoot.js +3 -4
  142. package/dist/node/nodes/AreRoot.js.map +1 -1
  143. package/dist/node/nodes/AreRoot.mjs +3 -4
  144. package/dist/node/nodes/AreRoot.mjs.map +1 -1
  145. package/dist/node/nodes/AreText.js +17 -4
  146. package/dist/node/nodes/AreText.js.map +1 -1
  147. package/dist/node/nodes/AreText.mjs +10 -3
  148. package/dist/node/nodes/AreText.mjs.map +1 -1
  149. package/dist/node/signals/AreRoute.signal.js +18 -5
  150. package/dist/node/signals/AreRoute.signal.js.map +1 -1
  151. package/dist/node/signals/AreRoute.signal.mjs +10 -3
  152. package/dist/node/signals/AreRoute.signal.mjs.map +1 -1
  153. package/docs/SYNTAX.md +714 -0
  154. package/docs/arehtml.monaco.json +235 -0
  155. package/docs/arehtml.monaco.ts +119 -0
  156. package/examples/dashboard/dist/index.html +1 -1
  157. package/examples/dashboard/dist/mpioi5ab-8c3oa9.js +13674 -0
  158. package/examples/jumpstart/dist/index.html +1 -1
  159. package/examples/{dashboard/dist/mnzfypsd-6zjt7w.js → jumpstart/dist/mor90p6y-0plg7g.js} +1869 -1926
  160. package/examples/jumpstart/dist/{mnpl1g4i-nobz9g.js → mor90p7p-1898bz.js} +2797 -2282
  161. package/examples/jumpstart/src/components/List.component.ts +14 -13
  162. package/examples/jumpstart/src/concept.ts +5 -4
  163. package/jest.config.ts +1 -1
  164. package/package.json +10 -6
  165. package/src/attributes/AreBinding.attribute.ts +5 -0
  166. package/src/attributes/AreDirective.attribute.ts +5 -0
  167. package/src/attributes/AreEvent.attribute.ts +5 -0
  168. package/src/attributes/AreStatic.attribute.ts +5 -0
  169. package/src/directives/AreDirectiveFor.directive.ts +97 -60
  170. package/src/directives/AreDirectiveIf.directive.ts +37 -15
  171. package/src/engine/AreHTML.compiler.ts +64 -36
  172. package/src/engine/AreHTML.constants.ts +144 -0
  173. package/src/engine/AreHTML.context.ts +33 -4
  174. package/src/engine/AreHTML.engine.ts +12 -7
  175. package/src/engine/AreHTML.interpreter.ts +195 -68
  176. package/src/engine/AreHTML.lifecycle.ts +5 -0
  177. package/src/engine/AreHTML.tokenizer.ts +6 -1
  178. package/src/engine/AreHTML.transformer.ts +5 -0
  179. package/src/index.ts +2 -2
  180. package/src/instructions/AddAttribute.instruction.ts +3 -4
  181. package/src/instructions/AddComment.instruction.ts +3 -4
  182. package/src/instructions/AddElement.instruction.ts +3 -4
  183. package/src/instructions/AddInterpolation.instruction.ts +3 -4
  184. package/src/instructions/AddListener.instruction.ts +3 -4
  185. package/src/instructions/AddStyle.instruction.ts +3 -4
  186. package/src/instructions/AddText.instruction.ts +3 -4
  187. package/src/lib/AreDirective/AreDirective.component.ts +5 -0
  188. package/src/lib/AreHTMLAttribute/AreHTML.attribute.ts +5 -0
  189. package/src/lib/AreHTMLNode/AreHTMLNode.ts +3 -4
  190. package/src/lib/AreRoot/AreRoot.component.ts +3 -4
  191. package/src/lib/{AreWatcher/AreWatcher.component.ts → AreRouteWatcher/AreRouteWatcher.component.ts} +5 -6
  192. package/src/lib/AreStyle/AreStyle.context.ts +5 -0
  193. package/src/nodes/AreComment.ts +5 -0
  194. package/src/nodes/AreComponent.ts +3 -4
  195. package/src/nodes/AreInterpolation.ts +5 -0
  196. package/src/nodes/AreRoot.ts +3 -4
  197. package/src/nodes/AreText.ts +5 -0
  198. package/src/signals/AreRoute.signal.ts +5 -0
  199. package/dist/node/lib/AreWatcher/AreWatcher.component.js.map +0 -1
  200. package/dist/node/lib/AreWatcher/AreWatcher.component.mjs.map +0 -1
@@ -8998,7 +8998,7 @@ AreEngine = __decorateClass3([
8998
8998
  })
8999
8999
  ], AreEngine);
9000
9000
  var _a109;
9001
- var AreWatcher = (_a109 = class extends v {
9001
+ var AreRouteWatcher = (_a109 = class extends v {
9002
9002
  /**
9003
9003
  * Initialize the watcher. This method is called once when the watcher is first created. Use this to set up any necessary state or start observing changes.
9004
9004
  */
@@ -9011,17 +9011,17 @@ var AreWatcher = (_a109 = class extends v {
9011
9011
  }
9012
9012
  destroy() {
9013
9013
  }
9014
- }, __name(_a109, "AreWatcher"), _a109);
9014
+ }, __name(_a109, "AreRouteWatcher"), _a109);
9015
9015
  __decorateClass3([
9016
9016
  Ce.Stop()
9017
- ], AreWatcher.prototype, "destroy", 1);
9018
- AreWatcher = __decorateClass3([
9017
+ ], AreRouteWatcher.prototype, "destroy", 1);
9018
+ AreRouteWatcher = __decorateClass3([
9019
9019
  c2.Component({
9020
9020
  namespace: "A-ARE",
9021
- name: "AreWatcher",
9022
- description: "AreWatcher is a component that observes changes and produces A_Signals Depending on the actual handlers"
9021
+ name: "AreRouteWatcher",
9022
+ description: "AreRouteWatcher is a component that observes changes and produces A_Signals Depending on the actual handlers"
9023
9023
  })
9024
- ], AreWatcher);
9024
+ ], AreRouteWatcher);
9025
9025
  var _a110;
9026
9026
  var _a111;
9027
9027
  var AreContainer = (_a111 = class extends A_Service {
@@ -9060,7 +9060,7 @@ __decorateClass3([
9060
9060
  __decorateParam3(1, ke(AreContext)),
9061
9061
  __decorateParam3(2, F.All()),
9062
9062
  __decorateParam3(2, F.Flat()),
9063
- __decorateParam3(2, ke(AreWatcher)),
9063
+ __decorateParam3(2, ke(AreRouteWatcher)),
9064
9064
  __decorateParam3(3, ke(A_Logger))
9065
9065
  ], AreContainer.prototype, _a110, 1);
9066
9066
  var _a112;
@@ -9104,1105 +9104,960 @@ var AreRoute = (_a117 = class extends AreSignal {
9104
9104
  }
9105
9105
  }, __name(_a117, "_AreRoute"), _a117);
9106
9106
 
9107
- // examples/dashboard/src/components/DashboardApp.component.ts
9108
- var _DashboardApp = class _DashboardApp extends Are {
9109
- template(node) {
9110
- node.setContent(`
9111
- <div class="dashboard">
9112
- <dashboard-header></dashboard-header>
9113
- <dashboard-sidebar></dashboard-sidebar>
9114
- <dashboard-main></dashboard-main>
9115
- </div>
9116
- `);
9117
- }
9118
- data(store) {
9119
- store.set({
9120
- appName: "ARE Dashboard"
9121
- });
9122
- }
9123
- };
9124
- __name(_DashboardApp, "DashboardApp");
9125
- __decorateClass([
9126
- Are.Template,
9127
- __decorateParam(0, ke(G))
9128
- ], _DashboardApp.prototype, "template", 1);
9129
- __decorateClass([
9130
- Are.Data,
9131
- __decorateParam(0, ke(AreStore))
9132
- ], _DashboardApp.prototype, "data", 1);
9133
- var DashboardApp = _DashboardApp;
9134
-
9135
- // examples/dashboard/src/components/DashboardHeader.component.ts
9136
- var _DashboardHeader = class _DashboardHeader extends Are {
9137
- template(node) {
9138
- node.setContent(`
9139
- <header class="header">
9140
- <dashboard-logo></dashboard-logo>
9141
- <dashboard-nav></dashboard-nav>
9142
- <div class="header-actions">
9143
- <div class="header-search">
9144
- <span class="header-search-icon">\u2315</span>
9145
- <span class="header-search-text">{{searchPlaceholder}}</span>
9146
- </div>
9147
- <div class="header-notification">
9148
- \u{1F514}
9149
- <span class="header-notification-badge"></span>
9150
- </div>
9151
- </div>
9152
- </header>
9153
- `);
9154
- }
9155
- data(store) {
9156
- store.set({
9157
- title: "Dashboard",
9158
- searchPlaceholder: "Search\u2026"
9159
- });
9107
+ // examples/jumpstart/src/components/A-Btn.component.ts
9108
+ var _ABtn = class _ABtn extends Are {
9109
+ constructor() {
9110
+ super(...arguments);
9111
+ this.props = {
9112
+ name: {
9113
+ type: "string",
9114
+ default: "A_Button Element"
9115
+ }
9116
+ };
9160
9117
  }
9161
- };
9162
- __name(_DashboardHeader, "DashboardHeader");
9163
- __decorateClass([
9164
- Are.Template,
9165
- __decorateParam(0, ke(G))
9166
- ], _DashboardHeader.prototype, "template", 1);
9167
- __decorateClass([
9168
- Are.Data,
9169
- __decorateParam(0, ke(AreStore))
9170
- ], _DashboardHeader.prototype, "data", 1);
9171
- var DashboardHeader = _DashboardHeader;
9172
-
9173
- // examples/dashboard/src/components/DashboardLogo.component.ts
9174
- var _DashboardLogo = class _DashboardLogo extends Are {
9175
- async template(node) {
9118
+ async template(node, store) {
9176
9119
  node.setContent(`
9177
- <div class="logo">
9178
- <div class="logo-icon">A</div>
9179
- <span class="logo-text">{{brandName}}</span>
9180
- </div>
9120
+ <button class="a-btn" @click="handleClick"> Make it: {{name}} {{number}}</button>
9181
9121
  `);
9182
9122
  }
9183
- async data(store) {
9184
- store.set({
9185
- brandName: "ARE Platform"
9186
- });
9123
+ filter(test) {
9124
+ console.log("test", test);
9187
9125
  }
9188
- };
9189
- __name(_DashboardLogo, "DashboardLogo");
9190
- __decorateClass([
9191
- Are.Template,
9192
- __decorateParam(0, ke(G))
9193
- ], _DashboardLogo.prototype, "template", 1);
9194
- __decorateClass([
9195
- Are.Data,
9196
- __decorateParam(0, ke(AreStore))
9197
- ], _DashboardLogo.prototype, "data", 1);
9198
- var DashboardLogo = _DashboardLogo;
9199
-
9200
- // examples/dashboard/src/components/DashboardNav.component.ts
9201
- var _DashboardNav = class _DashboardNav extends Are {
9202
- template(node) {
9203
- node.setContent(`
9204
- <nav class="nav">
9205
- <dashboard-nav-item></dashboard-nav-item>
9206
- </nav>
9207
- `);
9126
+ async styles(node) {
9208
9127
  }
9209
- data(store) {
9128
+ async data(node, store) {
9210
9129
  store.set({
9211
- section: "navigation"
9130
+ name: "A_Button Element",
9131
+ showInput: false,
9132
+ bgColor: "#007BFF",
9133
+ btn2: "Button 2",
9134
+ showInput2: false,
9135
+ number: 0
9212
9136
  });
9213
9137
  }
9214
- };
9215
- __name(_DashboardNav, "DashboardNav");
9216
- __decorateClass([
9217
- Are.Template,
9218
- __decorateParam(0, ke(G))
9219
- ], _DashboardNav.prototype, "template", 1);
9220
- __decorateClass([
9221
- Are.Data,
9222
- __decorateParam(0, ke(AreStore))
9223
- ], _DashboardNav.prototype, "data", 1);
9224
- var DashboardNav = _DashboardNav;
9225
-
9226
- // examples/dashboard/src/components/DashboardNavItem.component.ts
9227
- var _DashboardNavItem = class _DashboardNavItem extends Are {
9228
- template(node) {
9229
- node.setContent(`
9230
- <span class="nav-item nav-item-active">{{label1}}</span>
9231
- <span class="nav-item">{{label2}}</span>
9232
- <span class="nav-item">{{label3}}</span>
9233
- <span class="nav-item">{{label4}}</span>
9234
- `);
9235
- }
9236
- data(store) {
9237
- store.set({
9238
- label1: "Overview",
9239
- label2: "Analytics",
9240
- label3: "Reports",
9241
- label4: "Settings"
9242
- });
9138
+ async handleClick(scope, node, store, logger, event, scene) {
9139
+ store.set("number", Math.floor(Math.random() * 1e3));
9140
+ store.set("name", `Clicked! `);
9141
+ console.log("Changing ShowInput from ", store.get("showInput"));
9142
+ store.set("showInput", !store.get("showInput"));
9143
+ console.log("Changing ShowInput to ", store.get("showInput"), store);
9144
+ store.set("bgColor", "#ff5733");
9145
+ console.log("event data:", event);
9146
+ await node.update();
9147
+ }
9148
+ async handleClick2(scope, node, store, logger, event, scene) {
9149
+ store.set("btn2", `Button 2 Clicked! `);
9150
+ store.set("showInput2", !store.get("showInput2"));
9151
+ console.log("event data:", event);
9152
+ await node.update();
9243
9153
  }
9244
9154
  };
9245
- __name(_DashboardNavItem, "DashboardNavItem");
9155
+ __name(_ABtn, "ABtn");
9246
9156
  __decorateClass([
9247
9157
  Are.Template,
9248
- __decorateParam(0, ke(G))
9249
- ], _DashboardNavItem.prototype, "template", 1);
9158
+ __decorateParam(0, ke(G)),
9159
+ __decorateParam(1, ke(AreStore))
9160
+ ], _ABtn.prototype, "template", 1);
9250
9161
  __decorateClass([
9251
- Are.Data,
9252
- __decorateParam(0, ke(AreStore))
9253
- ], _DashboardNavItem.prototype, "data", 1);
9254
- var DashboardNavItem = _DashboardNavItem;
9255
-
9256
- // examples/dashboard/src/components/DashboardSidebar.component.ts
9257
- var _DashboardSidebar = class _DashboardSidebar extends Are {
9258
- template(node) {
9259
- node.setContent(`
9260
- <aside class="sidebar">
9261
- {{section}}
9262
- <dashboard-user-card></dashboard-user-card>
9263
- <dashboard-menu></dashboard-menu>
9264
- </aside>
9265
- `);
9266
- }
9267
- data(store) {
9268
- store.set({
9269
- section: "sidebar"
9270
- });
9271
- }
9272
- async menuItemClicked(node, event, store) {
9273
- console.log("Sidebar clicked!", event.get("section"));
9274
- store.set("section", event.get("section"));
9275
- }
9276
- };
9277
- __name(_DashboardSidebar, "DashboardSidebar");
9162
+ AreStore.Function
9163
+ ], _ABtn.prototype, "filter", 1);
9278
9164
  __decorateClass([
9279
- Are.Template,
9165
+ Are.Styles,
9280
9166
  __decorateParam(0, ke(G))
9281
- ], _DashboardSidebar.prototype, "template", 1);
9167
+ ], _ABtn.prototype, "styles", 1);
9282
9168
  __decorateClass([
9283
9169
  Are.Data,
9284
- __decorateParam(0, ke(AreStore))
9285
- ], _DashboardSidebar.prototype, "data", 1);
9286
- __decorateClass([
9287
- Are.EventHandler,
9288
9170
  __decorateParam(0, ke(G)),
9289
- __decorateParam(1, ke(AreEvent)),
9290
- __decorateParam(2, ke(AreStore))
9291
- ], _DashboardSidebar.prototype, "menuItemClicked", 1);
9292
- var DashboardSidebar = _DashboardSidebar;
9293
-
9294
- // examples/dashboard/src/components/DashboardUserCard.component.ts
9295
- var _DashboardUserCard = class _DashboardUserCard extends Are {
9296
- template(node) {
9297
- node.setContent(`
9298
- <div class="user-card">
9299
- <div class="user-avatar">{{initials}}</div>
9300
- <div class="user-info">
9301
- <div class="user-name">{{fullName}}</div>
9302
- <div class="user-role">{{role}}</div>
9303
- </div>
9304
- <div class="user-status">
9305
- <span class="user-status-dot"></span>
9306
- {{status}}
9307
- </div>
9308
- </div>
9309
- `);
9310
- }
9311
- data(store) {
9312
- store.set({
9313
- initials: "JD",
9314
- fullName: "John Doe",
9315
- role: "Administrator",
9316
- status: "Online"
9317
- });
9318
- }
9319
- };
9320
- __name(_DashboardUserCard, "DashboardUserCard");
9171
+ __decorateParam(1, ke(AreStore))
9172
+ ], _ABtn.prototype, "data", 1);
9321
9173
  __decorateClass([
9322
- Are.Template,
9323
- __decorateParam(0, ke(G))
9324
- ], _DashboardUserCard.prototype, "template", 1);
9174
+ Are.EventHandler,
9175
+ __decorateParam(0, ke(D)),
9176
+ __decorateParam(1, ke(G)),
9177
+ __decorateParam(2, ke(AreStore)),
9178
+ __decorateParam(3, ke(A_Logger)),
9179
+ __decorateParam(4, ke(AreEvent)),
9180
+ __decorateParam(5, ke(AreScene))
9181
+ ], _ABtn.prototype, "handleClick", 1);
9325
9182
  __decorateClass([
9326
- Are.Data,
9327
- __decorateParam(0, ke(AreStore))
9328
- ], _DashboardUserCard.prototype, "data", 1);
9329
- var DashboardUserCard = _DashboardUserCard;
9183
+ Are.EventHandler,
9184
+ __decorateParam(0, ke(D)),
9185
+ __decorateParam(1, ke(G)),
9186
+ __decorateParam(2, ke(AreStore)),
9187
+ __decorateParam(3, ke(A_Logger)),
9188
+ __decorateParam(4, ke(AreEvent)),
9189
+ __decorateParam(5, ke(AreScene))
9190
+ ], _ABtn.prototype, "handleClick2", 1);
9191
+ var ABtn = _ABtn;
9330
9192
 
9331
- // examples/dashboard/src/components/DashboardMenu.component.ts
9332
- var _DashboardMenu = class _DashboardMenu extends Are {
9333
- template(node) {
9334
- node.setContent(`
9335
- <div class="menu-section">Main</div>
9336
- <ul class="menu">
9337
- <li @click="$handleClick('Dashboard')" :class="active==='Dashboard' ? 'menu-item-active' : ''" class="menu-item "><span class="menu-icon">\u229E</span> <span class="menu-text">{{item1}}</span></li>
9338
- <li @click="$handleClick('Users')" :class="active==='Users' ? 'menu-item-active' : ''" class="menu-item"><span class="menu-icon">\u22A1</span> <span class="menu-text">{{item2}}</span> <span class="menu-badge">{{usersBadge}}</span></li>
9339
- <li @click="$handleClick('Products')" :class="active==='Products' ? 'menu-item-active' : ''" class="menu-item"><span class="menu-icon">\u22A0</span> <span class="menu-text">{{item3}}</span></li>
9340
- <li @click="$handleClick('Orders')" :class="active==='Orders' ? 'menu-item-active' : ''" class="menu-item"><span class="menu-icon">\u229F</span> <span class="menu-text">{{item4}}</span></li>
9341
- </ul>
9342
- <div class="menu-section">System</div>
9343
- <ul class="menu">
9344
- <li
9345
- $for="item in items" @click="$handleClick(item.name)"
9346
- :class="active===item.name ? 'menu-item-active' : ''"
9347
- class="menu-item">
9348
- <span class="menu-icon">\u2299</span>
9349
- <span class="menu-text">{{item.name}}</span>
9350
- <span $if="!item.badge" class="menu-badge">{{item.badge}}</span>
9351
- {{item.badge}}
9352
- </li>
9353
- </ul>
9354
- `);
9193
+ // src/lib/AreRoot/AreRoot.component.ts
9194
+ var AreRoot = class extends Are {
9195
+ constructor() {
9196
+ super(...arguments);
9197
+ this.props = {
9198
+ default: {
9199
+ type: "string",
9200
+ default: ""
9201
+ }
9202
+ };
9355
9203
  }
9356
- data(store) {
9357
- store.set({
9358
- active: "Dashboard",
9359
- item1: "Dashboard",
9360
- item2: "Users",
9361
- item3: "Products",
9362
- item4: "Orders",
9363
- item5: "Messages",
9364
- item6: "Settings",
9365
- usersBadge: "24",
9366
- msgBadge: "3",
9367
- items: [
9368
- { name: "Messages", badge: "3" },
9369
- { name: "Settings", badge: "0" }
9370
- ]
9371
- });
9204
+ async template(root, logger, signalsContext) {
9205
+ const rootId = root.id;
9206
+ if (signalsContext && !signalsContext.hasRoot(rootId)) {
9207
+ return;
9208
+ }
9209
+ const currentRoute = AreRoute.default();
9210
+ let componentName;
9211
+ if (currentRoute) {
9212
+ const initialVector = new A_SignalVector([currentRoute]);
9213
+ let renderTarget = signalsContext?.findComponentByVector(rootId, initialVector);
9214
+ if (!renderTarget) {
9215
+ const signalsMeta = c.meta(AreSignals);
9216
+ renderTarget = signalsMeta?.findComponentByVector(initialVector);
9217
+ }
9218
+ if (renderTarget?.name) {
9219
+ componentName = h.toKebabCase(renderTarget.name);
9220
+ }
9221
+ }
9222
+ if (!componentName) {
9223
+ const defaultAttr = root.attributes.find((attr) => attr.name === "default");
9224
+ componentName = defaultAttr?.content;
9225
+ }
9226
+ if (!componentName) {
9227
+ logger.warning('AreRoot: No component found for initial render. Please ensure a route condition or "default" attribute is set.');
9228
+ return;
9229
+ }
9230
+ root.setContent(`<${componentName}></${componentName}>`);
9372
9231
  }
9373
- async handleClick(node, event, context, store, logger) {
9374
- try {
9375
- console.log("Menu item clicked!", event.get("args"), store);
9376
- const item = event.get("args")?.[0] || "Dashboard";
9377
- store.set("active", item);
9378
- context.endPerformance("Click");
9379
- logger.info(`Menu item clicked: ${item}`, ...context.performance);
9380
- } catch (error) {
9381
- logger.error(error);
9232
+ async onSignal(root, vector, store, logger, signalsContext) {
9233
+ console.log("Received signal vector in AreRoot:", root, vector);
9234
+ const rootId = root.id;
9235
+ if (signalsContext && !signalsContext.hasRoot(rootId)) {
9236
+ return;
9237
+ }
9238
+ let renderTarget = signalsContext?.findComponentByVector(rootId, vector);
9239
+ if (!renderTarget) {
9240
+ const signalsMeta = c.meta(AreSignals);
9241
+ renderTarget = signalsMeta?.findComponentByVector(vector);
9242
+ }
9243
+ const componentName = renderTarget?.name ? h.toKebabCase(renderTarget.name) : store.get("default");
9244
+ if (!componentName) {
9245
+ logger.warning("No component found for rendering in AreRoot. Please ensure that the signal vector matches at least one component or that a default component name is provided in the store.");
9246
+ return;
9247
+ }
9248
+ root.setContent(`<${componentName}></${componentName}>`);
9249
+ for (let i = 0; i < root.children.length; i++) {
9250
+ const child = root.children[i];
9251
+ child.unmount();
9252
+ child.destroy();
9253
+ root.removeChild(child);
9254
+ }
9255
+ root.tokenize();
9256
+ for (let i = 0; i < root.children.length; i++) {
9257
+ const child = root.children[i];
9258
+ child.init();
9259
+ const res = child.load();
9260
+ if (res instanceof Promise) {
9261
+ await res;
9262
+ }
9263
+ child.transform();
9264
+ child.compile();
9265
+ child.mount();
9382
9266
  }
9383
9267
  }
9384
9268
  };
9385
- __name(_DashboardMenu, "DashboardMenu");
9269
+ __name(AreRoot, "AreRoot");
9386
9270
  __decorateClass([
9387
9271
  Are.Template,
9388
- __decorateParam(0, ke(G))
9389
- ], _DashboardMenu.prototype, "template", 1);
9390
- __decorateClass([
9391
- Are.Data,
9392
- __decorateParam(0, ke(AreStore))
9393
- ], _DashboardMenu.prototype, "data", 1);
9272
+ __decorateParam(0, ke(G)),
9273
+ __decorateParam(1, ke(A_Logger)),
9274
+ __decorateParam(2, ke(AreSignalsContext))
9275
+ ], AreRoot.prototype, "template", 1);
9394
9276
  __decorateClass([
9395
- Are.EventHandler,
9277
+ Are.Signal,
9396
9278
  __decorateParam(0, ke(G)),
9397
- __decorateParam(1, ke(AreEvent)),
9398
- __decorateParam(2, ke(AreContext)),
9399
- __decorateParam(3, ke(AreStore)),
9400
- __decorateParam(4, ke(A_Logger))
9401
- ], _DashboardMenu.prototype, "handleClick", 1);
9402
- var DashboardMenu = _DashboardMenu;
9279
+ __decorateParam(1, ke(A_SignalVector)),
9280
+ __decorateParam(2, ke(AreStore)),
9281
+ __decorateParam(3, ke(A_Logger)),
9282
+ __decorateParam(4, ke(AreSignalsContext))
9283
+ ], AreRoot.prototype, "onSignal", 1);
9284
+ AreRoot = __decorateClass([
9285
+ c2.Component({
9286
+ namespace: "A-ARE",
9287
+ name: "AreRoot",
9288
+ 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."
9289
+ })
9290
+ ], AreRoot);
9403
9291
 
9404
- // examples/dashboard/src/components/DashboardMain.component.ts
9405
- var _DashboardMain = class _DashboardMain extends Are {
9406
- template(node) {
9407
- node.setContent(`
9408
- <main class="main">
9409
- <div class="main-header">
9410
- <div>
9411
- <h1 class="main-title">{{pageTitle}}</h1>
9412
- <div class="main-subtitle">{{pageSubtitle}}</div>
9413
- </div>
9414
- <div class="main-actions">
9415
- <button class="btn btn-outline"><span class="btn-icon">\u2B07</span> {{exportLabel}}</button>
9416
- <button class="btn btn-primary" @click="(e)=>!!pageTitle? $testHandler(e,'item'):null"><span class="btn-icon">+</span> {{addLabel}}</button>
9417
- </div>
9418
- </div>
9419
- <dashboard-stats></dashboard-stats>
9420
- <dashboard-table></dashboard-table>
9421
- </main>
9422
- `);
9423
- }
9424
- data(store) {
9425
- store.set({
9426
- pageTitle: "Overview",
9427
- pageSubtitle: "Welcome back, John. Here's what's happening today.",
9428
- exportLabel: "Export",
9429
- addLabel: "New Record"
9430
- });
9431
- }
9432
- async testHandler(node, store, logger, event, scene) {
9433
- console.log("Button clicked! This is a test event handler.", event);
9434
- }
9292
+ // src/instructions/AreHTML.instructions.constants.ts
9293
+ var AreHTMLInstructions = {
9294
+ AddElement: "_AreHTML_AddElement",
9295
+ AddText: "_AreHTML_AddText",
9296
+ AddAttribute: "_AreHTML_AddAttribute",
9297
+ AddStyle: "_AreHTML_AddStyle",
9298
+ AddListener: "_AreHTML_AddListener",
9299
+ AddInterpolation: "_AreHTML_AddInterpolation",
9300
+ AddComment: "_AreHTML_AddComment"
9435
9301
  };
9436
- __name(_DashboardMain, "DashboardMain");
9437
- __decorateClass([
9438
- Are.Template,
9439
- __decorateParam(0, ke(G))
9440
- ], _DashboardMain.prototype, "template", 1);
9441
- __decorateClass([
9442
- Are.Data,
9443
- __decorateParam(0, ke(AreStore))
9444
- ], _DashboardMain.prototype, "data", 1);
9445
- __decorateClass([
9446
- Are.EventHandler,
9447
- __decorateParam(0, ke(G)),
9448
- __decorateParam(1, ke(AreStore)),
9449
- __decorateParam(2, ke(A_Logger)),
9450
- __decorateParam(3, ke(AreEvent)),
9451
- __decorateParam(4, ke(AreScene))
9452
- ], _DashboardMain.prototype, "testHandler", 1);
9453
- var DashboardMain = _DashboardMain;
9454
9302
 
9455
- // examples/dashboard/src/components/DashboardStats.component.ts
9456
- var _DashboardStats = class _DashboardStats extends Are {
9457
- template(node) {
9458
- node.setContent(`
9459
- <div class="stats">
9460
- <dashboard-stat-card></dashboard-stat-card>
9461
- </div>
9462
- `);
9463
- }
9464
- data(store) {
9465
- store.set({
9466
- section: "stats"
9467
- });
9468
- }
9469
- };
9470
- __name(_DashboardStats, "DashboardStats");
9471
- __decorateClass([
9472
- Are.Template,
9473
- __decorateParam(0, ke(G))
9474
- ], _DashboardStats.prototype, "template", 1);
9475
- __decorateClass([
9476
- Are.Data,
9477
- __decorateParam(0, ke(AreStore))
9478
- ], _DashboardStats.prototype, "data", 1);
9479
- var DashboardStats = _DashboardStats;
9480
-
9481
- // examples/dashboard/src/components/DashboardStatCard.component.ts
9482
- var _DashboardStatCard = class _DashboardStatCard extends Are {
9483
- template(node) {
9484
- node.setContent(`
9485
- <div class="stat-card">
9486
- <div class="stat-card-header">
9487
- <div class="stat-label">{{label1}}</div>
9488
- <div class="stat-icon stat-icon-purple">\u{1F464}</div>
9489
- </div>
9490
- <div class="stat-value">{{value1}}</div>
9491
- <div class="stat-change"><span class="stat-change-icon">\u2191</span> {{change1}}</div>
9492
- </div>
9493
- <div class="stat-card">
9494
- <div class="stat-card-header">
9495
- <div class="stat-label">{{label2}}</div>
9496
- <div class="stat-icon stat-icon-green">\u{1F4B0}</div>
9497
- </div>
9498
- <div class="stat-value">{{value2}}</div>
9499
- <div class="stat-change"><span class="stat-change-icon">\u2191</span> {{change2}}</div>
9500
- </div>
9501
- <div class="stat-card">
9502
- <div class="stat-card-header">
9503
- <div class="stat-label">{{label3}}</div>
9504
- <div class="stat-icon stat-icon-red">\u{1F4CA}</div>
9505
- </div>
9506
- <div class="stat-value">{{value3}}</div>
9507
- <div class="stat-change stat-change-down"><span class="stat-change-icon">\u2193</span> {{change3}}</div>
9508
- </div>
9509
- <div class="stat-card">
9510
- <div class="stat-card-header">
9511
- <div class="stat-label">{{label4}}</div>
9512
- <div class="stat-icon stat-icon-blue">\u{1F3AF}</div>
9513
- </div>
9514
- <div class="stat-value">{{value4}}</div>
9515
- <div class="stat-change"><span class="stat-change-icon">\u2191</span> {{change4}}</div>
9516
- </div>
9517
- `);
9518
- }
9519
- data(store) {
9520
- store.set({
9521
- label1: "Total Users",
9522
- value1: "24,521",
9523
- change1: "+12.5% from last month",
9524
- label2: "Revenue",
9525
- value2: "$48,390",
9526
- change2: "+8.2% from last month",
9527
- label3: "Active Sessions",
9528
- value3: "1,429",
9529
- change3: "-3.1% from last hour",
9530
- label4: "Conversion Rate",
9531
- value4: "3.24%",
9532
- change4: "+0.8% from last week"
9533
- });
9303
+ // src/lib/AreDirective/AreDirective.context.ts
9304
+ var _AreDirectiveContext = class _AreDirectiveContext extends A_ExecutionContext {
9305
+ constructor(aseid) {
9306
+ super(aseid.toString());
9307
+ this.scope = {};
9534
9308
  }
9535
9309
  };
9536
- __name(_DashboardStatCard, "DashboardStatCard");
9537
- __decorateClass([
9538
- Are.Template,
9539
- __decorateParam(0, ke(G))
9540
- ], _DashboardStatCard.prototype, "template", 1);
9541
- __decorateClass([
9542
- Are.Data,
9543
- __decorateParam(0, ke(AreStore))
9544
- ], _DashboardStatCard.prototype, "data", 1);
9545
- var DashboardStatCard = _DashboardStatCard;
9310
+ __name(_AreDirectiveContext, "AreDirectiveContext");
9311
+ var AreDirectiveContext = _AreDirectiveContext;
9546
9312
 
9547
- // examples/dashboard/src/components/DashboardTable.component.ts
9548
- var _DashboardTable = class _DashboardTable extends Are {
9549
- template(node) {
9550
- node.setContent(`
9551
- <div class="table-container">
9552
- <div class="table-header">
9553
- <div>
9554
- <div class="table-title">{{tableTitle}}</div>
9555
- <div class="table-subtitle">{{tableSubtitle}}</div>
9556
- </div>
9557
- <div class="table-filter">
9558
- <button class="table-filter-btn table-filter-btn-active">{{filterAll}}</button>
9559
- <button class="table-filter-btn">{{filterActive}}</button>
9560
- <button class="table-filter-btn">{{filterPending}}</button>
9561
- </div>
9562
- </div>
9563
- <table class="table">
9564
- <thead>
9565
- <tr>
9566
- <th>{{col1}}</th>
9567
- <th>{{col2}}</th>
9568
- <th>{{col3}}</th>
9569
- <th>{{col4}}</th>
9570
- <th>{{col5}}</th>
9571
- </tr>
9572
- </thead>
9573
- <tbody>
9574
- <tr>
9575
- <td class="table-cell-primary">{{r1c1}}</td>
9576
- <td>{{r1c2}}</td>
9577
- <td>{{r1c3}}</td>
9578
- <td><span class="status-badge status-active"><span class="status-dot"></span> {{r1c4}}</span></td>
9579
- <td class="table-cell-secondary">{{r1c5}}</td>
9580
- </tr>
9581
- <tr>
9582
- <td class="table-cell-primary">{{r2c1}}</td>
9583
- <td>{{r2c2}}</td>
9584
- <td>{{r2c3}}</td>
9585
- <td><span class="status-badge status-pending"><span class="status-dot"></span> {{r2c4}}</span></td>
9586
- <td class="table-cell-secondary">{{r2c5}}</td>
9587
- </tr>
9588
- <tr>
9589
- <td class="table-cell-primary">{{r3c1}}</td>
9590
- <td>{{r3c2}}</td>
9591
- <td>{{r3c3}}</td>
9592
- <td><span class="status-badge status-active"><span class="status-dot"></span> {{r3c4}}</span></td>
9593
- <td class="table-cell-secondary">{{r3c5}}</td>
9594
- </tr>
9595
- <tr>
9596
- <td class="table-cell-primary">{{r4c1}}</td>
9597
- <td>{{r4c2}}</td>
9598
- <td>{{r4c3}}</td>
9599
- <td><span class="status-badge status-inactive"><span class="status-dot"></span> {{r4c4}}</span></td>
9600
- <td class="table-cell-secondary">{{r4c5}}</td>
9601
- </tr>
9602
- <tr>
9603
- <td class="table-cell-primary">{{r5c1}}</td>
9604
- <td>{{r5c2}}</td>
9605
- <td>{{r5c3}}</td>
9606
- <td><span class="status-badge status-active"><span class="status-dot"></span> {{r5c4}}</span></td>
9607
- <td class="table-cell-secondary">{{r5c5}}</td>
9608
- </tr>
9609
- </tbody>
9610
- </table>
9611
- <div class="table-footer">
9612
- <span>{{footerText}}</span>
9613
- <div class="table-pagination">
9614
- <button class="table-page-btn table-page-btn-active">1</button>
9615
- <button class="table-page-btn">2</button>
9616
- <button class="table-page-btn">3</button>
9617
- <button class="table-page-btn">\u2192</button>
9618
- </div>
9619
- </div>
9620
- </div>
9621
- `);
9313
+ // src/engine/AreHTML.context.ts
9314
+ var _AreHTMLEngineContext = class _AreHTMLEngineContext extends AreContext {
9315
+ constructor(props) {
9316
+ super(props.container?.body.innerHTML || props.source || "");
9317
+ /**
9318
+ * Index structure mapping:
9319
+ *
9320
+ * Node -> Group ID -> Element
9321
+ * -----------------------------------------------------------------------------------
9322
+ * | - Attribute | group: string | Node
9323
+ * | - Directive (e.g. for) | | Node
9324
+ */
9325
+ this.index = {
9326
+ /**
9327
+ * 1 AreNode = 1 Dom Node
9328
+ *
9329
+ * uses ASEID
9330
+ */
9331
+ nodeToHostElements: /* @__PURE__ */ new Map(),
9332
+ /**
9333
+ * 1 Group Instruction = MANY Dom Nodes (e.g. for loop)
9334
+ *
9335
+ * uses ASEID
9336
+ */
9337
+ groupToElements: /* @__PURE__ */ new Map(),
9338
+ /**
9339
+ * 1 Dom Node = 1 Instruction
9340
+ *
9341
+ * uses ASEID
9342
+ */
9343
+ elementToInstruction: /* @__PURE__ */ new WeakMap(),
9344
+ /**
9345
+ * 1 Instruction = 1 Dom Node (for CreateElement instructions, for example)
9346
+ *
9347
+ * uses ASEID
9348
+ */
9349
+ instructionToElement: /* @__PURE__ */ new Map(),
9350
+ /**
9351
+ * Event listeners attached to elements, used for proper cleanup when reverting instructions. Maps a DOM element to a map of event names and their corresponding listeners, allowing the engine to track which listeners are attached to which elements and remove them when necessary (e.g., when an instruction is reverted).
9352
+ */
9353
+ elementListeners: /* @__PURE__ */ new WeakMap()
9354
+ };
9355
+ this._container = props.container;
9622
9356
  }
9623
- data(store) {
9624
- store.set({
9625
- tableTitle: "Recent Transactions",
9626
- tableSubtitle: "Last 30 days activity",
9627
- filterAll: "All",
9628
- filterActive: "Active",
9629
- filterPending: "Pending",
9630
- col1: "Transaction",
9631
- col2: "Customer",
9632
- col3: "Amount",
9633
- col4: "Status",
9634
- col5: "Date",
9635
- r1c1: "INV-001",
9636
- r1c2: "Alice Johnson",
9637
- r1c3: "$1,250.00",
9638
- r1c4: "Active",
9639
- r1c5: "Mar 28, 2026",
9640
- r2c1: "INV-002",
9641
- r2c2: "Bob Williams",
9642
- r2c3: "$890.00",
9643
- r2c4: "Pending",
9644
- r2c5: "Mar 27, 2026",
9645
- r3c1: "INV-003",
9646
- r3c2: "Carol Davis",
9647
- r3c3: "$2,100.00",
9648
- r3c4: "Active",
9649
- r3c5: "Mar 26, 2026",
9650
- r4c1: "INV-004",
9651
- r4c2: "Dan Martinez",
9652
- r4c3: "$450.00",
9653
- r4c4: "Inactive",
9654
- r4c5: "Mar 25, 2026",
9655
- r5c1: "INV-005",
9656
- r5c2: "Eve Thompson",
9657
- r5c3: "$3,400.00",
9658
- r5c4: "Active",
9659
- r5c5: "Mar 24, 2026",
9660
- footerText: "Showing 1-5 of 24 results"
9661
- });
9357
+ get container() {
9358
+ return this._container;
9662
9359
  }
9663
- };
9664
- __name(_DashboardTable, "DashboardTable");
9665
- __decorateClass([
9666
- Are.Template,
9667
- __decorateParam(0, ke(G))
9668
- ], _DashboardTable.prototype, "template", 1);
9669
- __decorateClass([
9670
- Are.Data,
9671
- __decorateParam(0, ke(AreStore))
9672
- ], _DashboardTable.prototype, "data", 1);
9673
- var DashboardTable = _DashboardTable;
9674
-
9675
- // src/lib/AreHTMLAttribute/AreHTML.attribute.ts
9676
- var _AreHTMLAttribute = class _AreHTMLAttribute extends AreAttribute {
9677
- get owner() {
9678
- return this.scope.issuer();
9360
+ getNodeElement(node) {
9361
+ if (typeof node === "string") {
9362
+ return this.index.nodeToHostElements.get(node);
9363
+ } else {
9364
+ return this.index.nodeToHostElements.get(node.aseid.toString());
9365
+ }
9679
9366
  }
9680
- };
9681
- __name(_AreHTMLAttribute, "AreHTMLAttribute");
9682
- var AreHTMLAttribute = _AreHTMLAttribute;
9683
-
9684
- // src/attributes/AreBinding.attribute.ts
9685
- var _AreBindingAttribute = class _AreBindingAttribute extends AreHTMLAttribute {
9686
- // get value(): string {
9687
- // const [firstPart, ...pathPart] = this.content.split('.');
9688
- // const primaryObject = this.owner.store.get(firstPart);
9689
- // return AreCommonHelper.extractPropertyByPath(primaryObject, pathPart.join('.')) as string;
9690
- // }
9691
- };
9692
- __name(_AreBindingAttribute, "AreBindingAttribute");
9693
- var AreBindingAttribute = _AreBindingAttribute;
9694
-
9695
- // src/attributes/AreDirective.attribute.ts
9696
- var _AreDirectiveAttribute = class _AreDirectiveAttribute extends AreHTMLAttribute {
9697
9367
  /**
9698
- * Returns a custom directive component associated with this attribute, if available.
9368
+ * Associates a DOM element with a given instruction and its owner node. This method updates the context's index to map the instruction's ASEID to the provided DOM element, and also maps the element back to the instruction's ASEID for reverse lookup. If the instruction has an owner node, it also maps the node's ASEID to the element. Additionally, if the instruction belongs to a group, it adds the element to the set of elements associated with that group. This indexing allows the engine to efficiently manage and update DOM elements based on instructions and their corresponding nodes, enabling dynamic rendering and interaction in response to application state changes.
9699
9369
  *
9700
- * The method uses the attribute's name to resolve the corresponding directive component from the scope. It constructs the expected directive name by converting the attribute name to PascalCase and prefixing it with "AreDirective". If a matching directive component is found in the scope, it is returned; otherwise, the method returns undefined.
9370
+ * @param instruction
9371
+ * @param element
9701
9372
  */
9702
- get component() {
9703
- const component = this.scope.resolve(`AreDirective${h.toPascalCase(this.name)}`);
9704
- return component;
9373
+ setInstructionElement(instruction, element) {
9374
+ const node = instruction.owner;
9375
+ this.index.instructionToElement.set(instruction.aseid.toString(), element);
9376
+ this.index.elementToInstruction.set(element, instruction.aseid.toString());
9377
+ if (node) {
9378
+ this.index.nodeToHostElements.set(node.aseid.toString(), element);
9379
+ }
9380
+ if (instruction.group) {
9381
+ const groupId = instruction.group;
9382
+ if (!this.index.groupToElements.has(groupId)) {
9383
+ this.index.groupToElements.set(groupId, /* @__PURE__ */ new Set());
9384
+ }
9385
+ this.index.groupToElements.get(groupId).add(element);
9386
+ }
9705
9387
  }
9706
- };
9707
- __name(_AreDirectiveAttribute, "AreDirectiveAttribute");
9708
- var AreDirectiveAttribute = _AreDirectiveAttribute;
9709
-
9710
- // src/attributes/AreEvent.attribute.ts
9711
- var _AreEventAttribute = class _AreEventAttribute extends AreHTMLAttribute {
9712
- };
9713
- __name(_AreEventAttribute, "AreEventAttribute");
9714
- var AreEventAttribute = _AreEventAttribute;
9715
-
9716
- // src/attributes/AreStatic.attribute.ts
9717
- var _AreStaticAttribute = class _AreStaticAttribute extends AreHTMLAttribute {
9718
- };
9719
- __name(_AreStaticAttribute, "AreStaticAttribute");
9720
- var AreStaticAttribute = _AreStaticAttribute;
9721
-
9722
- // src/lib/AreDirective/AreDirective.meta.ts
9723
- var _AreDirectiveMeta = class _AreDirectiveMeta extends R {
9724
- constructor() {
9725
- super(...arguments);
9726
- this.priority = 0;
9388
+ getElementByInstruction(instruction) {
9389
+ if (typeof instruction === "string") {
9390
+ return this.index.instructionToElement.get(instruction);
9391
+ } else {
9392
+ return this.index.instructionToElement.get(instruction.aseid.toString());
9393
+ }
9727
9394
  }
9728
- };
9729
- __name(_AreDirectiveMeta, "AreDirectiveMeta");
9730
- var AreDirectiveMeta = _AreDirectiveMeta;
9731
-
9732
- // src/lib/AreDirective/AreDirective.constants.ts
9733
- var AreDirectiveFeatures = {
9734
- /**
9735
- * Feature that should transform the tree based on the directive attribute. This method is called during the transformation phase of the ARE component and should perform any necessary transformations on the AreNode tree based on the directive's content and context. This can include tasks such as adding or removing nodes, modifying node properties, or restructuring the tree to ensure that the directive is applied correctly during rendering.
9736
- */
9737
- Transform: "_AreDirective_Transform",
9738
9395
  /**
9739
- * Feature that should convert a directiveAttribute definition into a set of SceneInstructions to be rendered correctly
9396
+ * Removes the association between a given instruction and its corresponding DOM element. This method looks up the instruction's ASEID to find the associated DOM element, and if found, it deletes the mapping from both instructionToElement and elementToInstruction. If the instruction has an owner node, it also removes the mapping from nodeToHostElements. Additionally, if the instruction belongs to a group, it removes the element from the set of elements associated with that group, and if the group has no more elements, it deletes the group from the index. This cleanup is essential for maintaining an accurate and efficient mapping of instructions to DOM elements, especially when instructions are reverted or when nodes are removed from the DOM.
9397
+ *
9398
+ * @param instruction
9740
9399
  */
9741
- Compile: "_AreDirective_Compile",
9400
+ removeInstructionElement(instruction) {
9401
+ const element = this.index.instructionToElement.get(instruction.aseid.toString());
9402
+ if (element) {
9403
+ this.index.instructionToElement.delete(instruction.aseid.toString());
9404
+ this.index.elementToInstruction.delete(element);
9405
+ const node = instruction.owner;
9406
+ if (node) {
9407
+ this.index.nodeToHostElements.delete(node.aseid.toString());
9408
+ }
9409
+ if (instruction.group) {
9410
+ const groupId = instruction.group;
9411
+ const groupElements = this.index.groupToElements.get(groupId);
9412
+ if (groupElements) {
9413
+ groupElements.delete(element);
9414
+ if (groupElements.size === 0) {
9415
+ this.index.groupToElements.delete(groupId);
9416
+ }
9417
+ }
9418
+ }
9419
+ }
9420
+ }
9421
+ getElementsByGroup(instruction) {
9422
+ if (typeof instruction === "string") {
9423
+ return this.index.groupToElements.get(instruction);
9424
+ } else {
9425
+ return this.index.groupToElements.get(instruction.aseid.toString());
9426
+ }
9427
+ }
9742
9428
  /**
9743
- * Feature that should update the directiveAttribute based on the changes in the store or other dependencies.
9429
+ * Adds an event listener to a specific DOM element and keeps track of it in the context's index for proper cleanup later. This method takes a DOM element, an event name, and a listener function or object, and stores this information in the elementListeners map. This allows the engine to efficiently manage event listeners attached to dynamically created elements, ensuring that they can be removed when the associated instructions are reverted or when nodes are removed from the DOM, preventing memory leaks and unintended behavior.
9430
+ *
9431
+ * @param element
9432
+ * @param eventName
9433
+ * @param listener
9744
9434
  */
9745
- Update: "_AreDirective_Update"
9746
- };
9747
-
9748
- // src/lib/AreDirective/AreDirective.component.ts
9749
- var AreDirective = class extends v {
9750
- //==================================================================================
9751
- //======================== LIFECYCLE DECORATORS ====================================
9752
- //==================================================================================
9435
+ addListener(element, eventName, listener) {
9436
+ if (!this.index.elementListeners.has(element)) {
9437
+ this.index.elementListeners.set(element, /* @__PURE__ */ new Map());
9438
+ }
9439
+ const byEvent = this.index.elementListeners.get(element);
9440
+ if (!byEvent.has(eventName)) {
9441
+ byEvent.set(eventName, /* @__PURE__ */ new Set());
9442
+ }
9443
+ byEvent.get(eventName).add(listener);
9444
+ }
9753
9445
  /**
9754
- * Allows to define a compilation order for directives, which is necessary when we have multiple directives on the same node and we want to control the order of their compilation and application. The directive with the highest priority will be compiled and applied first, and the directive with the lowest priority will be compiled and applied last. This is important because some directives may depend on the output of other directives, so we need to ensure that they are compiled and applied in the correct order to avoid errors and ensure the expected behavior.
9446
+ * Retrieves the event listener associated with a specific DOM element and event name from the context's index. This method looks up the element in the elementListeners map and then retrieves the listener for the specified event name. If no listener is found for the given element and event, it returns undefined. This allows the engine to efficiently access and manage event listeners that have been attached to dynamically created elements, enabling proper cleanup when instructions are reverted or when nodes are removed from the DOM.
9755
9447
  *
9756
- * @param priority
9448
+ * @param element
9449
+ * @param eventName
9757
9450
  * @returns
9758
9451
  */
9759
- static Priority(priority) {
9760
- return function(target) {
9761
- const meta = c.meta(target);
9762
- meta.priority = priority;
9763
- return target;
9764
- };
9452
+ getListener(element, eventName) {
9453
+ const set = this.index.elementListeners.get(element)?.get(eventName);
9454
+ if (!set || set.size === 0) return void 0;
9455
+ return set.values().next().value;
9765
9456
  }
9766
9457
  /**
9767
- * Allows to define a custom method for transforming the AreNode tree based on the directive attribute. This method is called during the transformation phase of the ARE component and should perform any necessary transformations on the AreNode tree based on the directive's content and context. This can include tasks such as adding or removing nodes, modifying node properties, or restructuring the tree to ensure that the directive is applied correctly during rendering.
9458
+ * Returns all listeners registered for a given element + event name.
9768
9459
  */
9769
- static get Transform() {
9770
- return (target, propertyKey, descriptor) => {
9771
- return w.Extend({
9772
- name: AreDirectiveFeatures.Transform,
9773
- scope: [target.constructor]
9774
- })(target, propertyKey, descriptor);
9775
- };
9460
+ getListeners(element, eventName) {
9461
+ return this.index.elementListeners.get(element)?.get(eventName);
9776
9462
  }
9777
9463
  /**
9778
- * Allows to define a custom method for compiling a directive attribute into a set of SceneInstructions.
9779
- * Can be used at any component to extend this logic not only for a AreDirective inherited.
9464
+ * Removes an event listener from a specific DOM element and updates the context's index accordingly. This method looks up the element in the elementListeners map and deletes the listener for the specified event name. This is typically called when an instruction is reverted or when a node is removed from the DOM, ensuring that any attached event listeners are properly cleaned up to prevent memory leaks and unintended behavior.
9465
+ *
9466
+ * @param element
9467
+ * @param eventName
9780
9468
  */
9781
- static get Compile() {
9782
- return (target, propertyKey, descriptor) => {
9783
- return w.Extend({
9784
- name: AreDirectiveFeatures.Compile,
9785
- scope: [target.constructor]
9786
- })(target, propertyKey, descriptor);
9787
- };
9788
- }
9789
- /**
9790
- * Allows to define a custom method for updating a directive attribute based on changes in the store or other dependencies.
9791
- * Can be used at any component to extend this logic not only for a AreDirective inherited.
9792
- */
9793
- static get Update() {
9794
- return (target, propertyKey, descriptor) => {
9795
- return w.Extend({
9796
- name: AreDirectiveFeatures.Update,
9797
- scope: [target.constructor]
9798
- })(target, propertyKey, descriptor);
9799
- };
9800
- }
9801
- /**
9802
- * Default transform method for directives, which can be overridden by specific directive implementations. This method is called during the transformation phase of the ARE component and should perform any necessary transformations on the AreNode tree based on the directive's content and context. This can include tasks such as adding or removing nodes, modifying node properties, or restructuring the tree to ensure that the directive is applied correctly during rendering.
9803
- *
9804
- * @param attribute - The directive attribute to transform, which contains all the information about the directive as defined in the template (e.g. name, raw content, evaluated value, etc.)
9805
- * @param args - Additional arguments that may be required for the transformation process.
9806
- */
9807
- transform(attribute, ...args) {
9808
- const logger = c.scope(this).resolve(A_Logger);
9809
- if (logger) {
9810
- logger.warning(`No transforming logic defined for directive: ${attribute.name} with content: ${attribute.content}`);
9811
- }
9812
- }
9813
- compile(attribute, ...args) {
9814
- const logger = c.scope(this).resolve(A_Logger);
9815
- if (logger) {
9816
- logger.warning(`No compiling logic defined for directive: ${attribute.name} with content: ${attribute.content}`);
9817
- }
9818
- }
9819
- update(attribute, ...args) {
9820
- const logger = c.scope(this).resolve(A_Logger);
9821
- if (logger) {
9822
- logger.warning(`No update logic defined for directive: ${attribute.name} with content: ${attribute.content}`);
9469
+ removeListener(element, eventName, listener) {
9470
+ const byEvent = this.index.elementListeners.get(element);
9471
+ if (!byEvent) return;
9472
+ if (listener) {
9473
+ const set = byEvent.get(eventName);
9474
+ if (set) {
9475
+ set.delete(listener);
9476
+ if (set.size === 0) byEvent.delete(eventName);
9477
+ }
9478
+ } else {
9479
+ byEvent.delete(eventName);
9823
9480
  }
9824
9481
  }
9825
9482
  };
9826
- __name(AreDirective, "AreDirective");
9827
- __decorateClass([
9828
- __decorateParam(0, ke(G))
9829
- ], AreDirective.prototype, "transform", 1);
9830
- __decorateClass([
9831
- w.Extend({
9832
- name: AreDirectiveFeatures.Compile,
9833
- scope: [AreDirective]
9834
- }),
9835
- __decorateParam(0, ke(G))
9836
- ], AreDirective.prototype, "compile", 1);
9837
- __decorateClass([
9838
- w.Extend({
9839
- name: AreDirectiveFeatures.Update,
9840
- scope: [AreDirective]
9841
- }),
9842
- __decorateParam(0, ke(G))
9843
- ], AreDirective.prototype, "update", 1);
9844
- AreDirective = __decorateClass([
9845
- m.Define(AreDirectiveMeta)
9846
- ], AreDirective);
9483
+ __name(_AreHTMLEngineContext, "AreHTMLEngineContext");
9484
+ var AreHTMLEngineContext = _AreHTMLEngineContext;
9847
9485
 
9848
- // src/instructions/AreHTML.instructions.constants.ts
9849
- var AreHTMLInstructions = {
9850
- AddElement: "_AreHTML_AddElement",
9851
- AddText: "_AreHTML_AddText",
9852
- AddAttribute: "_AreHTML_AddAttribute",
9853
- AddStyle: "_AreHTML_AddStyle",
9854
- AddListener: "_AreHTML_AddListener",
9855
- AddInterpolation: "_AreHTML_AddInterpolation",
9856
- AddComment: "_AreHTML_AddComment"
9486
+ // src/engine/AreHTML.constants.ts
9487
+ var BOOLEAN_ATTRIBUTES = /* @__PURE__ */ new Set([
9488
+ "allowfullscreen",
9489
+ "async",
9490
+ "autofocus",
9491
+ "autoplay",
9492
+ "checked",
9493
+ "controls",
9494
+ "default",
9495
+ "defer",
9496
+ "disabled",
9497
+ "formnovalidate",
9498
+ "hidden",
9499
+ "inert",
9500
+ "ismap",
9501
+ "itemscope",
9502
+ "loop",
9503
+ "multiple",
9504
+ "muted",
9505
+ "nomodule",
9506
+ "novalidate",
9507
+ "open",
9508
+ "playsinline",
9509
+ "readonly",
9510
+ "required",
9511
+ "reversed",
9512
+ "selected"
9513
+ ]);
9514
+ function isBooleanAttribute(name) {
9515
+ return BOOLEAN_ATTRIBUTES.has(name.toLowerCase());
9516
+ }
9517
+ __name(isBooleanAttribute, "isBooleanAttribute");
9518
+ var IDL_FORM_PROPERTIES = {
9519
+ INPUT: /* @__PURE__ */ new Set(["value", "checked", "indeterminate"]),
9520
+ TEXTAREA: /* @__PURE__ */ new Set(["value"]),
9521
+ SELECT: /* @__PURE__ */ new Set(["value"]),
9522
+ OPTION: /* @__PURE__ */ new Set(["selected"])
9857
9523
  };
9858
-
9859
- // src/instructions/AddComment.instruction.ts
9860
- var AddCommentInstruction = class extends AreDeclaration {
9861
- get content() {
9862
- return this.payload.content;
9524
+ function isIDLFormProperty(tagName, attrName) {
9525
+ const set = IDL_FORM_PROPERTIES[tagName.toUpperCase()];
9526
+ return !!set && set.has(attrName);
9527
+ }
9528
+ __name(isIDLFormProperty, "isIDLFormProperty");
9529
+ function normalizeClassValue(value) {
9530
+ if (value === null || value === void 0 || value === false) return "";
9531
+ if (typeof value === "string") return value;
9532
+ if (typeof value === "number") return String(value);
9533
+ if (Array.isArray(value)) {
9534
+ return value.map(normalizeClassValue).filter(Boolean).join(" ");
9535
+ }
9536
+ if (typeof value === "object") {
9537
+ const parts = [];
9538
+ for (const key of Object.keys(value)) {
9539
+ if (value[key]) parts.push(key);
9540
+ }
9541
+ return parts.join(" ");
9542
+ }
9543
+ return "";
9544
+ }
9545
+ __name(normalizeClassValue, "normalizeClassValue");
9546
+ function normalizeStyleValue(value) {
9547
+ if (value === null || value === void 0 || value === false) return "";
9548
+ if (typeof value === "string") return value;
9549
+ if (typeof value === "number") return String(value);
9550
+ if (Array.isArray(value)) {
9551
+ return value.map(normalizeStyleValue).filter(Boolean).join("; ");
9552
+ }
9553
+ if (typeof value === "object") {
9554
+ const parts = [];
9555
+ for (const key of Object.keys(value)) {
9556
+ const v2 = value[key];
9557
+ if (v2 === null || v2 === void 0 || v2 === false) continue;
9558
+ const kebab = key.replace(/[A-Z]/g, (m2) => "-" + m2.toLowerCase());
9559
+ parts.push(`${kebab}: ${v2}`);
9560
+ }
9561
+ return parts.join("; ");
9562
+ }
9563
+ return "";
9564
+ }
9565
+ __name(normalizeStyleValue, "normalizeStyleValue");
9566
+ function parseEventName(raw) {
9567
+ const [event, ...modifiers] = raw.split(".");
9568
+ return { event, modifiers: new Set(modifiers) };
9569
+ }
9570
+ __name(parseEventName, "parseEventName");
9571
+ function toDOMString(value) {
9572
+ if (value === null || value === void 0) return "";
9573
+ if (typeof value === "string") return value;
9574
+ if (typeof value === "number" || typeof value === "boolean") return String(value);
9575
+ try {
9576
+ return JSON.stringify(value);
9577
+ } catch {
9578
+ return "";
9863
9579
  }
9864
- constructor(props) {
9865
- if ("aseid" in props) {
9866
- super(props);
9867
- } else {
9868
- super(AreHTMLInstructions.AddComment, props);
9580
+ }
9581
+ __name(toDOMString, "toDOMString");
9582
+
9583
+ // src/engine/AreHTML.interpreter.ts
9584
+ var AreHTMLInterpreter = class extends AreInterpreter {
9585
+ addElement(declaration, context, logger) {
9586
+ try {
9587
+ const node = declaration.owner;
9588
+ let currentNode = node;
9589
+ let parent = node.parent;
9590
+ while (parent) {
9591
+ if (context.getNodeElement(parent)) {
9592
+ break;
9593
+ }
9594
+ currentNode = parent;
9595
+ parent = parent.parent;
9596
+ }
9597
+ const tag = node.tag;
9598
+ if (parent) {
9599
+ const mountPoint = context.getNodeElement(parent);
9600
+ if (!mountPoint) {
9601
+ throw new AreInterpreterError({
9602
+ title: "Mount Point Not Found",
9603
+ description: `Could not find a mount point for the node with id "${node.id}". Ensure that the parent node is rendered before its children, or that a valid root element with the corresponding id exists in the DOM.`
9604
+ });
9605
+ }
9606
+ const element = context.container.createElement(tag);
9607
+ element.setAttribute("data-aseid", node.aseid.toString());
9608
+ if (mountPoint.nodeType === Node.ELEMENT_NODE) {
9609
+ mountPoint.appendChild(element);
9610
+ } else {
9611
+ mountPoint.parentNode?.insertBefore(element, mountPoint);
9612
+ }
9613
+ context.setInstructionElement(declaration, element);
9614
+ } else {
9615
+ const mountPoint = context.container.getElementById(node.id);
9616
+ if (!mountPoint) {
9617
+ throw new AreInterpreterError({
9618
+ title: "Mount Point Not Found",
9619
+ description: `Could not find a mount point for the node with id "${node.id}". Ensure that the parent node is rendered before its children, or that a valid root element with the corresponding id exists in the DOM.`
9620
+ });
9621
+ }
9622
+ const element = context.container.createElement(tag);
9623
+ element.setAttribute("data-aseid", node.aseid.toString());
9624
+ mountPoint.parentNode?.replaceChild(element, mountPoint);
9625
+ context.setInstructionElement(declaration, element);
9626
+ }
9627
+ logger?.debug("green", `Element ${node.aseid.toString()} added to Context:`);
9628
+ } catch (error) {
9629
+ logger?.error(error);
9630
+ throw error;
9869
9631
  }
9870
9632
  }
9871
- };
9872
- __name(AddCommentInstruction, "AddCommentInstruction");
9873
- AddCommentInstruction = __decorateClass([
9874
- c2.Component({
9875
- namespace: "A-ARE",
9876
- name: "AddCommentInstruction",
9877
- description: "Appends a comment node to an element. Apply creates the comment node; revert removes it. Content can be a static string or a dynamic getter for interpolations."
9878
- })
9879
- ], AddCommentInstruction);
9880
-
9881
- // src/lib/AreDirective/AreDirective.context.ts
9882
- var _AreDirectiveContext = class _AreDirectiveContext extends A_ExecutionContext {
9883
- constructor(aseid) {
9884
- super(aseid.toString());
9885
- this.scope = {};
9633
+ removeElement(declaration, context) {
9634
+ const element = context.getElementByInstruction(declaration);
9635
+ if (element && element.parentNode) {
9636
+ element.parentNode.removeChild(element);
9637
+ }
9638
+ context.removeInstructionElement(declaration);
9886
9639
  }
9887
- };
9888
- __name(_AreDirectiveContext, "AreDirectiveContext");
9889
- var AreDirectiveContext = _AreDirectiveContext;
9890
-
9891
- // src/directives/AreDirectiveFor.directive.ts
9892
- var AreDirectiveFor = class extends AreDirective {
9893
- transform(attribute, scope, store, scene, logger, ...args) {
9894
- logger.debug(`[Transform] directive $FOR for <${attribute.owner.aseid.toString()}>`);
9895
- const node = attribute.owner;
9896
- const forTemplate = node.cloneWithScope();
9897
- const forAttr = forTemplate.attributes.find((d2) => d2.name === attribute.name);
9898
- if (forAttr) {
9899
- forTemplate.scope.deregister(forAttr);
9900
- node.scope.register(forAttr);
9640
+ addAttribute(mutation, context, store, syntax, directiveContext, logger) {
9641
+ const element = context.getElementByInstruction(mutation.parent);
9642
+ if (!element) {
9643
+ throw new AreInterpreterError({
9644
+ title: "Element Not Found",
9645
+ description: `Could not find a DOM element associated with the instruction ASEID "${mutation.parent}". Ensure that the parent instruction is properly rendered and associated with a DOM element before applying attribute mutations.`
9646
+ });
9901
9647
  }
9902
- node.init();
9903
- attribute.template = forTemplate;
9904
- const { key, index, arrayExpr } = this.parseExpression(attribute.content);
9905
- const array = this.resolveArray(store, arrayExpr, attribute.content);
9906
- attribute.value = array;
9907
- console.log('Initial array for "for" directive:', scene);
9908
- for (let i = 0; i < array.length; i++) {
9909
- this.spawnItemNode(attribute.template, attribute.owner, key, index, array[i], i);
9648
+ const { name, content, evaluate } = mutation.payload;
9649
+ const rawValue = evaluate ? syntax.evaluate(content, store, {
9650
+ ...directiveContext?.scope || {}
9651
+ }) : content;
9652
+ const el = element;
9653
+ const lowerName = name.toLowerCase();
9654
+ if (isBooleanAttribute(lowerName)) {
9655
+ if (rawValue) {
9656
+ el.setAttribute(lowerName, "");
9657
+ try {
9658
+ el[lowerName] = true;
9659
+ } catch {
9660
+ }
9661
+ } else {
9662
+ el.removeAttribute(lowerName);
9663
+ try {
9664
+ el[lowerName] = false;
9665
+ } catch {
9666
+ }
9667
+ }
9668
+ mutation.cache = rawValue ? "true" : "";
9669
+ return;
9910
9670
  }
9911
- console.log('Template for "for" directive:', forTemplate);
9912
- }
9913
- compile(attribute, store, scene, ...args) {
9914
- const hostInstruction = scene.host;
9915
- const commentIdentifier = ` --- for: ${attribute.template.id} --- `;
9916
- const declaration = new AddCommentInstruction({ content: commentIdentifier });
9917
- scene.setHost(declaration);
9918
- scene.planBefore(declaration, hostInstruction);
9919
- scene.unPlan(hostInstruction);
9920
- }
9921
- update(attribute, store, scene, ...args) {
9922
- const { key, index, arrayExpr } = this.parseExpression(attribute.content);
9923
- const newArray = this.resolveArray(store, arrayExpr, attribute.content);
9924
- const owner = attribute.owner;
9925
- const currentChildren = [...owner.children];
9926
- attribute.value = newArray;
9927
- const newLen = newArray.length;
9928
- const newItemSet = new Set(newArray);
9929
- const keptChildren = [];
9930
- const removedChildren = [];
9931
- for (const child of currentChildren) {
9932
- const ctx = child.scope.resolveFlat(AreDirectiveContext);
9933
- if (ctx && newItemSet.has(ctx.scope[key])) {
9934
- keptChildren.push(child);
9671
+ if (isIDLFormProperty(el.tagName, name)) {
9672
+ const propName = name === "value" ? "value" : name === "checked" ? "checked" : name === "selected" ? "selected" : name === "indeterminate" ? "indeterminate" : name;
9673
+ try {
9674
+ if (propName === "checked" || propName === "selected" || propName === "indeterminate") {
9675
+ el[propName] = !!rawValue;
9676
+ } else {
9677
+ el[propName] = toDOMString(rawValue);
9678
+ }
9679
+ } catch {
9680
+ }
9681
+ if (propName !== "value") {
9682
+ if (rawValue) el.setAttribute(name, "");
9683
+ else el.removeAttribute(name);
9935
9684
  } else {
9936
- removedChildren.push(child);
9685
+ el.setAttribute(name, toDOMString(rawValue));
9937
9686
  }
9687
+ mutation.cache = toDOMString(rawValue);
9688
+ return;
9938
9689
  }
9939
- for (const child of removedChildren) {
9940
- child.unmount();
9941
- owner.removeChild(child);
9690
+ if (lowerName === "class") {
9691
+ const newValue = normalizeClassValue(rawValue);
9692
+ if (mutation.cache === void 0) {
9693
+ const existingValue = el.getAttribute("class");
9694
+ const merged = existingValue ? `${existingValue} ${newValue}`.trim() : newValue;
9695
+ if (merged) el.setAttribute("class", merged);
9696
+ else el.removeAttribute("class");
9697
+ } else {
9698
+ const existingValue = el.getAttribute("class");
9699
+ const existingParts = existingValue ? existingValue.split(/\s+/).filter(Boolean) : [];
9700
+ const oldParts = new Set(mutation.cache.split(/\s+/).filter(Boolean));
9701
+ const newParts = newValue ? newValue.split(/\s+/).filter(Boolean) : [];
9702
+ const merged = [...existingParts.filter((p) => !oldParts.has(p)), ...newParts].join(" ");
9703
+ if (merged) el.setAttribute("class", merged);
9704
+ else el.removeAttribute("class");
9705
+ }
9706
+ mutation.cache = newValue;
9707
+ return;
9942
9708
  }
9943
- for (let i = 0; i < keptChildren.length; i++) {
9944
- let directiveContext = keptChildren[i].scope.resolveFlat(AreDirectiveContext);
9945
- if (!directiveContext) {
9946
- directiveContext = new AreDirectiveContext(keptChildren[i].aseid);
9947
- keptChildren[i].scope.register(directiveContext);
9948
- }
9949
- directiveContext.scope = {
9950
- ...directiveContext.scope,
9951
- [key]: newArray[i],
9952
- [index || "index"]: i
9953
- };
9709
+ if (lowerName === "style") {
9710
+ const newValue = normalizeStyleValue(rawValue);
9711
+ if (newValue) el.setAttribute("style", newValue);
9712
+ else el.removeAttribute("style");
9713
+ mutation.cache = newValue;
9714
+ return;
9954
9715
  }
9955
- for (let i = keptChildren.length; i < newLen; i++) {
9956
- const itemNode = this.spawnItemNode(attribute.template, owner, key, index, newArray[i], i);
9957
- itemNode.transform();
9958
- itemNode.compile();
9959
- itemNode.mount();
9716
+ const stringValue = toDOMString(rawValue);
9717
+ if (stringValue === "" && evaluate && (rawValue === false || rawValue === null || rawValue === void 0)) {
9718
+ el.removeAttribute(name);
9719
+ } else {
9720
+ el.setAttribute(name, stringValue);
9960
9721
  }
9722
+ mutation.cache = stringValue;
9961
9723
  }
9962
- // ─────────────────────────────────────────────────────────────────────────────
9963
- // ── Helpers ──────────────────────────────────────────────────────────────────
9964
- // ─────────────────────────────────────────────────────────────────────────────
9965
- /**
9966
- * Parses the $for expression string into its constituent parts.
9967
- *
9968
- * Supported formats:
9969
- * item in items
9970
- * item, index in items
9971
- * (item, index) in items
9972
- * item in filter(items)
9973
- * item, index in filter(items, 'active')
9974
- */
9975
- parseExpression(content) {
9976
- const inIndex = content.lastIndexOf(" in ");
9977
- const keyAndIndex = content.slice(0, inIndex).trim().replace(/^\(|\)$/g, "");
9978
- const arrayExpr = content.slice(inIndex + 4).trim();
9979
- const keyParts = keyAndIndex.split(",").map((p) => p.trim());
9980
- return {
9981
- key: keyParts[0],
9982
- index: keyParts[1] || void 0,
9983
- arrayExpr
9984
- };
9985
- }
9986
- /**
9987
- * Resolves the array expression against the store.
9988
- * Supports both plain key lookups and function-call expressions:
9989
- * items → store.get('items')
9990
- * filter(items) → store.get('filter')(store.get('items'))
9991
- */
9992
- resolveArray(store, arrayExpr, fullContent) {
9993
- let result;
9994
- const callMatch = arrayExpr.match(/^([^(]+)\((.+)\)$/);
9995
- if (callMatch) {
9996
- const fnName = callMatch[1].trim();
9997
- const fn = store.get(fnName);
9998
- if (typeof fn !== "function")
9999
- throw new AreCompilerError({
10000
- title: 'Invalid "for" Directive Function',
10001
- description: `The expression "${fnName}" in the "for" directive does not resolve to a function in the store. Received: ${typeof fn}`
10002
- });
10003
- const rawArgs = callMatch[2].split(",").map((a2) => a2.trim());
10004
- const resolvedArgs = rawArgs.map((arg) => {
10005
- if (arg.startsWith("'") && arg.endsWith("'")) return arg.slice(1, -1);
10006
- if (arg.startsWith('"') && arg.endsWith('"')) return arg.slice(1, -1);
10007
- if (!isNaN(Number(arg))) return Number(arg);
10008
- return store.get(arg);
10009
- });
10010
- result = fn(...resolvedArgs);
10011
- } else {
10012
- result = store.get(arrayExpr);
9724
+ removeAttribute(mutation, context) {
9725
+ try {
9726
+ const element = context.getElementByInstruction(mutation.parent);
9727
+ if (!element) return;
9728
+ const { name } = mutation.payload;
9729
+ if (name && element.nodeType === Node.ELEMENT_NODE) {
9730
+ element?.removeAttribute(name);
9731
+ }
9732
+ } catch (error) {
9733
+ console.log("Error removing attribute:", error);
10013
9734
  }
10014
- if (!Array.isArray(result))
10015
- throw new AreCompilerError({
10016
- title: 'Invalid "for" Directive Value',
10017
- description: `The "for" directive expects an array but got ${typeof result}. Expression: "${fullContent}". Received: ${JSON.stringify(result)}`
10018
- });
10019
- return result;
10020
9735
  }
10021
- /**
10022
- * Creates a single item node from the template, registers it as a child of
10023
- * the owner, initialises it, injects item-scoped store values, and activates
10024
- * its scene so the mount/compile cycle will include it.
10025
- *
10026
- * NOTE: This method does NOT call compile() or mount() the caller is
10027
- * responsible for doing so when the main lifecycle cycle won't cover it
10028
- * (i.e. during update, but not during the initial compile phase).
10029
- */
10030
- spawnItemNode(template, owner, key, index, item, i) {
10031
- const itemNode = template.clone();
10032
- owner.addChild(itemNode);
10033
- const queue = [itemNode];
10034
- while (queue.length > 0) {
10035
- const current = queue.shift();
10036
- current.init();
10037
- queue.push(...current.children);
9736
+ addEventListener(mutation, context, store, syntax, directiveContext, logger) {
9737
+ const element = context.getElementByInstruction(mutation.parent);
9738
+ if (!element) {
9739
+ throw new AreInterpreterError({
9740
+ title: "Element Not Found",
9741
+ description: `Could not find a DOM element associated with the instruction ASEID "${mutation.parent}". Ensure that the parent instruction is properly rendered and associated with a DOM element before adding event listeners.`
9742
+ });
10038
9743
  }
10039
- let directiveContext = itemNode.scope.resolveFlat(AreDirectiveContext);
10040
- if (!directiveContext) {
10041
- directiveContext = new AreDirectiveContext(itemNode.aseid);
10042
- itemNode.scope.register(directiveContext);
9744
+ const { event: eventName, modifiers } = parseEventName(mutation.payload.name);
9745
+ const listenerOptions = {};
9746
+ if (modifiers.has("capture")) listenerOptions.capture = true;
9747
+ if (modifiers.has("once")) listenerOptions.once = true;
9748
+ if (modifiers.has("passive")) listenerOptions.passive = true;
9749
+ const handlers = syntax.extractEmitHandlers(mutation.payload.handler);
9750
+ let liveEvent = null;
9751
+ const handlerScope = {};
9752
+ for (const handler of handlers) {
9753
+ const handlerFn = /* @__PURE__ */ __name((...args) => {
9754
+ const event = new AreEvent(handler);
9755
+ const effectiveArgs = args.length === 0 && liveEvent ? [liveEvent] : liveEvent ? [...args, liveEvent] : args;
9756
+ event.set("args", effectiveArgs);
9757
+ event.set("element", element);
9758
+ event.set("instruction", mutation);
9759
+ mutation.owner.emit(event);
9760
+ }, "handlerFn");
9761
+ handlerScope[`$${handler}`] = handlerFn;
10043
9762
  }
10044
- directiveContext.scope = {
10045
- ...directiveContext.scope,
10046
- [key]: item,
10047
- [index || "index"]: i
10048
- };
10049
- itemNode.scene.activate();
10050
- return itemNode;
9763
+ const callback = /* @__PURE__ */ __name((e) => {
9764
+ try {
9765
+ liveEvent = e;
9766
+ if (modifiers.has("self") && e.target !== element) return;
9767
+ if (modifiers.has("stop")) e.stopPropagation();
9768
+ if (modifiers.has("prevent")) e.preventDefault();
9769
+ if (e instanceof KeyboardEvent && modifiers.size > 0) {
9770
+ const key = (e.key || "").toLowerCase();
9771
+ const KEY_ALIASES = {
9772
+ enter: ["enter"],
9773
+ esc: ["escape"],
9774
+ escape: ["escape"],
9775
+ tab: ["tab"],
9776
+ space: [" ", "spacebar"],
9777
+ up: ["arrowup"],
9778
+ down: ["arrowdown"],
9779
+ left: ["arrowleft"],
9780
+ right: ["arrowright"],
9781
+ delete: ["delete", "backspace"]
9782
+ };
9783
+ const keyMods = [...modifiers].filter((m2) => m2 in KEY_ALIASES || m2 === "ctrl" || m2 === "alt" || m2 === "shift" || m2 === "meta");
9784
+ if (keyMods.length > 0) {
9785
+ const keyMatch = keyMods.some((m2) => {
9786
+ if (m2 === "ctrl") return e.ctrlKey;
9787
+ if (m2 === "alt") return e.altKey;
9788
+ if (m2 === "shift") return e.shiftKey;
9789
+ if (m2 === "meta") return e.metaKey;
9790
+ const aliases = KEY_ALIASES[m2];
9791
+ return aliases && aliases.includes(key);
9792
+ });
9793
+ if (!keyMatch) return;
9794
+ }
9795
+ }
9796
+ context.startPerformance("event:" + eventName);
9797
+ const result = syntax.evaluate(mutation.payload.handler, store, {
9798
+ ...handlerScope,
9799
+ $event: e,
9800
+ ...directiveContext?.scope || {}
9801
+ });
9802
+ if (typeof result === "function") result(e);
9803
+ context.endPerformance("event:" + eventName);
9804
+ } catch (err) {
9805
+ logger?.error(err);
9806
+ } finally {
9807
+ liveEvent = null;
9808
+ }
9809
+ }, "callback");
9810
+ const useOptions = listenerOptions.capture || listenerOptions.once || listenerOptions.passive;
9811
+ if (useOptions) {
9812
+ element.addEventListener(eventName, callback, listenerOptions);
9813
+ } else {
9814
+ element.addEventListener(eventName, callback);
9815
+ }
9816
+ mutation.payload._callback = callback;
9817
+ context.addListener(element, mutation.payload.name, callback);
10051
9818
  }
10052
- };
10053
- __name(AreDirectiveFor, "AreDirectiveFor");
10054
- __decorateClass([
10055
- AreDirective.Transform,
10056
- __decorateParam(0, ke(G)),
10057
- __decorateParam(1, ke(D)),
10058
- __decorateParam(2, ke(AreStore)),
10059
- __decorateParam(3, ke(AreScene)),
10060
- __decorateParam(4, ke(A_Logger))
10061
- ], AreDirectiveFor.prototype, "transform", 1);
10062
- __decorateClass([
10063
- AreDirective.Compile,
10064
- __decorateParam(0, ke(G)),
10065
- __decorateParam(1, ke(AreStore)),
10066
- __decorateParam(2, ke(AreScene))
10067
- ], AreDirectiveFor.prototype, "compile", 1);
10068
- __decorateClass([
10069
- AreDirective.Update,
10070
- __decorateParam(0, ke(G)),
10071
- __decorateParam(1, ke(AreStore)),
10072
- __decorateParam(2, ke(AreScene))
10073
- ], AreDirectiveFor.prototype, "update", 1);
10074
- AreDirectiveFor = __decorateClass([
10075
- AreDirective.Priority(1)
10076
- ], AreDirectiveFor);
10077
-
10078
- // src/directives/AreDirectiveIf.directive.ts
10079
- var AreDirectiveIf = class extends AreDirective {
10080
- transform(attribute, scope, store, scene, logger, ...args) {
10081
- logger.debug(`[Transform] directive $IF for <${attribute.owner.aseid.toString()}>`);
10082
- const node = attribute.owner;
10083
- const ifTemplate = node.cloneWithScope();
10084
- const ifAttr = ifTemplate.attributes.find((d2) => d2.name === attribute.name);
10085
- if (ifAttr) {
10086
- ifTemplate.scope.deregister(ifAttr);
10087
- node.scope.register(ifAttr);
9819
+ removeEventListener(mutation, context) {
9820
+ const element = context.getElementByInstruction(mutation.parent);
9821
+ if (!element) return;
9822
+ const { name } = mutation.payload;
9823
+ const { event: eventName } = parseEventName(name);
9824
+ const listener = mutation.payload._callback;
9825
+ if (listener) {
9826
+ element.removeEventListener(eventName, listener);
9827
+ context.removeListener(element, name, listener);
9828
+ mutation.payload._callback = void 0;
10088
9829
  }
10089
- node.init();
10090
- node.addChild(ifTemplate);
10091
- ifTemplate.scene.deactivate();
10092
- attribute.template = ifTemplate;
10093
9830
  }
10094
- compile(attribute, store, scene, syntax, directiveContext, ...args) {
10095
- console.log('Compiling directive "if" with attribute content:', attribute);
10096
- attribute.value = syntax.evaluate(attribute.content, store, {
9831
+ addText(declaration, context, store, syntax, directiveContext, logger) {
9832
+ const node = declaration.owner.parent;
9833
+ const { content, evaluate } = declaration.payload;
9834
+ const rawValue = evaluate ? syntax.evaluate(content, store, {
10097
9835
  ...directiveContext?.scope || {}
10098
- });
10099
- const hostInstruction = scene.host;
10100
- const commentIdentifier = ` --- if: ${attribute.template.id} --- `;
10101
- const declaration = new AddCommentInstruction({ content: commentIdentifier });
10102
- scene.setHost(declaration);
10103
- scene.planBefore(declaration, hostInstruction);
10104
- scene.unPlan(hostInstruction);
10105
- if (attribute.value)
10106
- attribute.template.scene.activate();
10107
- else
10108
- attribute.template.scene.deactivate();
9836
+ }) : content;
9837
+ const value = toDOMString(rawValue);
9838
+ if (!node) {
9839
+ const textNode = context.container.createTextNode(value);
9840
+ context.container.body.appendChild(textNode);
9841
+ context.setInstructionElement(declaration, textNode);
9842
+ } else {
9843
+ const element = context.getNodeElement(node);
9844
+ if (!element) {
9845
+ throw new AreInterpreterError({
9846
+ title: "Element Not Found",
9847
+ description: `Could not find a DOM element associated with the instruction ASEID "${declaration.owner.parent.aseid}". Ensure that the parent instruction is properly rendered and associated with a DOM element before applying attribute mutations.`
9848
+ });
9849
+ }
9850
+ const existingNode = context.getElementByInstruction(declaration);
9851
+ if (existingNode) {
9852
+ existingNode.textContent = value;
9853
+ } else {
9854
+ const textNode = context.container.createTextNode(value);
9855
+ element.appendChild(textNode);
9856
+ context.setInstructionElement(declaration, textNode);
9857
+ }
9858
+ }
9859
+ logger?.debug("green", `Text ${node?.aseid.toString()} added to Context:`);
10109
9860
  }
10110
- update(attribute, store, scope, syntax, scene, ...args) {
10111
- attribute.value = syntax.evaluate(attribute.content, store);
10112
- if (attribute.value) {
10113
- attribute.template.scene.activate();
10114
- attribute.template.mount();
9861
+ removeText(declaration, context) {
9862
+ const element = context.getElementByInstruction(declaration);
9863
+ if (!element) return;
9864
+ element.parentNode?.removeChild(element);
9865
+ context.removeInstructionElement(declaration);
9866
+ }
9867
+ addComment(declaration, context, store, syntax, directiveContext, logger) {
9868
+ const node = declaration.owner.parent;
9869
+ const { content, evaluate } = declaration.payload;
9870
+ const rawValue = evaluate ? syntax.evaluate(content, store, {
9871
+ ...directiveContext?.scope || {}
9872
+ }) : content;
9873
+ const value = toDOMString(rawValue);
9874
+ if (!node) {
9875
+ const commentNode = context.container.createComment(value);
9876
+ context.container.body.appendChild(commentNode);
9877
+ context.setInstructionElement(declaration, commentNode);
10115
9878
  } else {
10116
- attribute.template.unmount();
10117
- attribute.template.scene.deactivate();
9879
+ const element = context.getNodeElement(node);
9880
+ if (!element) {
9881
+ throw new AreInterpreterError({
9882
+ title: "Element Not Found",
9883
+ description: `Could not find a DOM element associated with the instruction ASEID "${declaration.owner.parent.aseid}". Ensure that the parent instruction is properly rendered and associated with a DOM element before applying attribute mutations.`
9884
+ });
9885
+ }
9886
+ const existingNode = context.getElementByInstruction(declaration);
9887
+ if (existingNode) {
9888
+ existingNode.textContent = value;
9889
+ } else {
9890
+ const commentNode = context.container.createComment(value);
9891
+ element.appendChild(commentNode);
9892
+ context.setInstructionElement(declaration, commentNode);
9893
+ }
10118
9894
  }
9895
+ logger?.debug("green", `Comment ${node?.aseid.toString()} added to Context:`);
9896
+ }
9897
+ removeComment(declaration, context) {
9898
+ const element = context.getElementByInstruction(declaration);
9899
+ if (!element) return;
9900
+ element.parentNode?.removeChild(element);
9901
+ context.removeInstructionElement(declaration);
10119
9902
  }
10120
9903
  };
10121
- __name(AreDirectiveIf, "AreDirectiveIf");
9904
+ __name(AreHTMLInterpreter, "AreHTMLInterpreter");
10122
9905
  __decorateClass([
10123
- AreDirective.Transform,
9906
+ c2.Method({
9907
+ description: "Create an HTML element based on the provided declaration instruction. Handles both root-level mounting and child element creation based on the structural parent hierarchy."
9908
+ }),
9909
+ AreInterpreter.Apply(AreInstructionDefaultNames.Default),
9910
+ AreInterpreter.Apply(AreHTMLInstructions.AddElement),
10124
9911
  __decorateParam(0, ke(G)),
10125
- __decorateParam(1, ke(D)),
10126
- __decorateParam(2, ke(AreStore)),
10127
- __decorateParam(3, ke(AreScene)),
10128
- __decorateParam(4, ke(A_Logger))
10129
- ], AreDirectiveIf.prototype, "transform", 1);
9912
+ __decorateParam(1, ke(AreHTMLEngineContext)),
9913
+ __decorateParam(2, ke(A_Logger))
9914
+ ], AreHTMLInterpreter.prototype, "addElement", 1);
10130
9915
  __decorateClass([
10131
- AreDirective.Compile,
9916
+ c2.Method({
9917
+ description: "Remove an HTML element that was created by a CreateElement declaration. Cleans up the DOM and the context index."
9918
+ }),
9919
+ AreInterpreter.Revert(AreInstructionDefaultNames.Default),
9920
+ AreInterpreter.Revert(AreHTMLInstructions.AddElement),
10132
9921
  __decorateParam(0, ke(G)),
10133
- __decorateParam(1, ke(AreStore)),
10134
- __decorateParam(2, ke(AreScene)),
10135
- __decorateParam(3, ke(AreSyntax)),
10136
- __decorateParam(4, ke(AreDirectiveContext))
10137
- ], AreDirectiveIf.prototype, "compile", 1);
9922
+ __decorateParam(1, ke(AreHTMLEngineContext))
9923
+ ], AreHTMLInterpreter.prototype, "removeElement", 1);
10138
9924
  __decorateClass([
10139
- AreDirective.Update,
9925
+ c2.Method({
9926
+ description: "Add an attribute to an HTML element based on the provided mutation instruction."
9927
+ }),
9928
+ AreInterpreter.Apply(AreHTMLInstructions.AddAttribute),
9929
+ AreInterpreter.Update(AreHTMLInstructions.AddAttribute),
10140
9930
  __decorateParam(0, ke(G)),
10141
- __decorateParam(1, ke(AreStore)),
10142
- __decorateParam(2, ke(D)),
9931
+ __decorateParam(1, ke(AreHTMLEngineContext)),
9932
+ __decorateParam(2, ke(AreStore)),
10143
9933
  __decorateParam(3, ke(AreSyntax)),
10144
- __decorateParam(4, ke(AreScene))
10145
- ], AreDirectiveIf.prototype, "update", 1);
10146
- AreDirectiveIf = __decorateClass([
10147
- AreDirective.Priority(2)
10148
- ], AreDirectiveIf);
10149
-
10150
- // src/instructions/AddAttribute.instruction.ts
10151
- var AddAttributeInstruction = class extends AreMutation {
10152
- constructor(parent, props) {
10153
- if ("aseid" in props) {
10154
- super(props);
10155
- } else {
10156
- super(AreHTMLInstructions.AddAttribute, parent, props);
10157
- }
10158
- }
10159
- };
10160
- __name(AddAttributeInstruction, "AddAttributeInstruction");
10161
- AddAttributeInstruction = __decorateClass([
9934
+ __decorateParam(4, ke(AreDirectiveContext)),
9935
+ __decorateParam(5, ke(A_Logger))
9936
+ ], AreHTMLInterpreter.prototype, "addAttribute", 1);
9937
+ __decorateClass([
9938
+ c2.Method({
9939
+ description: "Remove an attribute from an HTML element based on the provided mutation instruction."
9940
+ }),
9941
+ AreInterpreter.Revert(AreHTMLInstructions.AddAttribute),
9942
+ __decorateParam(0, ke(G)),
9943
+ __decorateParam(1, ke(AreHTMLEngineContext))
9944
+ ], AreHTMLInterpreter.prototype, "removeAttribute", 1);
9945
+ __decorateClass([
9946
+ c2.Method({
9947
+ description: "Add an event listener to an HTML element based on the provided mutation instruction."
9948
+ }),
9949
+ AreInterpreter.Apply(AreHTMLInstructions.AddListener),
9950
+ __decorateParam(0, ke(G)),
9951
+ __decorateParam(1, ke(AreHTMLEngineContext)),
9952
+ __decorateParam(2, ke(AreStore)),
9953
+ __decorateParam(3, ke(AreSyntax)),
9954
+ __decorateParam(4, ke(AreDirectiveContext)),
9955
+ __decorateParam(5, ke(A_Logger))
9956
+ ], AreHTMLInterpreter.prototype, "addEventListener", 1);
9957
+ __decorateClass([
9958
+ c2.Method({
9959
+ description: "Remove an event listener from an HTML element based on the provided mutation instruction."
9960
+ }),
9961
+ AreInterpreter.Revert(AreHTMLInstructions.AddListener),
9962
+ __decorateParam(0, ke(G)),
9963
+ __decorateParam(1, ke(AreHTMLEngineContext))
9964
+ ], AreHTMLInterpreter.prototype, "removeEventListener", 1);
9965
+ __decorateClass([
9966
+ c2.Method({
9967
+ description: "Add text content to an HTML element based on the provided declaration instruction."
9968
+ }),
9969
+ AreInterpreter.Apply(AreHTMLInstructions.AddText),
9970
+ AreInterpreter.Update(AreHTMLInstructions.AddText),
9971
+ __decorateParam(0, ke(G)),
9972
+ __decorateParam(1, ke(AreHTMLEngineContext)),
9973
+ __decorateParam(2, ke(AreStore)),
9974
+ __decorateParam(3, ke(AreSyntax)),
9975
+ __decorateParam(4, ke(AreDirectiveContext)),
9976
+ __decorateParam(5, ke(A_Logger))
9977
+ ], AreHTMLInterpreter.prototype, "addText", 1);
9978
+ __decorateClass([
9979
+ c2.Method({
9980
+ description: "Remove text content from an HTML element based on the provided declaration instruction."
9981
+ }),
9982
+ AreInterpreter.Revert(AreHTMLInstructions.AddText),
9983
+ __decorateParam(0, ke(G)),
9984
+ __decorateParam(1, ke(AreHTMLEngineContext))
9985
+ ], AreHTMLInterpreter.prototype, "removeText", 1);
9986
+ __decorateClass([
9987
+ c2.Method({
9988
+ description: "Add a comment node to the DOM based on the provided declaration instruction."
9989
+ }),
9990
+ AreInterpreter.Apply(AreHTMLInstructions.AddComment),
9991
+ AreInterpreter.Update(AreHTMLInstructions.AddComment),
9992
+ __decorateParam(0, ke(G)),
9993
+ __decorateParam(1, ke(AreHTMLEngineContext)),
9994
+ __decorateParam(2, ke(AreStore)),
9995
+ __decorateParam(3, ke(AreSyntax)),
9996
+ __decorateParam(4, ke(AreDirectiveContext)),
9997
+ __decorateParam(5, ke(A_Logger))
9998
+ ], AreHTMLInterpreter.prototype, "addComment", 1);
9999
+ __decorateClass([
10000
+ c2.Method({
10001
+ description: "Remove a comment node from the DOM based on the provided declaration instruction."
10002
+ }),
10003
+ AreInterpreter.Revert(AreHTMLInstructions.AddComment),
10004
+ __decorateParam(0, ke(G)),
10005
+ __decorateParam(1, ke(AreHTMLEngineContext))
10006
+ ], AreHTMLInterpreter.prototype, "removeComment", 1);
10007
+ AreHTMLInterpreter = __decorateClass([
10162
10008
  c2.Component({
10163
10009
  namespace: "A-ARE",
10164
- name: "AddAttributeInstruction",
10165
- description: "Sets an attribute on an HTML element. Apply calls setAttribute; revert calls removeAttribute."
10010
+ name: "AreHTMLInterpreter",
10011
+ description: "AreHTMLInterpreter is a component that serves as a host for rendering AreNodes into HTML. It provides the necessary context and environment for AreNodes to be rendered and interact with the DOM."
10166
10012
  })
10167
- ], AddAttributeInstruction);
10013
+ ], AreHTMLInterpreter);
10168
10014
 
10169
- // src/instructions/AddListener.instruction.ts
10170
- var AddListenerInstruction = class extends AreMutation {
10171
- constructor(parent, props) {
10172
- if ("aseid" in props) {
10173
- super(props);
10174
- } else {
10175
- super(AreHTMLInstructions.AddListener, parent, props);
10176
- }
10015
+ // src/lib/AreHTMLAttribute/AreHTML.attribute.ts
10016
+ var _AreHTMLAttribute = class _AreHTMLAttribute extends AreAttribute {
10017
+ get owner() {
10018
+ return this.scope.issuer();
10177
10019
  }
10178
10020
  };
10179
- __name(AddListenerInstruction, "AddListenerInstruction");
10180
- AddListenerInstruction = __decorateClass([
10181
- c2.Component({
10182
- namespace: "A-ARE",
10183
- name: "AddListenerInstruction",
10184
- description: "Attaches a DOM event listener to an element. Apply calls addEventListener; revert calls removeEventListener."
10185
- })
10186
- ], AddListenerInstruction);
10021
+ __name(_AreHTMLAttribute, "AreHTMLAttribute");
10022
+ var AreHTMLAttribute = _AreHTMLAttribute;
10187
10023
 
10188
- // src/instructions/AddText.instruction.ts
10189
- var AddTextInstruction = class extends AreDeclaration {
10190
- constructor(props) {
10191
- if ("aseid" in props) {
10192
- super(props);
10193
- } else {
10194
- super(AreHTMLInstructions.AddText, props);
10195
- }
10024
+ // src/attributes/AreBinding.attribute.ts
10025
+ var _AreBindingAttribute = class _AreBindingAttribute extends AreHTMLAttribute {
10026
+ // get value(): string {
10027
+ // const [firstPart, ...pathPart] = this.content.split('.');
10028
+ // const primaryObject = this.owner.store.get(firstPart);
10029
+ // return AreCommonHelper.extractPropertyByPath(primaryObject, pathPart.join('.')) as string;
10030
+ // }
10031
+ };
10032
+ __name(_AreBindingAttribute, "AreBindingAttribute");
10033
+ var AreBindingAttribute = _AreBindingAttribute;
10034
+
10035
+ // src/attributes/AreDirective.attribute.ts
10036
+ var _AreDirectiveAttribute = class _AreDirectiveAttribute extends AreHTMLAttribute {
10037
+ /**
10038
+ * Returns a custom directive component associated with this attribute, if available.
10039
+ *
10040
+ * The method uses the attribute's name to resolve the corresponding directive component from the scope. It constructs the expected directive name by converting the attribute name to PascalCase and prefixing it with "AreDirective". If a matching directive component is found in the scope, it is returned; otherwise, the method returns undefined.
10041
+ */
10042
+ get component() {
10043
+ const component = this.scope.resolve(`AreDirective${h.toPascalCase(this.name)}`);
10044
+ return component;
10196
10045
  }
10197
10046
  };
10198
- __name(AddTextInstruction, "AddTextInstruction");
10199
- AddTextInstruction = __decorateClass([
10200
- c2.Component({
10201
- namespace: "A-ARE",
10202
- name: "AddTextInstruction",
10203
- description: "Appends a text node to an element. Apply creates the text node; revert removes it. Content can be a static string or a dynamic getter for interpolations."
10204
- })
10205
- ], AddTextInstruction);
10047
+ __name(_AreDirectiveAttribute, "AreDirectiveAttribute");
10048
+ var AreDirectiveAttribute = _AreDirectiveAttribute;
10049
+
10050
+ // src/attributes/AreEvent.attribute.ts
10051
+ var _AreEventAttribute = class _AreEventAttribute extends AreHTMLAttribute {
10052
+ };
10053
+ __name(_AreEventAttribute, "AreEventAttribute");
10054
+ var AreEventAttribute = _AreEventAttribute;
10055
+
10056
+ // src/attributes/AreStatic.attribute.ts
10057
+ var _AreStaticAttribute = class _AreStaticAttribute extends AreHTMLAttribute {
10058
+ };
10059
+ __name(_AreStaticAttribute, "AreStaticAttribute");
10060
+ var AreStaticAttribute = _AreStaticAttribute;
10206
10061
 
10207
10062
  // src/lib/AreStyle/AreStyle.context.ts
10208
10063
  var _AreStyle = class _AreStyle extends L {
@@ -10280,6 +10135,36 @@ AreHTMLNode = __decorateClass([
10280
10135
  })
10281
10136
  ], AreHTMLNode);
10282
10137
 
10138
+ // src/nodes/AreInterpolation.ts
10139
+ var _AreInterpolation = class _AreInterpolation extends AreHTMLNode {
10140
+ fromNew(newEntity) {
10141
+ super.fromNew({
10142
+ ...newEntity,
10143
+ payload: {
10144
+ ...newEntity.payload || {},
10145
+ entity: "are-interpolation"
10146
+ }
10147
+ });
10148
+ }
10149
+ };
10150
+ __name(_AreInterpolation, "AreInterpolation");
10151
+ var AreInterpolation = _AreInterpolation;
10152
+
10153
+ // src/nodes/AreText.ts
10154
+ var _AreText = class _AreText extends AreHTMLNode {
10155
+ fromNew(newEntity) {
10156
+ super.fromNew({
10157
+ ...newEntity,
10158
+ payload: {
10159
+ ...newEntity.payload || {},
10160
+ entity: "are-text"
10161
+ }
10162
+ });
10163
+ }
10164
+ };
10165
+ __name(_AreText, "AreText");
10166
+ var AreText = _AreText;
10167
+
10283
10168
  // src/nodes/AreComment.ts
10284
10169
  var _AreComment = class _AreComment extends AreHTMLNode {
10285
10170
  fromNew(newEntity) {
@@ -10317,21 +10202,6 @@ AreComponentNode = __decorateClass([
10317
10202
  })
10318
10203
  ], AreComponentNode);
10319
10204
 
10320
- // src/nodes/AreInterpolation.ts
10321
- var _AreInterpolation = class _AreInterpolation extends AreHTMLNode {
10322
- fromNew(newEntity) {
10323
- super.fromNew({
10324
- ...newEntity,
10325
- payload: {
10326
- ...newEntity.payload || {},
10327
- entity: "are-interpolation"
10328
- }
10329
- });
10330
- }
10331
- };
10332
- __name(_AreInterpolation, "AreInterpolation");
10333
- var AreInterpolation = _AreInterpolation;
10334
-
10335
10205
  // src/nodes/AreRoot.ts
10336
10206
  var AreRootNode = class extends AreHTMLNode {
10337
10207
  /**
@@ -10360,268 +10230,353 @@ AreRootNode = __decorateClass([
10360
10230
  })
10361
10231
  ], AreRootNode);
10362
10232
 
10363
- // src/nodes/AreText.ts
10364
- var _AreText = class _AreText extends AreHTMLNode {
10365
- fromNew(newEntity) {
10366
- super.fromNew({
10367
- ...newEntity,
10368
- payload: {
10369
- ...newEntity.payload || {},
10370
- entity: "are-text"
10371
- }
10372
- });
10233
+ // src/engine/AreHTML.tokenizer.ts
10234
+ var _AreHTMLTokenizer = class _AreHTMLTokenizer extends AreTokenizer {
10235
+ constructor() {
10236
+ super(...arguments);
10237
+ this.ATTR_PATTERN = /([$:@]?[\w.-]+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s>/"'=]+)))?/g;
10373
10238
  }
10374
- };
10375
- __name(_AreText, "AreText");
10376
- var AreText = _AreText;
10377
-
10378
- // src/engine/AreHTML.context.ts
10379
- var _AreHTMLEngineContext = class _AreHTMLEngineContext extends AreContext {
10380
- constructor(props) {
10381
- super(props.container?.body.innerHTML || props.source || "");
10382
- /**
10383
- * Index structure mapping:
10384
- *
10385
- * Node -> Group ID -> Element
10386
- * -----------------------------------------------------------------------------------
10387
- * | - Attribute | group: string | Node
10388
- * | - Directive (e.g. for) | | Node
10389
- */
10390
- this.index = {
10391
- /**
10392
- * 1 AreNode = 1 Dom Node
10393
- *
10394
- * uses ASEID
10395
- */
10396
- nodeToHostElements: /* @__PURE__ */ new Map(),
10397
- /**
10398
- * 1 Group Instruction = MANY Dom Nodes (e.g. for loop)
10399
- *
10400
- * uses ASEID
10401
- */
10402
- groupToElements: /* @__PURE__ */ new Map(),
10403
- /**
10404
- * 1 Dom Node = 1 Instruction
10405
- *
10406
- * uses ASEID
10407
- */
10408
- elementToInstruction: /* @__PURE__ */ new WeakMap(),
10409
- /**
10410
- * 1 Instruction = 1 Dom Node (for CreateElement instructions, for example)
10411
- *
10412
- * uses ASEID
10413
- */
10414
- instructionToElement: /* @__PURE__ */ new Map(),
10415
- /**
10416
- * Event listeners attached to elements, used for proper cleanup when reverting instructions. Maps a DOM element to a map of event names and their corresponding listeners, allowing the engine to track which listeners are attached to which elements and remove them when necessary (e.g., when an instruction is reverted).
10417
- */
10418
- elementListeners: /* @__PURE__ */ new WeakMap()
10419
- };
10420
- this._container = props.container;
10421
- }
10422
- get container() {
10423
- return this._container;
10424
- }
10425
- getNodeElement(node) {
10426
- if (typeof node === "string") {
10427
- return this.index.nodeToHostElements.get(node);
10428
- } else {
10429
- return this.index.nodeToHostElements.get(node.aseid.toString());
10430
- }
10431
- }
10432
- /**
10433
- * Associates a DOM element with a given instruction and its owner node. This method updates the context's index to map the instruction's ASEID to the provided DOM element, and also maps the element back to the instruction's ASEID for reverse lookup. If the instruction has an owner node, it also maps the node's ASEID to the element. Additionally, if the instruction belongs to a group, it adds the element to the set of elements associated with that group. This indexing allows the engine to efficiently manage and update DOM elements based on instructions and their corresponding nodes, enabling dynamic rendering and interaction in response to application state changes.
10434
- *
10435
- * @param instruction
10436
- * @param element
10437
- */
10438
- setInstructionElement(instruction, element) {
10439
- const node = instruction.owner;
10440
- this.index.instructionToElement.set(instruction.aseid.toString(), element);
10441
- this.index.elementToInstruction.set(element, instruction.aseid.toString());
10442
- if (node) {
10443
- this.index.nodeToHostElements.set(node.aseid.toString(), element);
10444
- }
10445
- if (instruction.group) {
10446
- const groupId = instruction.group;
10447
- if (!this.index.groupToElements.has(groupId)) {
10448
- this.index.groupToElements.set(groupId, /* @__PURE__ */ new Set());
10449
- }
10450
- this.index.groupToElements.get(groupId).add(element);
10451
- }
10452
- }
10453
- getElementByInstruction(instruction) {
10454
- if (typeof instruction === "string") {
10455
- return this.index.instructionToElement.get(instruction);
10456
- } else {
10457
- return this.index.instructionToElement.get(instruction.aseid.toString());
10239
+ tokenize(node, context, logger) {
10240
+ super.tokenize(node, context, logger);
10241
+ context.startPerformance("attributeExtraction");
10242
+ const attributes = this.extractAttributes(node.markup);
10243
+ for (const attr of attributes) {
10244
+ node.scope.register(attr);
10458
10245
  }
10246
+ context.endPerformance("attributeExtraction");
10459
10247
  }
10460
- /**
10461
- * Removes the association between a given instruction and its corresponding DOM element. This method looks up the instruction's ASEID to find the associated DOM element, and if found, it deletes the mapping from both instructionToElement and elementToInstruction. If the instruction has an owner node, it also removes the mapping from nodeToHostElements. Additionally, if the instruction belongs to a group, it removes the element from the set of elements associated with that group, and if the group has no more elements, it deletes the group from the index. This cleanup is essential for maintaining an accurate and efficient mapping of instructions to DOM elements, especially when instructions are reverted or when nodes are removed from the DOM.
10462
- *
10463
- * @param instruction
10464
- */
10465
- removeInstructionElement(instruction) {
10466
- const element = this.index.instructionToElement.get(instruction.aseid.toString());
10467
- if (element) {
10468
- this.index.instructionToElement.delete(instruction.aseid.toString());
10469
- this.index.elementToInstruction.delete(element);
10470
- const node = instruction.owner;
10471
- if (node) {
10472
- this.index.nodeToHostElements.delete(node.aseid.toString());
10473
- }
10474
- if (instruction.group) {
10475
- const groupId = instruction.group;
10476
- const groupElements = this.index.groupToElements.get(groupId);
10477
- if (groupElements) {
10478
- groupElements.delete(element);
10479
- if (groupElements.size === 0) {
10480
- this.index.groupToElements.delete(groupId);
10481
- }
10482
- }
10248
+ extractAttributes(markup) {
10249
+ const withoutTag = markup.replace(/^<[a-zA-Z][a-zA-Z0-9-]*\s*/, "");
10250
+ let inSingle = false;
10251
+ let inDouble = false;
10252
+ let endIdx = withoutTag.length;
10253
+ for (let i = 0; i < withoutTag.length; i++) {
10254
+ const ch = withoutTag[i];
10255
+ if (ch === '"' && !inSingle) inDouble = !inDouble;
10256
+ else if (ch === "'" && !inDouble) inSingle = !inSingle;
10257
+ else if (ch === ">" && !inSingle && !inDouble) {
10258
+ endIdx = i;
10259
+ break;
10483
10260
  }
10484
10261
  }
10485
- }
10486
- getElementsByGroup(instruction) {
10487
- if (typeof instruction === "string") {
10488
- return this.index.groupToElements.get(instruction);
10489
- } else {
10490
- return this.index.groupToElements.get(instruction.aseid.toString());
10262
+ const attrString = withoutTag.slice(0, endIdx).replace(/\s*\/?\s*$/, "").trim();
10263
+ const results = [];
10264
+ for (const match of attrString.matchAll(this.ATTR_PATTERN)) {
10265
+ const raw = match[0];
10266
+ const full = match[1];
10267
+ if (!full) continue;
10268
+ const value = match[2] ?? match[3] ?? match[4] ?? "true";
10269
+ const prefix = full[0];
10270
+ const isSpecial = prefix === ":" || prefix === "@" || prefix === "$";
10271
+ const name = isSpecial ? full.slice(1) : full;
10272
+ const meta = { name, content: value, raw, prefix: isSpecial ? prefix : "" };
10273
+ if (prefix === ":") results.push(new AreBindingAttribute(meta));
10274
+ else if (prefix === "@") results.push(new AreEventAttribute(meta));
10275
+ else if (prefix === "$") results.push(new AreDirectiveAttribute(meta));
10276
+ else results.push(new AreStaticAttribute(meta));
10491
10277
  }
10278
+ return results;
10492
10279
  }
10280
+ };
10281
+ __name(_AreHTMLTokenizer, "AreHTMLTokenizer");
10282
+ __decorateClass([
10283
+ w.Extend({
10284
+ name: AreNodeFeatures.onTokenize,
10285
+ scope: [AreComponentNode, AreRootNode]
10286
+ }),
10287
+ __decorateParam(0, ke(G)),
10288
+ __decorateParam(1, ke(AreContext)),
10289
+ __decorateParam(2, ke(A_Logger))
10290
+ ], _AreHTMLTokenizer.prototype, "tokenize", 1);
10291
+ var AreHTMLTokenizer = _AreHTMLTokenizer;
10292
+
10293
+ // src/lib/AreDirective/AreDirective.constants.ts
10294
+ var AreDirectiveFeatures = {
10493
10295
  /**
10494
- * Adds an event listener to a specific DOM element and keeps track of it in the context's index for proper cleanup later. This method takes a DOM element, an event name, and a listener function or object, and stores this information in the elementListeners map. This allows the engine to efficiently manage event listeners attached to dynamically created elements, ensuring that they can be removed when the associated instructions are reverted or when nodes are removed from the DOM, preventing memory leaks and unintended behavior.
10495
- *
10496
- * @param element
10497
- * @param eventName
10498
- * @param listener
10296
+ * Feature that should transform the tree based on the directive attribute. This method is called during the transformation phase of the ARE component and should perform any necessary transformations on the AreNode tree based on the directive's content and context. This can include tasks such as adding or removing nodes, modifying node properties, or restructuring the tree to ensure that the directive is applied correctly during rendering.
10499
10297
  */
10500
- addListener(element, eventName, listener) {
10501
- if (!this.index.elementListeners.has(element)) {
10502
- this.index.elementListeners.set(element, /* @__PURE__ */ new Map());
10503
- }
10504
- this.index.elementListeners.get(element).set(eventName, listener);
10505
- }
10298
+ Transform: "_AreDirective_Transform",
10506
10299
  /**
10507
- * Retrieves the event listener associated with a specific DOM element and event name from the context's index. This method looks up the element in the elementListeners map and then retrieves the listener for the specified event name. If no listener is found for the given element and event, it returns undefined. This allows the engine to efficiently access and manage event listeners that have been attached to dynamically created elements, enabling proper cleanup when instructions are reverted or when nodes are removed from the DOM.
10508
- *
10509
- * @param element
10510
- * @param eventName
10511
- * @returns
10300
+ * Feature that should convert a directiveAttribute definition into a set of SceneInstructions to be rendered correctly
10512
10301
  */
10513
- getListener(element, eventName) {
10514
- return this.index.elementListeners.get(element)?.get(eventName);
10515
- }
10302
+ Compile: "_AreDirective_Compile",
10516
10303
  /**
10517
- * Removes an event listener from a specific DOM element and updates the context's index accordingly. This method looks up the element in the elementListeners map and deletes the listener for the specified event name. This is typically called when an instruction is reverted or when a node is removed from the DOM, ensuring that any attached event listeners are properly cleaned up to prevent memory leaks and unintended behavior.
10518
- *
10519
- * @param element
10520
- * @param eventName
10304
+ * Feature that should update the directiveAttribute based on the changes in the store or other dependencies.
10521
10305
  */
10522
- removeListener(element, eventName) {
10523
- this.index.elementListeners.get(element)?.delete(eventName);
10524
- }
10306
+ Update: "_AreDirective_Update"
10525
10307
  };
10526
- __name(_AreHTMLEngineContext, "AreHTMLEngineContext");
10527
- var AreHTMLEngineContext = _AreHTMLEngineContext;
10528
10308
 
10529
- // src/engine/AreHTML.compiler.ts
10530
- var AreHTMLCompiler = class extends AreCompiler {
10531
- compileInterpolation(interpolation, scene, store, logger, ...args) {
10532
- scene.plan(new AddTextInstruction({ content: interpolation.content, evaluate: true }));
10309
+ // src/engine/AreHTML.lifecycle.ts
10310
+ var _AreHTMLLifecycle = class _AreHTMLLifecycle extends AreLifecycle {
10311
+ initComponent(node, scope, context, logger, ...args) {
10312
+ super.init(node, scope, context, logger, ...args);
10533
10313
  }
10534
- compileText(text, scene, logger, ...args) {
10535
- logger?.debug("cyan", `AreHTMLCompiler: compile text node <${text.aseid.toString()}> with content: "${text.content}"`);
10536
- if (scene.host)
10537
- scene.unPlan(scene.host);
10538
- scene.plan(new AddTextInstruction({ content: text.content }));
10314
+ initRoot(node, scope, context, signalsContext, logger, ...args) {
10315
+ signalsContext?.subscribe(node);
10316
+ super.init(node, scope, context, logger, ...args);
10539
10317
  }
10540
- compileStaticAttribute(attribute, scene, ...args) {
10541
- if (!scene.host)
10542
- throw new AreCompilerError({
10543
- title: "Scene Host Not Found",
10544
- description: `No host found for the scene with id: ${scene.id}. Please ensure that the scene is properly initialized and has a host before compiling binding attributes.`
10545
- });
10546
- scene.plan(new AddAttributeInstruction(scene.host, {
10547
- name: attribute.name,
10548
- content: attribute.content
10549
- }));
10318
+ initText(node, scope, context, logger, ...args) {
10319
+ const scene = new AreScene(node.aseid);
10320
+ scope.register(scene);
10550
10321
  }
10551
- compileDirectiveAttribute(directive, store, feature, logger, ...args) {
10552
- store.watch(directive);
10322
+ initInterpolation(node, scope, context, logger, ...args) {
10323
+ const scene = new AreScene(node.aseid);
10324
+ scope.register(scene);
10325
+ }
10326
+ updateDirectiveAttribute(directive, scope, feature, logger, ...args) {
10553
10327
  if (directive.component) {
10554
- feature.chain(directive.component, AreDirectiveFeatures.Compile, directive.owner.scope);
10328
+ feature.chain(directive.component, AreDirectiveFeatures.Update, directive.owner.scope);
10555
10329
  } else {
10556
10330
  logger?.warning(`Directive handler component not found for directive: ${directive.name}. Make sure to create a component named "AreDirective${h.toPascalCase(directive.name)}" to handle this directive.`);
10557
10331
  }
10558
- store.unwatch(directive);
10559
- }
10560
- compileEventAttribute(attribute, scene, ...args) {
10561
- if (!scene.host)
10562
- throw new AreCompilerError({
10563
- title: "Scene Host Not Found",
10564
- description: `No host found for the scene with id: ${scene.id}. Please ensure that the scene is properly initialized and has a host before compiling binding attributes.`
10565
- });
10566
- scene.plan(new AddListenerInstruction(scene.host, {
10567
- name: attribute.name,
10568
- handler: attribute.content
10569
- }));
10570
- }
10571
- compileBindingAttribute(attribute, scene, parentStore, store, ...args) {
10572
- if (!scene.host)
10573
- throw new AreCompilerError({
10574
- title: "Scene Host Not Found",
10575
- description: `No host found for the scene with id: ${scene.id}. Please ensure that the scene is properly initialized and has a host before compiling binding attributes.`
10576
- });
10577
- const node = attribute.owner;
10578
- if (node.component && node.component.props[attribute.name]) {
10579
- const propDefinition = node.component.props[attribute.name];
10580
- let value = parentStore.get(attribute.content);
10581
- if (propDefinition.type) {
10582
- switch (propDefinition.type) {
10583
- case "string":
10584
- value = String(value);
10585
- break;
10586
- case "number":
10587
- value = Number(value);
10588
- break;
10589
- case "boolean":
10590
- value = Boolean(value);
10591
- break;
10592
- default:
10593
- break;
10594
- }
10595
- }
10596
- store.set(attribute.name, value);
10597
- } else {
10598
- const instruction = new AddAttributeInstruction(scene.host, {
10599
- name: attribute.name,
10600
- content: attribute.content,
10601
- evaluate: true
10602
- });
10603
- scene.plan(instruction);
10604
- }
10605
10332
  }
10606
10333
  };
10607
- __name(AreHTMLCompiler, "AreHTMLCompiler");
10334
+ __name(_AreHTMLLifecycle, "AreHTMLLifecycle");
10608
10335
  __decorateClass([
10609
- AreCompiler.Compile(AreInterpolation),
10336
+ AreLifecycle.Init(AreComponentNode),
10610
10337
  __decorateParam(0, ke(G)),
10611
- __decorateParam(1, ke(AreScene)),
10612
- __decorateParam(2, ke(AreStore)),
10338
+ __decorateParam(1, ke(D)),
10339
+ __decorateParam(2, ke(AreHTMLEngineContext)),
10613
10340
  __decorateParam(3, ke(A_Logger))
10614
- ], AreHTMLCompiler.prototype, "compileInterpolation", 1);
10341
+ ], _AreHTMLLifecycle.prototype, "initComponent", 1);
10615
10342
  __decorateClass([
10616
- AreCompiler.Compile(AreText),
10343
+ AreLifecycle.Init(AreRootNode),
10617
10344
  __decorateParam(0, ke(G)),
10618
- __decorateParam(1, ke(AreScene)),
10619
- __decorateParam(2, ke(A_Logger))
10620
- ], AreHTMLCompiler.prototype, "compileText", 1);
10345
+ __decorateParam(1, ke(D)),
10346
+ __decorateParam(2, ke(AreHTMLEngineContext)),
10347
+ __decorateParam(3, ke(AreSignalsContext)),
10348
+ __decorateParam(4, ke(A_Logger))
10349
+ ], _AreHTMLLifecycle.prototype, "initRoot", 1);
10621
10350
  __decorateClass([
10622
- AreCompiler.Compile(AreStaticAttribute),
10351
+ AreLifecycle.Init(AreText),
10623
10352
  __decorateParam(0, ke(G)),
10624
- __decorateParam(1, ke(AreScene))
10353
+ __decorateParam(1, ke(D)),
10354
+ __decorateParam(2, ke(AreHTMLEngineContext)),
10355
+ __decorateParam(3, ke(A_Logger))
10356
+ ], _AreHTMLLifecycle.prototype, "initText", 1);
10357
+ __decorateClass([
10358
+ AreLifecycle.Init(AreInterpolation),
10359
+ __decorateParam(0, ke(G)),
10360
+ __decorateParam(1, ke(D)),
10361
+ __decorateParam(2, ke(AreHTMLEngineContext)),
10362
+ __decorateParam(3, ke(A_Logger))
10363
+ ], _AreHTMLLifecycle.prototype, "initInterpolation", 1);
10364
+ __decorateClass([
10365
+ w.Extend({
10366
+ name: AreAttributeFeatures.Update,
10367
+ scope: [AreDirectiveAttribute]
10368
+ }),
10369
+ __decorateParam(0, ke(G)),
10370
+ __decorateParam(1, ke(D)),
10371
+ __decorateParam(2, ke(w)),
10372
+ __decorateParam(3, ke(A_Logger))
10373
+ ], _AreHTMLLifecycle.prototype, "updateDirectiveAttribute", 1);
10374
+ var AreHTMLLifecycle = _AreHTMLLifecycle;
10375
+
10376
+ // src/engine/AreHTML.transformer.ts
10377
+ var _AreHTMLTransformer = class _AreHTMLTransformer extends AreTransformer {
10378
+ transformDirectiveAttribute(directive, store, feature, logger, ...args) {
10379
+ store.watch(directive);
10380
+ if (directive.component) {
10381
+ feature.chain(directive.component, AreDirectiveFeatures.Transform, directive.owner.scope);
10382
+ } else {
10383
+ logger?.warning(`Directive handler component not found for directive: ${directive.name}. Make sure to create a component named "AreDirective${h.toPascalCase(directive.name)}" to handle this directive.`);
10384
+ }
10385
+ store.unwatch(directive);
10386
+ }
10387
+ };
10388
+ __name(_AreHTMLTransformer, "AreHTMLTransformer");
10389
+ __decorateClass([
10390
+ w.Extend({
10391
+ name: AreAttributeFeatures.Transform,
10392
+ scope: [AreDirectiveAttribute]
10393
+ }),
10394
+ __decorateParam(0, ke(G)),
10395
+ __decorateParam(1, ke(AreStore)),
10396
+ __decorateParam(2, ke(w)),
10397
+ __decorateParam(3, ke(A_Logger))
10398
+ ], _AreHTMLTransformer.prototype, "transformDirectiveAttribute", 1);
10399
+ var AreHTMLTransformer = _AreHTMLTransformer;
10400
+
10401
+ // src/instructions/AddAttribute.instruction.ts
10402
+ var AddAttributeInstruction = class extends AreMutation {
10403
+ constructor(parent, props) {
10404
+ if ("aseid" in props) {
10405
+ super(props);
10406
+ } else {
10407
+ super(AreHTMLInstructions.AddAttribute, parent, props);
10408
+ }
10409
+ }
10410
+ };
10411
+ __name(AddAttributeInstruction, "AddAttributeInstruction");
10412
+ AddAttributeInstruction = __decorateClass([
10413
+ c2.Component({
10414
+ namespace: "A-ARE",
10415
+ name: "AddAttributeInstruction",
10416
+ description: "Sets an attribute on an HTML element. Apply calls setAttribute; revert calls removeAttribute."
10417
+ })
10418
+ ], AddAttributeInstruction);
10419
+
10420
+ // src/instructions/AddText.instruction.ts
10421
+ var AddTextInstruction = class extends AreDeclaration {
10422
+ constructor(props) {
10423
+ if ("aseid" in props) {
10424
+ super(props);
10425
+ } else {
10426
+ super(AreHTMLInstructions.AddText, props);
10427
+ }
10428
+ }
10429
+ };
10430
+ __name(AddTextInstruction, "AddTextInstruction");
10431
+ AddTextInstruction = __decorateClass([
10432
+ c2.Component({
10433
+ namespace: "A-ARE",
10434
+ name: "AddTextInstruction",
10435
+ description: "Appends a text node to an element. Apply creates the text node; revert removes it. Content can be a static string or a dynamic getter for interpolations."
10436
+ })
10437
+ ], AddTextInstruction);
10438
+
10439
+ // src/instructions/AddListener.instruction.ts
10440
+ var AddListenerInstruction = class extends AreMutation {
10441
+ constructor(parent, props) {
10442
+ if ("aseid" in props) {
10443
+ super(props);
10444
+ } else {
10445
+ super(AreHTMLInstructions.AddListener, parent, props);
10446
+ }
10447
+ }
10448
+ };
10449
+ __name(AddListenerInstruction, "AddListenerInstruction");
10450
+ AddListenerInstruction = __decorateClass([
10451
+ c2.Component({
10452
+ namespace: "A-ARE",
10453
+ name: "AddListenerInstruction",
10454
+ description: "Attaches a DOM event listener to an element. Apply calls addEventListener; revert calls removeEventListener."
10455
+ })
10456
+ ], AddListenerInstruction);
10457
+
10458
+ // src/engine/AreHTML.compiler.ts
10459
+ var AreHTMLCompiler = class extends AreCompiler {
10460
+ compileInterpolation(interpolation, scene, store, logger, ...args) {
10461
+ scene.plan(new AddTextInstruction({ content: interpolation.content, evaluate: true }));
10462
+ }
10463
+ compileText(text, scene, logger, ...args) {
10464
+ logger?.debug("cyan", `AreHTMLCompiler: compile text node <${text.aseid.toString()}> with content: "${text.content}"`);
10465
+ if (scene.host)
10466
+ scene.unPlan(scene.host);
10467
+ scene.plan(new AddTextInstruction({ content: text.content }));
10468
+ }
10469
+ compileStaticAttribute(attribute, scene, ...args) {
10470
+ if (!scene.host)
10471
+ throw new AreCompilerError({
10472
+ title: "Scene Host Not Found",
10473
+ description: `No host found for the scene with id: ${scene.id}. Please ensure that the scene is properly initialized and has a host before compiling binding attributes.`
10474
+ });
10475
+ scene.plan(new AddAttributeInstruction(scene.host, {
10476
+ name: attribute.name,
10477
+ content: attribute.content
10478
+ }));
10479
+ }
10480
+ compileDirectiveAttribute(directive, store, feature, logger, ...args) {
10481
+ store.watch(directive);
10482
+ if (directive.component) {
10483
+ feature.chain(directive.component, AreDirectiveFeatures.Compile, directive.owner.scope);
10484
+ } else {
10485
+ logger?.warning(`Directive handler component not found for directive: ${directive.name}. Make sure to create a component named "AreDirective${h.toPascalCase(directive.name)}" to handle this directive.`);
10486
+ }
10487
+ store.unwatch(directive);
10488
+ }
10489
+ compileEventAttribute(attribute, scene, ...args) {
10490
+ if (!scene.host)
10491
+ throw new AreCompilerError({
10492
+ title: "Scene Host Not Found",
10493
+ description: `No host found for the scene with id: ${scene.id}. Please ensure that the scene is properly initialized and has a host before compiling binding attributes.`
10494
+ });
10495
+ scene.plan(new AddListenerInstruction(scene.host, {
10496
+ name: attribute.name,
10497
+ handler: attribute.content
10498
+ }));
10499
+ }
10500
+ compileBindingAttribute(attribute, scene, parentStore, store, syntax, ...args) {
10501
+ if (!scene.host)
10502
+ throw new AreCompilerError({
10503
+ title: "Scene Host Not Found",
10504
+ description: `No host found for the scene with id: ${scene.id}. Please ensure that the scene is properly initialized and has a host before compiling binding attributes.`
10505
+ });
10506
+ const node = attribute.owner;
10507
+ const props = node.component?.props;
10508
+ let propName;
10509
+ if (props) {
10510
+ if (props[attribute.name]) {
10511
+ propName = attribute.name;
10512
+ } else {
10513
+ const camel = h.toCamelCase(attribute.name);
10514
+ if (props[camel]) propName = camel;
10515
+ }
10516
+ }
10517
+ if (propName && props) {
10518
+ const propDefinition = props[propName];
10519
+ const coerce = /* @__PURE__ */ __name((raw) => {
10520
+ let value = raw;
10521
+ if (propDefinition.type) {
10522
+ switch (propDefinition.type) {
10523
+ case "string":
10524
+ value = value === void 0 || value === null ? "" : String(value);
10525
+ break;
10526
+ case "number":
10527
+ value = Number(value);
10528
+ break;
10529
+ case "boolean":
10530
+ value = Boolean(value);
10531
+ break;
10532
+ }
10533
+ }
10534
+ return value;
10535
+ }, "coerce");
10536
+ const watcher = {
10537
+ update: /* @__PURE__ */ __name(() => {
10538
+ try {
10539
+ parentStore.watch(watcher);
10540
+ const next = coerce(syntax.evaluate(attribute.content, parentStore));
10541
+ parentStore.unwatch(watcher);
10542
+ store.set(propName, next);
10543
+ } catch (e) {
10544
+ parentStore.unwatch(watcher);
10545
+ }
10546
+ }, "update")
10547
+ };
10548
+ parentStore.watch(watcher);
10549
+ const initial = coerce(syntax.evaluate(attribute.content, parentStore));
10550
+ parentStore.unwatch(watcher);
10551
+ store.set(propName, initial);
10552
+ return;
10553
+ }
10554
+ const instruction = new AddAttributeInstruction(scene.host, {
10555
+ name: attribute.name,
10556
+ content: attribute.content,
10557
+ evaluate: true
10558
+ });
10559
+ scene.plan(instruction);
10560
+ }
10561
+ };
10562
+ __name(AreHTMLCompiler, "AreHTMLCompiler");
10563
+ __decorateClass([
10564
+ AreCompiler.Compile(AreInterpolation),
10565
+ __decorateParam(0, ke(G)),
10566
+ __decorateParam(1, ke(AreScene)),
10567
+ __decorateParam(2, ke(AreStore)),
10568
+ __decorateParam(3, ke(A_Logger))
10569
+ ], AreHTMLCompiler.prototype, "compileInterpolation", 1);
10570
+ __decorateClass([
10571
+ AreCompiler.Compile(AreText),
10572
+ __decorateParam(0, ke(G)),
10573
+ __decorateParam(1, ke(AreScene)),
10574
+ __decorateParam(2, ke(A_Logger))
10575
+ ], AreHTMLCompiler.prototype, "compileText", 1);
10576
+ __decorateClass([
10577
+ AreCompiler.Compile(AreStaticAttribute),
10578
+ __decorateParam(0, ke(G)),
10579
+ __decorateParam(1, ke(AreScene))
10625
10580
  ], AreHTMLCompiler.prototype, "compileStaticAttribute", 1);
10626
10581
  __decorateClass([
10627
10582
  AreCompiler.Compile(AreDirectiveAttribute),
@@ -10641,7 +10596,8 @@ __decorateClass([
10641
10596
  __decorateParam(1, ke(AreScene)),
10642
10597
  __decorateParam(2, F.Parent()),
10643
10598
  __decorateParam(2, ke(AreStore)),
10644
- __decorateParam(3, ke(AreStore))
10599
+ __decorateParam(3, ke(AreStore)),
10600
+ __decorateParam(4, ke(AreSyntax))
10645
10601
  ], AreHTMLCompiler.prototype, "compileBindingAttribute", 1);
10646
10602
  AreHTMLCompiler = __decorateClass([
10647
10603
  c2.Component({
@@ -10651,781 +10607,766 @@ AreHTMLCompiler = __decorateClass([
10651
10607
  })
10652
10608
  ], AreHTMLCompiler);
10653
10609
 
10654
- // src/engine/AreHTML.interpreter.ts
10655
- var AreHTMLInterpreter = class extends AreInterpreter {
10656
- addElement(declaration, context, logger) {
10657
- try {
10658
- const node = declaration.owner;
10659
- let currentNode = node;
10660
- let parent = node.parent;
10661
- while (parent) {
10662
- if (context.getNodeElement(parent)) {
10663
- break;
10664
- }
10665
- currentNode = parent;
10666
- parent = parent.parent;
10667
- }
10668
- const tag = node.tag;
10669
- if (parent) {
10670
- const mountPoint = context.getNodeElement(parent);
10671
- if (!mountPoint) {
10672
- throw new AreInterpreterError({
10673
- title: "Mount Point Not Found",
10674
- description: `Could not find a mount point for the node with id "${node.id}". Ensure that the parent node is rendered before its children, or that a valid root element with the corresponding id exists in the DOM.`
10675
- });
10676
- }
10677
- const element = context.container.createElement(tag);
10678
- if (mountPoint.nodeType === Node.ELEMENT_NODE) {
10679
- mountPoint.appendChild(element);
10680
- } else {
10681
- mountPoint.parentNode?.insertBefore(element, mountPoint);
10610
+ // src/engine/AreHTML.engine.ts
10611
+ var AreHTMLEngine = class extends AreEngine {
10612
+ get DefaultSyntax() {
10613
+ return new AreSyntax({
10614
+ trimWhitespace: true,
10615
+ strictMode: true,
10616
+ rules: [
10617
+ // HTML comments
10618
+ {
10619
+ opening: "<!--",
10620
+ closing: "-->",
10621
+ component: AreComment,
10622
+ priority: 10,
10623
+ nested: false,
10624
+ extract: /* @__PURE__ */ __name((raw) => ({ content: raw.slice(4, -3).trim() }), "extract")
10625
+ },
10626
+ // interpolations
10627
+ {
10628
+ opening: "{{",
10629
+ closing: "}}",
10630
+ component: AreInterpolation,
10631
+ priority: 9,
10632
+ nested: false,
10633
+ extract: /* @__PURE__ */ __name((_, match) => ({ key: match.content }), "extract")
10634
+ },
10635
+ // are-root — matched before generic elements, produces AreRootNode
10636
+ {
10637
+ matcher: this.rootElementMatcher.bind(this),
10638
+ component: AreRootNode,
10639
+ priority: 5
10640
+ },
10641
+ // generic HTML elements
10642
+ {
10643
+ matcher: this.htmlElementMatcher.bind(this),
10644
+ component: AreComponentNode,
10645
+ priority: 4
10646
+ },
10647
+ // plain text fallback
10648
+ {
10649
+ component: AreText,
10650
+ priority: 0
10682
10651
  }
10683
- context.setInstructionElement(declaration, element);
10684
- } else {
10685
- const mountPoint = context.container.getElementById(node.id);
10686
- if (!mountPoint) {
10687
- throw new AreInterpreterError({
10688
- title: "Mount Point Not Found",
10689
- description: `Could not find a mount point for the node with id "${node.id}". Ensure that the parent node is rendered before its children, or that a valid root element with the corresponding id exists in the DOM.`
10690
- });
10691
- }
10692
- const element = context.container.createElement(tag);
10693
- element.setAttribute("data-aseid", node.aseid.toString());
10694
- mountPoint.parentNode?.replaceChild(element, mountPoint);
10695
- context.setInstructionElement(declaration, element);
10696
- }
10697
- logger?.debug("green", `Element ${node.aseid.toString()} added to Context:`);
10698
- } catch (error) {
10699
- logger?.error(error);
10700
- throw error;
10701
- }
10652
+ ]
10653
+ });
10702
10654
  }
10703
- removeElement(declaration, context) {
10704
- const element = context.getElementByInstruction(declaration);
10705
- if (element && element.parentNode) {
10706
- element.parentNode.removeChild(element);
10707
- }
10708
- context.removeInstructionElement(declaration);
10655
+ async init(scope) {
10656
+ this.package(scope, {
10657
+ context: new AreHTMLEngineContext({}),
10658
+ syntax: this.DefaultSyntax,
10659
+ compiler: AreHTMLCompiler,
10660
+ interpreter: AreHTMLInterpreter,
10661
+ tokenizer: AreHTMLTokenizer,
10662
+ lifecycle: AreHTMLLifecycle,
10663
+ transformer: AreHTMLTransformer
10664
+ });
10709
10665
  }
10710
- addAttribute(mutation, context, store, syntax, directiveContext, logger) {
10711
- const element = context.getElementByInstruction(mutation.parent);
10712
- if (!element) {
10713
- throw new AreInterpreterError({
10714
- title: "Element Not Found",
10715
- description: `Could not find a DOM element associated with the instruction ASEID "${mutation.parent}". Ensure that the parent instruction is properly rendered and associated with a DOM element before applying attribute mutations.`
10716
- });
10717
- }
10718
- const { name, content, evaluate } = mutation.payload;
10719
- const value = evaluate ? syntax.evaluate(content, store, {
10720
- ...directiveContext?.scope || {}
10721
- }) : content;
10722
- if (mutation.cache === void 0) {
10723
- const existingValue = element.getAttribute(name);
10724
- const result = existingValue ? `${existingValue} ${value}` : value;
10725
- element.setAttribute(name, result);
10726
- mutation.cache = value;
10727
- } else {
10728
- const existingValue = element.getAttribute(name);
10729
- const existingParts = existingValue ? existingValue.split(/\s+/).filter(Boolean) : [];
10730
- const oldParts = new Set(mutation.cache.split(/\s+/).filter(Boolean));
10731
- const newParts = value ? value.split(/\s+/).filter(Boolean) : [];
10732
- const result = [...existingParts.filter((part) => !oldParts.has(part)), ...newParts].join(" ");
10733
- element.setAttribute(name, result);
10734
- mutation.cache = value;
10735
- }
10666
+ rootElementMatcher(source, from, to, build) {
10667
+ const rootTag = "are-root";
10668
+ const tagStart = source.indexOf("<", from);
10669
+ if (tagStart === -1 || tagStart >= to) return null;
10670
+ const tagNameMatch = source.slice(tagStart).match(/^<([a-zA-Z][a-zA-Z0-9-]*)/);
10671
+ if (!tagNameMatch || tagNameMatch[1].toLowerCase() !== rootTag) return null;
10672
+ return this.htmlElementMatcher(source, from, to, build);
10736
10673
  }
10737
- removeAttribute(mutation, context) {
10738
- try {
10739
- const element = context.getElementByInstruction(mutation.parent);
10740
- if (!element) return;
10741
- const { name } = mutation.payload;
10742
- if (name && element.nodeType === Node.ELEMENT_NODE) {
10743
- element?.removeAttribute(name);
10674
+ htmlElementMatcher(source, from, to, build) {
10675
+ let index = from;
10676
+ while (index < to) {
10677
+ const tagStart = source.indexOf("<", index);
10678
+ if (tagStart === -1 || tagStart >= to) return null;
10679
+ if (source.startsWith("<!--", tagStart)) {
10680
+ index = tagStart + 1;
10681
+ continue;
10744
10682
  }
10745
- } catch (error) {
10746
- console.log("Error removing attribute:", error);
10747
- }
10748
- }
10749
- addEventListener(mutation, context, store, syntax, directiveContext, logger) {
10750
- const element = context.getElementByInstruction(mutation.parent);
10751
- if (!element) {
10752
- throw new AreInterpreterError({
10753
- title: "Element Not Found",
10754
- description: `Could not find a DOM element associated with the instruction ASEID "${mutation.parent}". Ensure that the parent instruction is properly rendered and associated with a DOM element before adding event listeners.`
10755
- });
10756
- }
10757
- const handlers = syntax.extractEmitHandlers(mutation.payload.handler);
10758
- const handlerScope = {};
10759
- for (const handler of handlers) {
10760
- const handlerFn = /* @__PURE__ */ __name((...args) => {
10761
- const event = new AreEvent(handler);
10762
- event.set("args", args);
10763
- event.set("element", element);
10764
- event.set("instruction", mutation);
10765
- mutation.owner.emit(event);
10766
- }, "handlerFn");
10767
- handlerScope[`$${handler}`] = handlerFn;
10768
- }
10769
- const callback = /* @__PURE__ */ __name((e) => {
10770
- context.startPerformance("Click");
10771
- const result = syntax.evaluate(mutation.payload.handler, store, {
10772
- ...handlerScope,
10773
- ...directiveContext?.scope || {}
10774
- });
10775
- if (typeof result === "function") result(e);
10776
- }, "callback");
10777
- if (callback) {
10778
- element.addEventListener(mutation.payload.name, callback);
10779
- context.addListener(element, mutation.payload.name, callback);
10780
- }
10781
- }
10782
- removeEventListener(mutation, context) {
10783
- const element = context.getElementByInstruction(mutation.parent);
10784
- if (!element) return;
10785
- const { name } = mutation.payload;
10786
- const listener = context.getListener(element, name);
10787
- if (listener) {
10788
- element.removeEventListener(name, listener);
10789
- context.removeListener(element, name);
10790
- }
10791
- }
10792
- addText(declaration, context, store, syntax, directiveContext, logger) {
10793
- const node = declaration.owner.parent;
10794
- const { content, evaluate } = declaration.payload;
10795
- const value = evaluate ? syntax.evaluate(content, store, {
10796
- ...directiveContext?.scope || {}
10797
- }) : content;
10798
- if (!node) {
10799
- const textNode = context.container.createTextNode(value);
10800
- context.container.body.appendChild(textNode);
10801
- context.setInstructionElement(declaration, textNode);
10802
- } else {
10803
- const element = context.getNodeElement(node);
10804
- if (!element) {
10805
- throw new AreInterpreterError({
10806
- title: "Element Not Found",
10807
- description: `Could not find a DOM element associated with the instruction ASEID "${declaration.owner.parent.aseid}". Ensure that the parent instruction is properly rendered and associated with a DOM element before applying attribute mutations.`
10808
- });
10683
+ if (source[tagStart + 1] === "/") {
10684
+ index = tagStart + 1;
10685
+ continue;
10809
10686
  }
10810
- const existingNode = context.getElementByInstruction(declaration);
10811
- if (existingNode) {
10812
- existingNode.textContent = value;
10813
- } else {
10814
- const textNode = context.container.createTextNode(value);
10815
- element.appendChild(textNode);
10816
- context.setInstructionElement(declaration, textNode);
10687
+ if (source[tagStart + 1] === "!" || source[tagStart + 1] === "?") {
10688
+ index = tagStart + 1;
10689
+ continue;
10817
10690
  }
10818
- }
10819
- logger?.debug("green", `Text ${node?.aseid.toString()} added to Context:`);
10820
- }
10821
- removeText(declaration, context) {
10822
- const element = context.getElementByInstruction(declaration);
10823
- if (!element) return;
10824
- element.parentNode?.removeChild(element);
10825
- context.removeInstructionElement(declaration);
10826
- }
10827
- addComment(declaration, context, store, syntax, directiveContext, logger) {
10828
- const node = declaration.owner.parent;
10829
- const { content, evaluate } = declaration.payload;
10830
- const value = evaluate ? syntax.evaluate(content, store, {
10831
- ...directiveContext?.scope || {}
10832
- }) : content;
10833
- if (!node) {
10834
- const commentNode = context.container.createComment(value);
10835
- context.container.body.appendChild(commentNode);
10836
- context.setInstructionElement(declaration, commentNode);
10837
- } else {
10838
- const element = context.getNodeElement(node);
10839
- if (!element) {
10840
- throw new AreInterpreterError({
10841
- title: "Element Not Found",
10842
- description: `Could not find a DOM element associated with the instruction ASEID "${declaration.owner.parent.aseid}". Ensure that the parent instruction is properly rendered and associated with a DOM element before applying attribute mutations.`
10843
- });
10691
+ const tagNameMatch = source.slice(tagStart).match(/^<([a-zA-Z][a-zA-Z0-9-]*)/);
10692
+ if (!tagNameMatch) {
10693
+ index = tagStart + 1;
10694
+ continue;
10844
10695
  }
10845
- const existingNode = context.getElementByInstruction(declaration);
10846
- if (existingNode) {
10847
- existingNode.textContent = value;
10848
- } else {
10849
- const commentNode = context.container.createComment(value);
10850
- element.appendChild(commentNode);
10851
- context.setInstructionElement(declaration, commentNode);
10696
+ const tagName = tagNameMatch[1];
10697
+ const openingTagEnd = AreHTMLEngine.findTagClose(source, tagStart);
10698
+ if (openingTagEnd === -1) return null;
10699
+ const openingTagStr = source.slice(tagStart, openingTagEnd + 1);
10700
+ const idMatch = openingTagStr.match(/\bid=["']([^"']*)["']/);
10701
+ const id = idMatch ? idMatch[1] : void 0;
10702
+ if (source[openingTagEnd - 1] === "/") {
10703
+ const raw = source.slice(tagStart, openingTagEnd + 1);
10704
+ const content2 = source.slice(tagStart + tagNameMatch[0].length, openingTagEnd - 1);
10705
+ const match2 = build(raw, content2, tagStart, "/>");
10706
+ match2.payload = { entity: tagName, selfClose: true, id };
10707
+ return match2;
10708
+ }
10709
+ const closingTag = `</${tagName}>`;
10710
+ let level = 0;
10711
+ let searchIndex = openingTagEnd + 1;
10712
+ let closingStart = -1;
10713
+ while (searchIndex < to) {
10714
+ const nextOpen = source.indexOf(`<${tagName}`, searchIndex);
10715
+ const nextClose = source.indexOf(closingTag, searchIndex);
10716
+ if (nextClose === -1) break;
10717
+ if (nextOpen !== -1 && nextOpen < nextClose) {
10718
+ const charAfter = source[nextOpen + tagName.length + 1];
10719
+ if (charAfter === " " || charAfter === ">" || charAfter === "/") {
10720
+ const innerEnd = AreHTMLEngine.findTagClose(source, nextOpen);
10721
+ const isSelfClose = innerEnd !== -1 && source[innerEnd - 1] === "/";
10722
+ if (!isSelfClose) {
10723
+ level++;
10724
+ }
10725
+ searchIndex = innerEnd === -1 ? nextOpen + tagName.length + 1 : innerEnd + 1;
10726
+ continue;
10727
+ }
10728
+ }
10729
+ if (level === 0) {
10730
+ closingStart = nextClose;
10731
+ break;
10732
+ }
10733
+ level--;
10734
+ searchIndex = nextClose + closingTag.length;
10852
10735
  }
10736
+ if (closingStart === -1) return null;
10737
+ const fullTag = source.slice(tagStart, closingStart + closingTag.length);
10738
+ const content = source.slice(openingTagEnd + 1, closingStart);
10739
+ const match = build(fullTag, content, tagStart, closingTag);
10740
+ match.payload = { entity: tagName, selfClose: false, id };
10741
+ return match;
10853
10742
  }
10854
- logger?.debug("green", `Comment ${node?.aseid.toString()} added to Context:`);
10743
+ return null;
10855
10744
  }
10856
- removeComment(declaration, context) {
10857
- const element = context.getElementByInstruction(declaration);
10858
- if (!element) return;
10859
- element.parentNode?.removeChild(element);
10860
- context.removeInstructionElement(declaration);
10745
+ /**
10746
+ * Find the index of the closing `>` of an opening tag, skipping over
10747
+ * `>` characters that appear inside quoted attribute values.
10748
+ */
10749
+ static findTagClose(source, from) {
10750
+ let inSingle = false;
10751
+ let inDouble = false;
10752
+ for (let i = from; i < source.length; i++) {
10753
+ const ch = source[i];
10754
+ if (ch === '"' && !inSingle) inDouble = !inDouble;
10755
+ else if (ch === "'" && !inDouble) inSingle = !inSingle;
10756
+ else if (ch === ">" && !inSingle && !inDouble) return i;
10757
+ }
10758
+ return -1;
10861
10759
  }
10862
10760
  };
10863
- __name(AreHTMLInterpreter, "AreHTMLInterpreter");
10864
- __decorateClass([
10865
- c2.Method({
10866
- description: "Create an HTML element based on the provided declaration instruction. Handles both root-level mounting and child element creation based on the structural parent hierarchy."
10867
- }),
10868
- AreInterpreter.Apply(AreInstructionDefaultNames.Default),
10869
- AreInterpreter.Apply(AreHTMLInstructions.AddElement),
10870
- __decorateParam(0, ke(G)),
10871
- __decorateParam(1, ke(AreHTMLEngineContext)),
10872
- __decorateParam(2, ke(A_Logger))
10873
- ], AreHTMLInterpreter.prototype, "addElement", 1);
10874
- __decorateClass([
10875
- c2.Method({
10876
- description: "Remove an HTML element that was created by a CreateElement declaration. Cleans up the DOM and the context index."
10877
- }),
10878
- AreInterpreter.Revert(AreInstructionDefaultNames.Default),
10879
- AreInterpreter.Revert(AreHTMLInstructions.AddElement),
10880
- __decorateParam(0, ke(G)),
10881
- __decorateParam(1, ke(AreHTMLEngineContext))
10882
- ], AreHTMLInterpreter.prototype, "removeElement", 1);
10883
- __decorateClass([
10884
- c2.Method({
10885
- description: "Add an attribute to an HTML element based on the provided mutation instruction."
10886
- }),
10887
- AreInterpreter.Apply(AreHTMLInstructions.AddAttribute),
10888
- AreInterpreter.Update(AreHTMLInstructions.AddAttribute),
10889
- __decorateParam(0, ke(G)),
10890
- __decorateParam(1, ke(AreHTMLEngineContext)),
10891
- __decorateParam(2, ke(AreStore)),
10892
- __decorateParam(3, ke(AreSyntax)),
10893
- __decorateParam(4, ke(AreDirectiveContext)),
10894
- __decorateParam(5, ke(A_Logger))
10895
- ], AreHTMLInterpreter.prototype, "addAttribute", 1);
10896
- __decorateClass([
10897
- c2.Method({
10898
- description: "Remove an attribute from an HTML element based on the provided mutation instruction."
10899
- }),
10900
- AreInterpreter.Revert(AreHTMLInstructions.AddAttribute),
10901
- __decorateParam(0, ke(G)),
10902
- __decorateParam(1, ke(AreHTMLEngineContext))
10903
- ], AreHTMLInterpreter.prototype, "removeAttribute", 1);
10761
+ __name(AreHTMLEngine, "AreHTMLEngine");
10904
10762
  __decorateClass([
10905
- c2.Method({
10906
- description: "Add an event listener to an HTML element based on the provided mutation instruction."
10763
+ w.Extend({
10764
+ name: A_ServiceFeatures.onBeforeLoad,
10765
+ before: /.*/
10907
10766
  }),
10908
- AreInterpreter.Apply(AreHTMLInstructions.AddListener),
10909
- __decorateParam(0, ke(G)),
10910
- __decorateParam(1, ke(AreHTMLEngineContext)),
10911
- __decorateParam(2, ke(AreStore)),
10912
- __decorateParam(3, ke(AreSyntax)),
10913
- __decorateParam(4, ke(AreDirectiveContext)),
10914
- __decorateParam(5, ke(A_Logger))
10915
- ], AreHTMLInterpreter.prototype, "addEventListener", 1);
10767
+ __decorateParam(0, ke(D))
10768
+ ], AreHTMLEngine.prototype, "init", 1);
10769
+ AreHTMLEngine = __decorateClass([
10770
+ c2.Component({
10771
+ namespace: "A-ARE",
10772
+ name: "AreHTMLEngine",
10773
+ description: "HTML Rendering Engine for A-Concept Rendering Engine (ARE), responsible for processing and rendering HTML templates within the ARE framework."
10774
+ })
10775
+ ], AreHTMLEngine);
10776
+
10777
+ // examples/jumpstart/src/components/List.component.ts
10778
+ var _ListComponent = class _ListComponent extends Are {
10779
+ async template(node) {
10780
+ node.setContent(`
10781
+ <div class="menu-section">Main</div>
10782
+ <ul class="menu">
10783
+ <li @click="$handleClick('Dashboard')" :class="active==='Dashboard' ? 'menu-item-active' : ''" class="menu-item "><span class="menu-icon">\u229E</span> <span class="menu-text">{{item1}}</span></li>
10784
+ <li $if="active=='Dashboard'" @click="$handleClick('Users')" :class="active==='Users' ? 'menu-item-active' : ''" class="menu-item"><span class="menu-icon">\u22A1</span> <span class="menu-text">{{item2}}</span> <span class="menu-badge">{{usersBadge}}</span></li>
10785
+ <li @click="$handleClick('Products')" :class="active==='Products' ? 'menu-item-active' : ''" class="menu-item"><span class="menu-icon">\u22A0</span> <span class="menu-text">{{item3}}</span></li>
10786
+ <li @click="$handleClick('Orders')" :class="active==='Orders' ? 'menu-item-active' : ''" class="menu-item"><span class="menu-icon">\u229F</span> <span class="menu-text">{{item4}}</span></li>
10787
+ </ul>
10788
+ <div class="menu-section">System</div>
10789
+ <button @click="$add">Add +</button>
10790
+ <div $if="active=='Dashboard'">
10791
+ <ul class="menu">
10792
+ <li
10793
+ $for="item in items track item.name" @click="$handleClick(item.name)"
10794
+ :class="active===item.name ? 'menu-item-active' : ''"
10795
+ class="menu-item">
10796
+ <span class="menu-icon">\u2299</span>
10797
+ <span class="menu-text">{{item.name}}</span>
10798
+ <span $if="item.badge > 0" class="menu-badge">{{item.badge}}</span>
10799
+ <button @click.stop="$remove(item)">+</button>
10800
+ </li>
10801
+ </ul>
10802
+ </div>
10803
+ `);
10804
+ }
10805
+ async data(store) {
10806
+ store.set({
10807
+ active: "Dashboard",
10808
+ item1: "Dashboard",
10809
+ item2: "Users",
10810
+ item3: "Products",
10811
+ item4: "Orders",
10812
+ item5: "Messages",
10813
+ item6: "Settings",
10814
+ usersBadge: "24",
10815
+ msgBadge: "3",
10816
+ items: [
10817
+ { name: "Messages", badge: 3 },
10818
+ { name: "Settings", badge: 0 }
10819
+ ]
10820
+ });
10821
+ }
10822
+ add(node, event, context, store, logger) {
10823
+ const currentItems = store.get("items") || [];
10824
+ currentItems.push({
10825
+ name: `Item ${currentItems.length + 1}`,
10826
+ badge: 0
10827
+ });
10828
+ store.set("items", currentItems);
10829
+ }
10830
+ remove(node, event, context, store, logger) {
10831
+ const itemToRemove = event.get("args")?.[0];
10832
+ console.log("Removing item:", itemToRemove, "from store:", store);
10833
+ if (!itemToRemove) {
10834
+ logger.warning("No item specified for removal");
10835
+ return;
10836
+ }
10837
+ const currentItems = store.get("items") || [];
10838
+ const updatedItems = currentItems.filter((item) => item.name !== itemToRemove.name);
10839
+ store.set("items", updatedItems);
10840
+ }
10841
+ async handleClick(node, event, context, store, logger) {
10842
+ try {
10843
+ console.log("Menu item clicked!", event.get("args"), store);
10844
+ const item = event.get("args")?.[0] || "Dashboard";
10845
+ store.set("active", item);
10846
+ context.endPerformance("Click");
10847
+ logger.info(`Menu item clicked: ${item}`, ...context.performance);
10848
+ } catch (error) {
10849
+ logger.error(error);
10850
+ }
10851
+ }
10852
+ };
10853
+ __name(_ListComponent, "ListComponent");
10916
10854
  __decorateClass([
10917
- c2.Method({
10918
- description: "Remove an event listener from an HTML element based on the provided mutation instruction."
10919
- }),
10920
- AreInterpreter.Revert(AreHTMLInstructions.AddListener),
10921
- __decorateParam(0, ke(G)),
10922
- __decorateParam(1, ke(AreHTMLEngineContext))
10923
- ], AreHTMLInterpreter.prototype, "removeEventListener", 1);
10855
+ Are.Template,
10856
+ __decorateParam(0, ke(G))
10857
+ ], _ListComponent.prototype, "template", 1);
10924
10858
  __decorateClass([
10925
- c2.Method({
10926
- description: "Add text content to an HTML element based on the provided declaration instruction."
10927
- }),
10928
- AreInterpreter.Apply(AreHTMLInstructions.AddText),
10929
- AreInterpreter.Update(AreHTMLInstructions.AddText),
10930
- __decorateParam(0, ke(G)),
10931
- __decorateParam(1, ke(AreHTMLEngineContext)),
10932
- __decorateParam(2, ke(AreStore)),
10933
- __decorateParam(3, ke(AreSyntax)),
10934
- __decorateParam(4, ke(AreDirectiveContext)),
10935
- __decorateParam(5, ke(A_Logger))
10936
- ], AreHTMLInterpreter.prototype, "addText", 1);
10859
+ Are.Data,
10860
+ __decorateParam(0, ke(AreStore))
10861
+ ], _ListComponent.prototype, "data", 1);
10937
10862
  __decorateClass([
10938
- c2.Method({
10939
- description: "Remove text content from an HTML element based on the provided declaration instruction."
10940
- }),
10941
- AreInterpreter.Revert(AreHTMLInstructions.AddText),
10863
+ Are.EventHandler,
10942
10864
  __decorateParam(0, ke(G)),
10943
- __decorateParam(1, ke(AreHTMLEngineContext))
10944
- ], AreHTMLInterpreter.prototype, "removeText", 1);
10865
+ __decorateParam(1, ke(AreEvent)),
10866
+ __decorateParam(2, ke(AreContext)),
10867
+ __decorateParam(3, ke(AreStore)),
10868
+ __decorateParam(4, ke(A_Logger))
10869
+ ], _ListComponent.prototype, "add", 1);
10945
10870
  __decorateClass([
10946
- c2.Method({
10947
- description: "Add a comment node to the DOM based on the provided declaration instruction."
10948
- }),
10949
- AreInterpreter.Apply(AreHTMLInstructions.AddComment),
10950
- AreInterpreter.Update(AreHTMLInstructions.AddComment),
10871
+ Are.EventHandler,
10951
10872
  __decorateParam(0, ke(G)),
10952
- __decorateParam(1, ke(AreHTMLEngineContext)),
10953
- __decorateParam(2, ke(AreStore)),
10954
- __decorateParam(3, ke(AreSyntax)),
10955
- __decorateParam(4, ke(AreDirectiveContext)),
10956
- __decorateParam(5, ke(A_Logger))
10957
- ], AreHTMLInterpreter.prototype, "addComment", 1);
10873
+ __decorateParam(1, ke(AreEvent)),
10874
+ __decorateParam(2, ke(AreContext)),
10875
+ __decorateParam(3, ke(AreStore)),
10876
+ __decorateParam(4, ke(A_Logger))
10877
+ ], _ListComponent.prototype, "remove", 1);
10958
10878
  __decorateClass([
10959
- c2.Method({
10960
- description: "Remove a comment node from the DOM based on the provided declaration instruction."
10961
- }),
10962
- AreInterpreter.Revert(AreHTMLInstructions.AddComment),
10879
+ Are.EventHandler,
10963
10880
  __decorateParam(0, ke(G)),
10964
- __decorateParam(1, ke(AreHTMLEngineContext))
10965
- ], AreHTMLInterpreter.prototype, "removeComment", 1);
10966
- AreHTMLInterpreter = __decorateClass([
10967
- c2.Component({
10968
- namespace: "A-ARE",
10969
- name: "AreHTMLInterpreter",
10970
- description: "AreHTMLInterpreter is a component that serves as a host for rendering AreNodes into HTML. It provides the necessary context and environment for AreNodes to be rendered and interact with the DOM."
10971
- })
10972
- ], AreHTMLInterpreter);
10881
+ __decorateParam(1, ke(AreEvent)),
10882
+ __decorateParam(2, ke(AreContext)),
10883
+ __decorateParam(3, ke(AreStore)),
10884
+ __decorateParam(4, ke(A_Logger))
10885
+ ], _ListComponent.prototype, "handleClick", 1);
10886
+ var ListComponent = _ListComponent;
10973
10887
 
10974
- // src/engine/AreHTML.tokenizer.ts
10975
- var _AreHTMLTokenizer = class _AreHTMLTokenizer extends AreTokenizer {
10888
+ // src/lib/AreDirective/AreDirective.meta.ts
10889
+ var _AreDirectiveMeta = class _AreDirectiveMeta extends R {
10976
10890
  constructor() {
10977
10891
  super(...arguments);
10978
- this.ATTR_PATTERN = /([$:@]?[\w-]+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s>/"'=]+)))?/g;
10892
+ this.priority = 0;
10979
10893
  }
10980
- tokenize(node, context, logger) {
10981
- super.tokenize(node, context, logger);
10982
- context.startPerformance("attributeExtraction");
10983
- const attributes = this.extractAttributes(node.markup);
10984
- for (const attr of attributes) {
10985
- node.scope.register(attr);
10894
+ };
10895
+ __name(_AreDirectiveMeta, "AreDirectiveMeta");
10896
+ var AreDirectiveMeta = _AreDirectiveMeta;
10897
+
10898
+ // src/lib/AreDirective/AreDirective.component.ts
10899
+ var AreDirective = class extends v {
10900
+ //==================================================================================
10901
+ //======================== LIFECYCLE DECORATORS ====================================
10902
+ //==================================================================================
10903
+ /**
10904
+ * Allows to define a compilation order for directives, which is necessary when we have multiple directives on the same node and we want to control the order of their compilation and application. The directive with the highest priority will be compiled and applied first, and the directive with the lowest priority will be compiled and applied last. This is important because some directives may depend on the output of other directives, so we need to ensure that they are compiled and applied in the correct order to avoid errors and ensure the expected behavior.
10905
+ *
10906
+ * @param priority
10907
+ * @returns
10908
+ */
10909
+ static Priority(priority) {
10910
+ return function(target) {
10911
+ const meta = c.meta(target);
10912
+ meta.priority = priority;
10913
+ return target;
10914
+ };
10915
+ }
10916
+ /**
10917
+ * Allows to define a custom method for transforming the AreNode tree based on the directive attribute. This method is called during the transformation phase of the ARE component and should perform any necessary transformations on the AreNode tree based on the directive's content and context. This can include tasks such as adding or removing nodes, modifying node properties, or restructuring the tree to ensure that the directive is applied correctly during rendering.
10918
+ */
10919
+ static get Transform() {
10920
+ return (target, propertyKey, descriptor) => {
10921
+ return w.Extend({
10922
+ name: AreDirectiveFeatures.Transform,
10923
+ scope: [target.constructor]
10924
+ })(target, propertyKey, descriptor);
10925
+ };
10926
+ }
10927
+ /**
10928
+ * Allows to define a custom method for compiling a directive attribute into a set of SceneInstructions.
10929
+ * Can be used at any component to extend this logic not only for a AreDirective inherited.
10930
+ */
10931
+ static get Compile() {
10932
+ return (target, propertyKey, descriptor) => {
10933
+ return w.Extend({
10934
+ name: AreDirectiveFeatures.Compile,
10935
+ scope: [target.constructor]
10936
+ })(target, propertyKey, descriptor);
10937
+ };
10938
+ }
10939
+ /**
10940
+ * Allows to define a custom method for updating a directive attribute based on changes in the store or other dependencies.
10941
+ * Can be used at any component to extend this logic not only for a AreDirective inherited.
10942
+ */
10943
+ static get Update() {
10944
+ return (target, propertyKey, descriptor) => {
10945
+ return w.Extend({
10946
+ name: AreDirectiveFeatures.Update,
10947
+ scope: [target.constructor]
10948
+ })(target, propertyKey, descriptor);
10949
+ };
10950
+ }
10951
+ /**
10952
+ * Default transform method for directives, which can be overridden by specific directive implementations. This method is called during the transformation phase of the ARE component and should perform any necessary transformations on the AreNode tree based on the directive's content and context. This can include tasks such as adding or removing nodes, modifying node properties, or restructuring the tree to ensure that the directive is applied correctly during rendering.
10953
+ *
10954
+ * @param attribute - The directive attribute to transform, which contains all the information about the directive as defined in the template (e.g. name, raw content, evaluated value, etc.)
10955
+ * @param args - Additional arguments that may be required for the transformation process.
10956
+ */
10957
+ transform(attribute, ...args) {
10958
+ const logger = c.scope(this).resolve(A_Logger);
10959
+ if (logger) {
10960
+ logger.warning(`No transforming logic defined for directive: ${attribute.name} with content: ${attribute.content}`);
10986
10961
  }
10987
- context.endPerformance("attributeExtraction");
10988
10962
  }
10989
- extractAttributes(markup) {
10990
- const withoutTag = markup.replace(/^<[a-zA-Z][a-zA-Z0-9-]*\s*/, "");
10991
- let inSingle = false;
10992
- let inDouble = false;
10993
- let endIdx = withoutTag.length;
10994
- for (let i = 0; i < withoutTag.length; i++) {
10995
- const ch = withoutTag[i];
10996
- if (ch === '"' && !inSingle) inDouble = !inDouble;
10997
- else if (ch === "'" && !inDouble) inSingle = !inSingle;
10998
- else if (ch === ">" && !inSingle && !inDouble) {
10999
- endIdx = i;
11000
- break;
11001
- }
10963
+ compile(attribute, ...args) {
10964
+ const logger = c.scope(this).resolve(A_Logger);
10965
+ if (logger) {
10966
+ logger.warning(`No compiling logic defined for directive: ${attribute.name} with content: ${attribute.content}`);
11002
10967
  }
11003
- const attrString = withoutTag.slice(0, endIdx).replace(/\s*\/?\s*$/, "").trim();
11004
- const results = [];
11005
- for (const match of attrString.matchAll(this.ATTR_PATTERN)) {
11006
- const raw = match[0];
11007
- const full = match[1];
11008
- if (!full) continue;
11009
- const value = match[2] ?? match[3] ?? match[4] ?? "true";
11010
- const prefix = full[0];
11011
- const isSpecial = prefix === ":" || prefix === "@" || prefix === "$";
11012
- const name = isSpecial ? full.slice(1) : full;
11013
- const meta = { name, content: value, raw, prefix: isSpecial ? prefix : "" };
11014
- if (prefix === ":") results.push(new AreBindingAttribute(meta));
11015
- else if (prefix === "@") results.push(new AreEventAttribute(meta));
11016
- else if (prefix === "$") results.push(new AreDirectiveAttribute(meta));
11017
- else results.push(new AreStaticAttribute(meta));
10968
+ }
10969
+ update(attribute, ...args) {
10970
+ const logger = c.scope(this).resolve(A_Logger);
10971
+ if (logger) {
10972
+ logger.warning(`No update logic defined for directive: ${attribute.name} with content: ${attribute.content}`);
11018
10973
  }
11019
- return results;
11020
10974
  }
11021
10975
  };
11022
- __name(_AreHTMLTokenizer, "AreHTMLTokenizer");
10976
+ __name(AreDirective, "AreDirective");
10977
+ __decorateClass([
10978
+ __decorateParam(0, ke(G))
10979
+ ], AreDirective.prototype, "transform", 1);
11023
10980
  __decorateClass([
11024
10981
  w.Extend({
11025
- name: AreNodeFeatures.onTokenize,
11026
- scope: [AreComponentNode, AreRootNode]
10982
+ name: AreDirectiveFeatures.Compile,
10983
+ scope: [AreDirective]
11027
10984
  }),
11028
- __decorateParam(0, ke(G)),
11029
- __decorateParam(1, ke(AreContext)),
11030
- __decorateParam(2, ke(A_Logger))
11031
- ], _AreHTMLTokenizer.prototype, "tokenize", 1);
11032
- var AreHTMLTokenizer = _AreHTMLTokenizer;
10985
+ __decorateParam(0, ke(G))
10986
+ ], AreDirective.prototype, "compile", 1);
10987
+ __decorateClass([
10988
+ w.Extend({
10989
+ name: AreDirectiveFeatures.Update,
10990
+ scope: [AreDirective]
10991
+ }),
10992
+ __decorateParam(0, ke(G))
10993
+ ], AreDirective.prototype, "update", 1);
10994
+ AreDirective = __decorateClass([
10995
+ m.Define(AreDirectiveMeta)
10996
+ ], AreDirective);
11033
10997
 
11034
- // src/engine/AreHTML.lifecycle.ts
11035
- var _AreHTMLLifecycle = class _AreHTMLLifecycle extends AreLifecycle {
11036
- initComponent(node, scope, context, logger, ...args) {
11037
- super.init(node, scope, context, logger, ...args);
10998
+ // src/instructions/AddComment.instruction.ts
10999
+ var AddCommentInstruction = class extends AreDeclaration {
11000
+ get content() {
11001
+ return this.payload.content;
11038
11002
  }
11039
- initRoot(node, scope, context, signalsContext, logger, ...args) {
11040
- signalsContext?.subscribe(node);
11041
- super.init(node, scope, context, logger, ...args);
11003
+ constructor(props) {
11004
+ if ("aseid" in props) {
11005
+ super(props);
11006
+ } else {
11007
+ super(AreHTMLInstructions.AddComment, props);
11008
+ }
11042
11009
  }
11043
- initText(node, scope, context, logger, ...args) {
11044
- const scene = new AreScene(node.aseid);
11045
- scope.register(scene);
11010
+ };
11011
+ __name(AddCommentInstruction, "AddCommentInstruction");
11012
+ AddCommentInstruction = __decorateClass([
11013
+ c2.Component({
11014
+ namespace: "A-ARE",
11015
+ name: "AddCommentInstruction",
11016
+ description: "Appends a comment node to an element. Apply creates the comment node; revert removes it. Content can be a static string or a dynamic getter for interpolations."
11017
+ })
11018
+ ], AddCommentInstruction);
11019
+
11020
+ // src/directives/AreDirectiveIf.directive.ts
11021
+ var AreDirectiveIf = class extends AreDirective {
11022
+ transform(attribute, scope, store, scene, logger, ...args) {
11023
+ logger.debug(`[Transform] directive $IF for <${attribute.owner.aseid.toString()}>`);
11024
+ const node = attribute.owner;
11025
+ const ifTemplate = node.cloneWithScope();
11026
+ const ifAttr = ifTemplate.attributes.find((d2) => d2.name === attribute.name);
11027
+ if (ifAttr) {
11028
+ ifTemplate.scope.deregister(ifAttr);
11029
+ node.scope.register(ifAttr);
11030
+ }
11031
+ node.init();
11032
+ node.addChild(ifTemplate);
11033
+ ifTemplate.scene.deactivate();
11034
+ attribute.template = ifTemplate;
11046
11035
  }
11047
- initInterpolation(node, scope, context, logger, ...args) {
11048
- const scene = new AreScene(node.aseid);
11049
- scope.register(scene);
11036
+ compile(attribute, store, scene, syntax, directiveContext, ...args) {
11037
+ attribute.value = syntax.evaluate(attribute.content, store, {
11038
+ ...directiveContext?.scope || {}
11039
+ });
11040
+ const hostInstruction = scene.host;
11041
+ const commentIdentifier = ` --- if: ${attribute.template.id} --- `;
11042
+ const declaration = new AddCommentInstruction({ content: commentIdentifier });
11043
+ scene.setHost(declaration);
11044
+ scene.planBefore(declaration, hostInstruction);
11045
+ scene.unPlan(hostInstruction);
11046
+ if (attribute.value)
11047
+ attribute.template.scene.activate();
11048
+ else
11049
+ attribute.template.scene.deactivate();
11050
11050
  }
11051
- updateDirectiveAttribute(directive, scope, feature, logger, ...args) {
11052
- if (directive.component) {
11053
- feature.chain(directive.component, AreDirectiveFeatures.Update, directive.owner.scope);
11051
+ update(attribute, store, scope, syntax, scene, ...args) {
11052
+ const previous = !!attribute.value;
11053
+ const next = !!syntax.evaluate(attribute.content, store);
11054
+ attribute.value = next;
11055
+ if (previous === next) return;
11056
+ if (next) {
11057
+ attribute.template.scene.activate();
11058
+ attribute.template.mount();
11054
11059
  } else {
11055
- logger?.warning(`Directive handler component not found for directive: ${directive.name}. Make sure to create a component named "AreDirective${h.toPascalCase(directive.name)}" to handle this directive.`);
11060
+ attribute.template.unmount();
11061
+ attribute.template.scene.deactivate();
11056
11062
  }
11057
11063
  }
11058
11064
  };
11059
- __name(_AreHTMLLifecycle, "AreHTMLLifecycle");
11060
- __decorateClass([
11061
- AreLifecycle.Init(AreComponentNode),
11062
- __decorateParam(0, ke(G)),
11063
- __decorateParam(1, ke(D)),
11064
- __decorateParam(2, ke(AreHTMLEngineContext)),
11065
- __decorateParam(3, ke(A_Logger))
11066
- ], _AreHTMLLifecycle.prototype, "initComponent", 1);
11065
+ __name(AreDirectiveIf, "AreDirectiveIf");
11067
11066
  __decorateClass([
11068
- AreLifecycle.Init(AreRootNode),
11067
+ AreDirective.Transform,
11069
11068
  __decorateParam(0, ke(G)),
11070
11069
  __decorateParam(1, ke(D)),
11071
- __decorateParam(2, ke(AreHTMLEngineContext)),
11072
- __decorateParam(3, ke(AreSignalsContext)),
11070
+ __decorateParam(2, ke(AreStore)),
11071
+ __decorateParam(3, ke(AreScene)),
11073
11072
  __decorateParam(4, ke(A_Logger))
11074
- ], _AreHTMLLifecycle.prototype, "initRoot", 1);
11075
- __decorateClass([
11076
- AreLifecycle.Init(AreText),
11077
- __decorateParam(0, ke(G)),
11078
- __decorateParam(1, ke(D)),
11079
- __decorateParam(2, ke(AreHTMLEngineContext)),
11080
- __decorateParam(3, ke(A_Logger))
11081
- ], _AreHTMLLifecycle.prototype, "initText", 1);
11082
- __decorateClass([
11083
- AreLifecycle.Init(AreInterpolation),
11084
- __decorateParam(0, ke(G)),
11085
- __decorateParam(1, ke(D)),
11086
- __decorateParam(2, ke(AreHTMLEngineContext)),
11087
- __decorateParam(3, ke(A_Logger))
11088
- ], _AreHTMLLifecycle.prototype, "initInterpolation", 1);
11073
+ ], AreDirectiveIf.prototype, "transform", 1);
11089
11074
  __decorateClass([
11090
- w.Extend({
11091
- name: AreAttributeFeatures.Update,
11092
- scope: [AreDirectiveAttribute]
11093
- }),
11075
+ AreDirective.Compile,
11094
11076
  __decorateParam(0, ke(G)),
11095
- __decorateParam(1, ke(D)),
11096
- __decorateParam(2, ke(w)),
11097
- __decorateParam(3, ke(A_Logger))
11098
- ], _AreHTMLLifecycle.prototype, "updateDirectiveAttribute", 1);
11099
- var AreHTMLLifecycle = _AreHTMLLifecycle;
11100
-
11101
- // src/engine/AreHTML.transformer.ts
11102
- var _AreHTMLTransformer = class _AreHTMLTransformer extends AreTransformer {
11103
- transformDirectiveAttribute(directive, store, feature, logger, ...args) {
11104
- store.watch(directive);
11105
- if (directive.component) {
11106
- feature.chain(directive.component, AreDirectiveFeatures.Transform, directive.owner.scope);
11107
- } else {
11108
- logger?.warning(`Directive handler component not found for directive: ${directive.name}. Make sure to create a component named "AreDirective${h.toPascalCase(directive.name)}" to handle this directive.`);
11109
- }
11110
- store.unwatch(directive);
11111
- }
11112
- };
11113
- __name(_AreHTMLTransformer, "AreHTMLTransformer");
11077
+ __decorateParam(1, ke(AreStore)),
11078
+ __decorateParam(2, ke(AreScene)),
11079
+ __decorateParam(3, ke(AreSyntax)),
11080
+ __decorateParam(4, ke(AreDirectiveContext))
11081
+ ], AreDirectiveIf.prototype, "compile", 1);
11114
11082
  __decorateClass([
11115
- w.Extend({
11116
- name: AreAttributeFeatures.Transform,
11117
- scope: [AreDirectiveAttribute]
11118
- }),
11083
+ AreDirective.Update,
11119
11084
  __decorateParam(0, ke(G)),
11120
11085
  __decorateParam(1, ke(AreStore)),
11121
- __decorateParam(2, ke(w)),
11122
- __decorateParam(3, ke(A_Logger))
11123
- ], _AreHTMLTransformer.prototype, "transformDirectiveAttribute", 1);
11124
- var AreHTMLTransformer = _AreHTMLTransformer;
11086
+ __decorateParam(2, ke(D)),
11087
+ __decorateParam(3, ke(AreSyntax)),
11088
+ __decorateParam(4, ke(AreScene))
11089
+ ], AreDirectiveIf.prototype, "update", 1);
11090
+ AreDirectiveIf = __decorateClass([
11091
+ AreDirective.Priority(2)
11092
+ ], AreDirectiveIf);
11125
11093
 
11126
- // src/engine/AreHTML.engine.ts
11127
- var AreHTMLEngine = class extends AreEngine {
11128
- get DefaultSyntax() {
11129
- return new AreSyntax({
11130
- trimWhitespace: true,
11131
- strictMode: true,
11132
- rules: [
11133
- // HTML comments
11134
- {
11135
- opening: "<!--",
11136
- closing: "-->",
11137
- component: AreComment,
11138
- priority: 10,
11139
- nested: false,
11140
- extract: /* @__PURE__ */ __name((raw) => ({ content: raw.slice(4, -3).trim() }), "extract")
11141
- },
11142
- // interpolations
11143
- {
11144
- opening: "{{",
11145
- closing: "}}",
11146
- component: AreInterpolation,
11147
- priority: 9,
11148
- nested: false,
11149
- extract: /* @__PURE__ */ __name((_, match) => ({ key: match.content }), "extract")
11150
- },
11151
- // are-root — matched before generic elements, produces AreRootNode
11152
- {
11153
- matcher: this.rootElementMatcher.bind(this),
11154
- component: AreRootNode,
11155
- priority: 5
11156
- },
11157
- // generic HTML elements
11158
- {
11159
- matcher: this.htmlElementMatcher.bind(this),
11160
- component: AreComponentNode,
11161
- priority: 4
11162
- },
11163
- // plain text fallback
11164
- {
11165
- component: AreText,
11166
- priority: 0
11167
- }
11168
- ]
11169
- });
11170
- }
11171
- async init(scope) {
11172
- this.package(scope, {
11173
- context: new AreHTMLEngineContext({}),
11174
- syntax: this.DefaultSyntax,
11175
- compiler: AreHTMLCompiler,
11176
- interpreter: AreHTMLInterpreter,
11177
- tokenizer: AreHTMLTokenizer,
11178
- lifecycle: AreHTMLLifecycle,
11179
- transformer: AreHTMLTransformer
11180
- });
11181
- }
11182
- rootElementMatcher(source, from, to, build) {
11183
- const rootTag = "are-root";
11184
- const tagStart = source.indexOf("<", from);
11185
- if (tagStart === -1 || tagStart >= to) return null;
11186
- const tagNameMatch = source.slice(tagStart).match(/^<([a-zA-Z][a-zA-Z0-9-]*)/);
11187
- if (!tagNameMatch || tagNameMatch[1].toLowerCase() !== rootTag) return null;
11188
- return this.htmlElementMatcher(source, from, to, build);
11189
- }
11190
- htmlElementMatcher(source, from, to, build) {
11191
- let index = from;
11192
- while (index < to) {
11193
- const tagStart = source.indexOf("<", index);
11194
- if (tagStart === -1 || tagStart >= to) return null;
11195
- if (source.startsWith("<!--", tagStart)) {
11196
- index = tagStart + 1;
11197
- continue;
11198
- }
11199
- if (source[tagStart + 1] === "/") {
11200
- index = tagStart + 1;
11201
- continue;
11202
- }
11203
- if (source[tagStart + 1] === "!" || source[tagStart + 1] === "?") {
11204
- index = tagStart + 1;
11205
- continue;
11206
- }
11207
- const tagNameMatch = source.slice(tagStart).match(/^<([a-zA-Z][a-zA-Z0-9-]*)/);
11208
- if (!tagNameMatch) {
11209
- index = tagStart + 1;
11210
- continue;
11211
- }
11212
- const tagName = tagNameMatch[1];
11213
- const openingTagEnd = AreHTMLEngine.findTagClose(source, tagStart);
11214
- if (openingTagEnd === -1) return null;
11215
- const openingTagStr = source.slice(tagStart, openingTagEnd + 1);
11216
- const idMatch = openingTagStr.match(/\bid=["']([^"']*)["']/);
11217
- const id = idMatch ? idMatch[1] : void 0;
11218
- if (source[openingTagEnd - 1] === "/") {
11219
- const raw = source.slice(tagStart, openingTagEnd + 1);
11220
- const content2 = source.slice(tagStart + tagNameMatch[0].length, openingTagEnd - 1);
11221
- const match2 = build(raw, content2, tagStart, "/>");
11222
- match2.payload = { entity: tagName, selfClose: true, id };
11223
- return match2;
11224
- }
11225
- const closingTag = `</${tagName}>`;
11226
- let level = 0;
11227
- let searchIndex = openingTagEnd + 1;
11228
- let closingStart = -1;
11229
- while (searchIndex < to) {
11230
- const nextOpen = source.indexOf(`<${tagName}`, searchIndex);
11231
- const nextClose = source.indexOf(closingTag, searchIndex);
11232
- if (nextClose === -1) break;
11233
- if (nextOpen !== -1 && nextOpen < nextClose) {
11234
- const charAfter = source[nextOpen + tagName.length + 1];
11235
- if (charAfter === " " || charAfter === ">" || charAfter === "/") {
11236
- level++;
11237
- searchIndex = nextOpen + tagName.length + 1;
11238
- continue;
11239
- }
11240
- }
11241
- if (level === 0) {
11242
- closingStart = nextClose;
11243
- break;
11244
- }
11245
- level--;
11246
- searchIndex = nextClose + closingTag.length;
11247
- }
11248
- if (closingStart === -1) return null;
11249
- const fullTag = source.slice(tagStart, closingStart + closingTag.length);
11250
- const content = source.slice(openingTagEnd + 1, closingStart);
11251
- const match = build(fullTag, content, tagStart, closingTag);
11252
- match.payload = { entity: tagName, selfClose: false, id };
11253
- return match;
11094
+ // src/directives/AreDirectiveFor.directive.ts
11095
+ var AreDirectiveFor = class extends AreDirective {
11096
+ transform(attribute, scope, store, scene, logger, ...args) {
11097
+ logger.debug(`[Transform] directive $FOR for <${attribute.owner.aseid.toString()}>`);
11098
+ const node = attribute.owner;
11099
+ const forTemplate = node.cloneWithScope();
11100
+ const forAttr = forTemplate.attributes.find((d2) => d2.name === attribute.name);
11101
+ if (forAttr) {
11102
+ forTemplate.scope.deregister(forAttr);
11103
+ node.scope.register(forAttr);
11254
11104
  }
11255
- return null;
11256
- }
11257
- /**
11258
- * Find the index of the closing `>` of an opening tag, skipping over
11259
- * `>` characters that appear inside quoted attribute values.
11260
- */
11261
- static findTagClose(source, from) {
11262
- let inSingle = false;
11263
- let inDouble = false;
11264
- for (let i = from; i < source.length; i++) {
11265
- const ch = source[i];
11266
- if (ch === '"' && !inSingle) inDouble = !inDouble;
11267
- else if (ch === "'" && !inDouble) inSingle = !inSingle;
11268
- else if (ch === ">" && !inSingle && !inDouble) return i;
11105
+ node.init();
11106
+ attribute.template = forTemplate;
11107
+ const { key, index, arrayExpr } = this.parseExpression(attribute.content);
11108
+ const array = this.resolveArray(store, arrayExpr, attribute.content);
11109
+ attribute.value = array;
11110
+ for (let i = 0; i < array.length; i++) {
11111
+ this.spawnItemNode(attribute.template, attribute.owner, key, index, array[i], i);
11269
11112
  }
11270
- return -1;
11271
11113
  }
11272
- };
11273
- __name(AreHTMLEngine, "AreHTMLEngine");
11274
- __decorateClass([
11275
- w.Extend({
11276
- name: A_ServiceFeatures.onBeforeLoad,
11277
- before: /.*/
11278
- }),
11279
- __decorateParam(0, ke(D))
11280
- ], AreHTMLEngine.prototype, "init", 1);
11281
- AreHTMLEngine = __decorateClass([
11282
- c2.Component({
11283
- namespace: "A-ARE",
11284
- name: "AreHTMLEngine",
11285
- description: "HTML Rendering Engine for A-Concept Rendering Engine (ARE), responsible for processing and rendering HTML templates within the ARE framework."
11286
- })
11287
- ], AreHTMLEngine);
11288
-
11289
- // src/lib/AreRoot/AreRoot.component.ts
11290
- var AreRoot = class extends Are {
11291
- constructor() {
11292
- super(...arguments);
11293
- this.props = {
11294
- default: {
11295
- type: "string",
11296
- default: ""
11297
- }
11298
- };
11114
+ compile(attribute, store, scene, ...args) {
11115
+ const hostInstruction = scene.host;
11116
+ const commentIdentifier = ` --- for: ${attribute.template.id} --- `;
11117
+ const declaration = new AddCommentInstruction({ content: commentIdentifier });
11118
+ scene.setHost(declaration);
11119
+ scene.planBefore(declaration, hostInstruction);
11120
+ scene.unPlan(hostInstruction);
11299
11121
  }
11300
- async template(root, logger, signalsContext) {
11301
- const rootId = root.id;
11302
- if (signalsContext && !signalsContext.hasRoot(rootId)) {
11303
- return;
11304
- }
11305
- const currentRoute = AreRoute.default();
11306
- let componentName;
11307
- if (currentRoute) {
11308
- const initialVector = new A_SignalVector([currentRoute]);
11309
- let renderTarget = signalsContext?.findComponentByVector(rootId, initialVector);
11310
- if (!renderTarget) {
11311
- const signalsMeta = c.meta(AreSignals);
11312
- renderTarget = signalsMeta?.findComponentByVector(initialVector);
11313
- }
11314
- if (renderTarget?.name) {
11315
- componentName = h.toKebabCase(renderTarget.name);
11122
+ update(attribute, store, scene, ...args) {
11123
+ const { key, index, arrayExpr, trackExpr } = this.parseExpression(attribute.content);
11124
+ const newArray = this.resolveArray(store, arrayExpr, attribute.content);
11125
+ const owner = attribute.owner;
11126
+ const currentChildren = [...owner.children];
11127
+ attribute.value = newArray;
11128
+ const computeKey = this.makeKeyFn(key, index, trackExpr);
11129
+ const childByKey = /* @__PURE__ */ new Map();
11130
+ const remaining = /* @__PURE__ */ new Set();
11131
+ for (let i = 0; i < currentChildren.length; i++) {
11132
+ const child = currentChildren[i];
11133
+ const ctx = child.scope.resolveFlat(AreDirectiveContext);
11134
+ const k2 = ctx ? computeKey(ctx.scope[key], ctx.scope[index || "index"]) : /* @__PURE__ */ Symbol("orphan");
11135
+ childByKey.set(k2, child);
11136
+ remaining.add(child);
11137
+ }
11138
+ const desired = [];
11139
+ const newOnes = [];
11140
+ for (let i = 0; i < newArray.length; i++) {
11141
+ const item = newArray[i];
11142
+ const k2 = computeKey(item, i);
11143
+ const existing = childByKey.get(k2);
11144
+ if (existing) {
11145
+ remaining.delete(existing);
11146
+ let directiveContext = existing.scope.resolveFlat(AreDirectiveContext);
11147
+ if (!directiveContext) {
11148
+ directiveContext = new AreDirectiveContext(existing.aseid);
11149
+ existing.scope.register(directiveContext);
11150
+ }
11151
+ directiveContext.scope = {
11152
+ ...directiveContext.scope,
11153
+ [key]: item,
11154
+ [index || "index"]: i
11155
+ };
11156
+ desired.push(existing);
11157
+ } else {
11158
+ const itemNode = this.spawnItemNode(attribute.template, owner, key, index, item, i);
11159
+ desired.push(itemNode);
11160
+ newOnes.push(itemNode);
11316
11161
  }
11317
11162
  }
11318
- if (!componentName) {
11319
- const defaultAttr = root.attributes.find((attr) => attr.name === "default");
11320
- componentName = defaultAttr?.content;
11321
- }
11322
- if (!componentName) {
11323
- logger.warning('AreRoot: No component found for initial render. Please ensure a route condition or "default" attribute is set.');
11324
- return;
11325
- }
11326
- root.setContent(`<${componentName}></${componentName}>`);
11327
- }
11328
- async onSignal(root, vector, store, logger, signalsContext) {
11329
- console.log("Received signal vector in AreRoot:", root, vector);
11330
- const rootId = root.id;
11331
- if (signalsContext && !signalsContext.hasRoot(rootId)) {
11332
- return;
11333
- }
11334
- let renderTarget = signalsContext?.findComponentByVector(rootId, vector);
11335
- if (!renderTarget) {
11336
- const signalsMeta = c.meta(AreSignals);
11337
- renderTarget = signalsMeta?.findComponentByVector(vector);
11338
- }
11339
- const componentName = renderTarget?.name ? h.toKebabCase(renderTarget.name) : store.get("default");
11340
- if (!componentName) {
11341
- logger.warning("No component found for rendering in AreRoot. Please ensure that the signal vector matches at least one component or that a default component name is provided in the store.");
11342
- return;
11343
- }
11344
- root.setContent(`<${componentName}></${componentName}>`);
11345
- for (let i = 0; i < root.children.length; i++) {
11346
- const child = root.children[i];
11163
+ for (const child of remaining) {
11347
11164
  child.unmount();
11348
- child.destroy();
11349
- root.removeChild(child);
11165
+ owner.removeChild(child);
11350
11166
  }
11351
- root.tokenize();
11352
- for (let i = 0; i < root.children.length; i++) {
11353
- const child = root.children[i];
11354
- child.init();
11355
- const res = child.load();
11356
- if (res instanceof Promise) {
11357
- await res;
11358
- }
11167
+ for (const child of newOnes) {
11359
11168
  child.transform();
11360
11169
  child.compile();
11361
11170
  child.mount();
11362
11171
  }
11363
11172
  }
11173
+ // ─────────────────────────────────────────────────────────────────────────────
11174
+ // ── Helpers ──────────────────────────────────────────────────────────────────
11175
+ // ─────────────────────────────────────────────────────────────────────────────
11176
+ /**
11177
+ * Build a key-function that derives a stable identity from each item.
11178
+ * If the user provided a `track <expr>` clause, evaluate it as a path on
11179
+ * the item; otherwise fall back to the item identity (reference equality).
11180
+ */
11181
+ makeKeyFn(key, index, trackExpr) {
11182
+ if (!trackExpr) {
11183
+ return (item, i) => item ?? i;
11184
+ }
11185
+ const path = trackExpr.startsWith(key + ".") ? trackExpr.slice(key.length + 1) : trackExpr;
11186
+ return (item, i) => {
11187
+ if (item == null) return i;
11188
+ if (path === key || path === "$index") return path === "$index" ? i : item;
11189
+ const parts = path.split(".");
11190
+ let v2 = item;
11191
+ for (const p of parts) {
11192
+ if (v2 == null) return i;
11193
+ v2 = v2[p];
11194
+ }
11195
+ return v2 ?? i;
11196
+ };
11197
+ }
11198
+ /**
11199
+ * Parses the $for expression string into its constituent parts.
11200
+ *
11201
+ * Supported formats:
11202
+ * item in items
11203
+ * item, index in items
11204
+ * (item, index) in items
11205
+ * item in filter(items)
11206
+ * item, index in filter(items, 'active')
11207
+ * item in items track item.id
11208
+ * (item, i) in items track item.id
11209
+ */
11210
+ parseExpression(content) {
11211
+ let trackExpr;
11212
+ const trackIdx = content.search(/\s+track\s+/);
11213
+ let body = content;
11214
+ if (trackIdx !== -1) {
11215
+ const m2 = content.slice(trackIdx).match(/\s+track\s+(.+)$/);
11216
+ if (m2) {
11217
+ trackExpr = m2[1].trim();
11218
+ body = content.slice(0, trackIdx).trim();
11219
+ }
11220
+ }
11221
+ const inIndex = body.lastIndexOf(" in ");
11222
+ const keyAndIndex = body.slice(0, inIndex).trim().replace(/^\(|\)$/g, "");
11223
+ const arrayExpr = body.slice(inIndex + 4).trim();
11224
+ const keyParts = keyAndIndex.split(",").map((p) => p.trim());
11225
+ return {
11226
+ key: keyParts[0],
11227
+ index: keyParts[1] || void 0,
11228
+ arrayExpr,
11229
+ trackExpr
11230
+ };
11231
+ }
11232
+ /**
11233
+ * Resolves the array expression against the store.
11234
+ * Supports both plain key lookups and function-call expressions:
11235
+ * items → store.get('items')
11236
+ * filter(items) → store.get('filter')(store.get('items'))
11237
+ */
11238
+ resolveArray(store, arrayExpr, fullContent) {
11239
+ let result;
11240
+ const callMatch = arrayExpr.match(/^([^(]+)\((.+)\)$/);
11241
+ if (callMatch) {
11242
+ const fnName = callMatch[1].trim();
11243
+ const fn = store.get(fnName);
11244
+ if (typeof fn !== "function")
11245
+ throw new AreCompilerError({
11246
+ title: 'Invalid "for" Directive Function',
11247
+ description: `The expression "${fnName}" in the "for" directive does not resolve to a function in the store. Received: ${typeof fn}`
11248
+ });
11249
+ const rawArgs = callMatch[2].split(",").map((a2) => a2.trim());
11250
+ const resolvedArgs = rawArgs.map((arg) => {
11251
+ if (arg.startsWith("'") && arg.endsWith("'")) return arg.slice(1, -1);
11252
+ if (arg.startsWith('"') && arg.endsWith('"')) return arg.slice(1, -1);
11253
+ if (!isNaN(Number(arg))) return Number(arg);
11254
+ return store.get(arg);
11255
+ });
11256
+ result = fn(...resolvedArgs);
11257
+ } else {
11258
+ result = store.get(arrayExpr);
11259
+ }
11260
+ if (!Array.isArray(result))
11261
+ throw new AreCompilerError({
11262
+ title: 'Invalid "for" Directive Value',
11263
+ description: `The "for" directive expects an array but got ${typeof result}. Expression: "${fullContent}". Received: ${JSON.stringify(result)}`
11264
+ });
11265
+ return result;
11266
+ }
11267
+ /**
11268
+ * Creates a single item node from the template, registers it as a child of
11269
+ * the owner, initialises it, injects item-scoped store values, and activates
11270
+ * its scene so the mount/compile cycle will include it.
11271
+ *
11272
+ * NOTE: This method does NOT call compile() or mount() — the caller is
11273
+ * responsible for doing so when the main lifecycle cycle won't cover it
11274
+ * (i.e. during update, but not during the initial compile phase).
11275
+ */
11276
+ spawnItemNode(template, owner, key, index, item, i) {
11277
+ const itemNode = template.clone();
11278
+ owner.addChild(itemNode);
11279
+ const queue = [itemNode];
11280
+ while (queue.length > 0) {
11281
+ const current = queue.shift();
11282
+ current.init();
11283
+ queue.push(...current.children);
11284
+ }
11285
+ let directiveContext = itemNode.scope.resolveFlat(AreDirectiveContext);
11286
+ if (!directiveContext) {
11287
+ directiveContext = new AreDirectiveContext(itemNode.aseid);
11288
+ itemNode.scope.register(directiveContext);
11289
+ }
11290
+ directiveContext.scope = {
11291
+ ...directiveContext.scope,
11292
+ [key]: item,
11293
+ [index || "index"]: i
11294
+ };
11295
+ itemNode.scene.activate();
11296
+ return itemNode;
11297
+ }
11364
11298
  };
11365
- __name(AreRoot, "AreRoot");
11299
+ __name(AreDirectiveFor, "AreDirectiveFor");
11366
11300
  __decorateClass([
11367
- Are.Template,
11301
+ AreDirective.Transform,
11368
11302
  __decorateParam(0, ke(G)),
11369
- __decorateParam(1, ke(A_Logger)),
11370
- __decorateParam(2, ke(AreSignalsContext))
11371
- ], AreRoot.prototype, "template", 1);
11303
+ __decorateParam(1, ke(D)),
11304
+ __decorateParam(2, ke(AreStore)),
11305
+ __decorateParam(3, ke(AreScene)),
11306
+ __decorateParam(4, ke(A_Logger))
11307
+ ], AreDirectiveFor.prototype, "transform", 1);
11372
11308
  __decorateClass([
11373
- Are.Signal,
11309
+ AreDirective.Compile,
11374
11310
  __decorateParam(0, ke(G)),
11375
- __decorateParam(1, ke(A_SignalVector)),
11376
- __decorateParam(2, ke(AreStore)),
11377
- __decorateParam(3, ke(A_Logger)),
11378
- __decorateParam(4, ke(AreSignalsContext))
11379
- ], AreRoot.prototype, "onSignal", 1);
11380
- AreRoot = __decorateClass([
11381
- c2.Component({
11382
- namespace: "A-ARE",
11383
- name: "AreRoot",
11384
- 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."
11385
- })
11386
- ], AreRoot);
11311
+ __decorateParam(1, ke(AreStore)),
11312
+ __decorateParam(2, ke(AreScene))
11313
+ ], AreDirectiveFor.prototype, "compile", 1);
11314
+ __decorateClass([
11315
+ AreDirective.Update,
11316
+ __decorateParam(0, ke(G)),
11317
+ __decorateParam(1, ke(AreStore)),
11318
+ __decorateParam(2, ke(AreScene))
11319
+ ], AreDirectiveFor.prototype, "update", 1);
11320
+ AreDirectiveFor = __decorateClass([
11321
+ AreDirective.Priority(1)
11322
+ ], AreDirectiveFor);
11387
11323
 
11388
- // examples/dashboard/src/concept.ts
11324
+ // examples/jumpstart/src/concept.ts
11389
11325
  (async () => {
11390
11326
  try {
11391
11327
  const container = new AreContainer({
11392
- name: "ARE Dashboard",
11328
+ name: "ARE Jumpstart",
11393
11329
  components: [
11330
+ // ----------------------------------
11331
+ // Allowed Entities
11332
+ // ----------------------------------
11333
+ // ............
11334
+ // ----------------------------------
11335
+ // Allowed Commands
11336
+ // ----------------------------------
11337
+ // ............
11394
11338
  // ----------------------------------
11395
11339
  // UI Components
11396
11340
  // ----------------------------------
11397
- DashboardApp,
11398
- DashboardHeader,
11399
- DashboardLogo,
11400
- DashboardNav,
11401
- DashboardNavItem,
11402
- DashboardSidebar,
11403
- DashboardUserCard,
11404
- DashboardMenu,
11405
- DashboardMain,
11406
- DashboardStats,
11407
- DashboardStatCard,
11408
- DashboardTable,
11341
+ ABtn,
11342
+ ListComponent,
11409
11343
  // ----------------------------------
11410
- // Directives
11344
+ // Directives
11411
11345
  // ----------------------------------
11412
11346
  AreDirectiveIf,
11413
11347
  AreDirectiveFor,
11414
11348
  // ----------------------------------
11415
- // Addons
11349
+ // Engine Components
11416
11350
  // ----------------------------------
11417
11351
  A_SignalBus,
11352
+ // ----------------------------------
11353
+ // Addons
11354
+ // ----------------------------------
11418
11355
  AreRoot,
11419
11356
  ConfigReader,
11420
11357
  AreHTMLEngine,
11421
11358
  A_Logger
11422
11359
  ],
11423
11360
  entities: [
11361
+ // ............
11424
11362
  AreInit,
11425
11363
  AreRoute
11426
11364
  ],
11427
11365
  fragments: [
11428
- new AreHTMLEngineContext({ container: document }),
11366
+ new A_SignalState([AreRoute]),
11367
+ new AreHTMLEngineContext({
11368
+ container: document
11369
+ }),
11429
11370
  new A_Config({
11430
11371
  defaults: {
11431
11372
  [A_LOGGER_ENV_KEYS.LOG_LEVEL]: "info"
@@ -11434,7 +11375,7 @@ AreRoot = __decorateClass([
11434
11375
  ]
11435
11376
  });
11436
11377
  const concept = new Ce({
11437
- name: "adaas-are-example-dashboard",
11378
+ name: "adaas-are-example-jumpstart",
11438
11379
  fragments: [new A_Config({
11439
11380
  variables: ["CONFIG_VERBOSE", "DEV_MODE"],
11440
11381
  defaults: {
@@ -11445,7 +11386,9 @@ AreRoot = __decorateClass([
11445
11386
  components: [A_Logger, ConfigReader, A_Polyfill],
11446
11387
  containers: [container]
11447
11388
  });
11389
+ console.log("Building Concept...");
11448
11390
  await concept.load();
11391
+ console.log("\u2713 Concept loaded successfully.");
11449
11392
  await concept.start();
11450
11393
  } catch (error) {
11451
11394
  const logger = c.root.resolve(A_Logger);