@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.
- package/README.md +4 -4
- package/dist/browser/index.d.mts +88 -5
- package/dist/browser/index.mjs +542 -176
- package/dist/browser/index.mjs.map +1 -1
- package/dist/node/attributes/AreBinding.attribute.js +17 -4
- package/dist/node/attributes/AreBinding.attribute.js.map +1 -1
- package/dist/node/attributes/AreBinding.attribute.mjs +10 -3
- package/dist/node/attributes/AreBinding.attribute.mjs.map +1 -1
- package/dist/node/attributes/AreDirective.attribute.js +17 -4
- package/dist/node/attributes/AreDirective.attribute.js.map +1 -1
- package/dist/node/attributes/AreDirective.attribute.mjs +10 -3
- package/dist/node/attributes/AreDirective.attribute.mjs.map +1 -1
- package/dist/node/attributes/AreEvent.attribute.js +17 -4
- package/dist/node/attributes/AreEvent.attribute.js.map +1 -1
- package/dist/node/attributes/AreEvent.attribute.mjs +10 -3
- package/dist/node/attributes/AreEvent.attribute.mjs.map +1 -1
- package/dist/node/attributes/AreStatic.attribute.js +17 -4
- package/dist/node/attributes/AreStatic.attribute.js.map +1 -1
- package/dist/node/attributes/AreStatic.attribute.mjs +10 -3
- package/dist/node/attributes/AreStatic.attribute.mjs.map +1 -1
- package/dist/node/directives/AreDirectiveFor.directive.d.mts +8 -0
- package/dist/node/directives/AreDirectiveFor.directive.d.ts +8 -0
- package/dist/node/directives/AreDirectiveFor.directive.js +78 -33
- package/dist/node/directives/AreDirectiveFor.directive.js.map +1 -1
- package/dist/node/directives/AreDirectiveFor.directive.mjs +78 -33
- package/dist/node/directives/AreDirectiveFor.directive.mjs.map +1 -1
- package/dist/node/directives/AreDirectiveIf.directive.d.mts +18 -0
- package/dist/node/directives/AreDirectiveIf.directive.d.ts +18 -0
- package/dist/node/directives/AreDirectiveIf.directive.js +10 -3
- package/dist/node/directives/AreDirectiveIf.directive.js.map +1 -1
- package/dist/node/directives/AreDirectiveIf.directive.mjs +10 -3
- package/dist/node/directives/AreDirectiveIf.directive.mjs.map +1 -1
- package/dist/node/engine/AreHTML.compiler.d.mts +2 -2
- package/dist/node/engine/AreHTML.compiler.d.ts +2 -2
- package/dist/node/engine/AreHTML.compiler.js +57 -29
- package/dist/node/engine/AreHTML.compiler.js.map +1 -1
- package/dist/node/engine/AreHTML.compiler.mjs +58 -30
- package/dist/node/engine/AreHTML.compiler.mjs.map +1 -1
- package/dist/node/engine/AreHTML.constants.d.mts +53 -1
- package/dist/node/engine/AreHTML.constants.d.ts +53 -1
- package/dist/node/engine/AreHTML.constants.js +100 -0
- package/dist/node/engine/AreHTML.constants.js.map +1 -1
- package/dist/node/engine/AreHTML.constants.mjs +93 -0
- package/dist/node/engine/AreHTML.constants.mjs.map +1 -1
- package/dist/node/engine/AreHTML.context.d.mts +6 -2
- package/dist/node/engine/AreHTML.context.d.ts +6 -2
- package/dist/node/engine/AreHTML.context.js +42 -7
- package/dist/node/engine/AreHTML.context.js.map +1 -1
- package/dist/node/engine/AreHTML.context.mjs +35 -6
- package/dist/node/engine/AreHTML.context.mjs.map +1 -1
- package/dist/node/engine/AreHTML.engine.js +10 -7
- package/dist/node/engine/AreHTML.engine.js.map +1 -1
- package/dist/node/engine/AreHTML.engine.mjs +10 -7
- package/dist/node/engine/AreHTML.engine.mjs.map +1 -1
- package/dist/node/engine/AreHTML.interpreter.js +155 -43
- package/dist/node/engine/AreHTML.interpreter.js.map +1 -1
- package/dist/node/engine/AreHTML.interpreter.mjs +155 -43
- package/dist/node/engine/AreHTML.interpreter.mjs.map +1 -1
- package/dist/node/engine/AreHTML.lifecycle.js +17 -12
- package/dist/node/engine/AreHTML.lifecycle.js.map +1 -1
- package/dist/node/engine/AreHTML.lifecycle.mjs +9 -2
- package/dist/node/engine/AreHTML.lifecycle.mjs.map +1 -1
- package/dist/node/engine/AreHTML.tokenizer.js +14 -9
- package/dist/node/engine/AreHTML.tokenizer.js.map +1 -1
- package/dist/node/engine/AreHTML.tokenizer.mjs +10 -3
- package/dist/node/engine/AreHTML.tokenizer.mjs.map +1 -1
- package/dist/node/engine/AreHTML.transformer.js +13 -8
- package/dist/node/engine/AreHTML.transformer.js.map +1 -1
- package/dist/node/engine/AreHTML.transformer.mjs +9 -2
- package/dist/node/engine/AreHTML.transformer.mjs.map +1 -1
- package/dist/node/index.d.mts +2 -1
- package/dist/node/index.d.ts +2 -1
- package/dist/node/index.js +3 -3
- package/dist/node/index.mjs +1 -1
- package/dist/node/instructions/AddAttribute.instruction.js +3 -4
- package/dist/node/instructions/AddAttribute.instruction.js.map +1 -1
- package/dist/node/instructions/AddAttribute.instruction.mjs +3 -4
- package/dist/node/instructions/AddAttribute.instruction.mjs.map +1 -1
- package/dist/node/instructions/AddComment.instruction.js +3 -4
- package/dist/node/instructions/AddComment.instruction.js.map +1 -1
- package/dist/node/instructions/AddComment.instruction.mjs +3 -4
- package/dist/node/instructions/AddComment.instruction.mjs.map +1 -1
- package/dist/node/instructions/AddElement.instruction.js +3 -4
- package/dist/node/instructions/AddElement.instruction.js.map +1 -1
- package/dist/node/instructions/AddElement.instruction.mjs +3 -4
- package/dist/node/instructions/AddElement.instruction.mjs.map +1 -1
- package/dist/node/instructions/AddInterpolation.instruction.js +3 -4
- package/dist/node/instructions/AddInterpolation.instruction.js.map +1 -1
- package/dist/node/instructions/AddInterpolation.instruction.mjs +3 -4
- package/dist/node/instructions/AddInterpolation.instruction.mjs.map +1 -1
- package/dist/node/instructions/AddListener.instruction.js +3 -4
- package/dist/node/instructions/AddListener.instruction.js.map +1 -1
- package/dist/node/instructions/AddListener.instruction.mjs +3 -4
- package/dist/node/instructions/AddListener.instruction.mjs.map +1 -1
- package/dist/node/instructions/AddStyle.instruction.js +3 -4
- package/dist/node/instructions/AddStyle.instruction.js.map +1 -1
- package/dist/node/instructions/AddStyle.instruction.mjs +3 -4
- package/dist/node/instructions/AddStyle.instruction.mjs.map +1 -1
- package/dist/node/instructions/AddText.instruction.js +3 -4
- package/dist/node/instructions/AddText.instruction.js.map +1 -1
- package/dist/node/instructions/AddText.instruction.mjs +3 -4
- package/dist/node/instructions/AddText.instruction.mjs.map +1 -1
- package/dist/node/lib/AreDirective/AreDirective.component.js +5 -0
- package/dist/node/lib/AreDirective/AreDirective.component.js.map +1 -1
- package/dist/node/lib/AreDirective/AreDirective.component.mjs +5 -0
- package/dist/node/lib/AreDirective/AreDirective.component.mjs.map +1 -1
- package/dist/node/lib/AreHTMLAttribute/AreHTML.attribute.js +17 -4
- package/dist/node/lib/AreHTMLAttribute/AreHTML.attribute.js.map +1 -1
- package/dist/node/lib/AreHTMLAttribute/AreHTML.attribute.mjs +10 -3
- package/dist/node/lib/AreHTMLAttribute/AreHTML.attribute.mjs.map +1 -1
- package/dist/node/lib/AreHTMLNode/AreHTMLNode.js +3 -4
- package/dist/node/lib/AreHTMLNode/AreHTMLNode.js.map +1 -1
- package/dist/node/lib/AreHTMLNode/AreHTMLNode.mjs +3 -4
- package/dist/node/lib/AreHTMLNode/AreHTMLNode.mjs.map +1 -1
- package/dist/node/lib/AreRoot/AreRoot.component.js +3 -4
- package/dist/node/lib/AreRoot/AreRoot.component.js.map +1 -1
- package/dist/node/lib/AreRoot/AreRoot.component.mjs +3 -4
- package/dist/node/lib/AreRoot/AreRoot.component.mjs.map +1 -1
- package/dist/node/lib/{AreWatcher/AreWatcher.component.d.mts → AreRouteWatcher/AreRouteWatcher.component.d.mts} +2 -2
- package/dist/node/lib/{AreWatcher/AreWatcher.component.d.ts → AreRouteWatcher/AreRouteWatcher.component.d.ts} +2 -2
- package/dist/node/lib/{AreWatcher/AreWatcher.component.js → AreRouteWatcher/AreRouteWatcher.component.js} +9 -10
- package/dist/node/lib/AreRouteWatcher/AreRouteWatcher.component.js.map +1 -0
- package/dist/node/lib/{AreWatcher/AreWatcher.component.mjs → AreRouteWatcher/AreRouteWatcher.component.mjs} +10 -11
- package/dist/node/lib/AreRouteWatcher/AreRouteWatcher.component.mjs.map +1 -0
- package/dist/node/lib/AreStyle/AreStyle.context.js +17 -4
- package/dist/node/lib/AreStyle/AreStyle.context.js.map +1 -1
- package/dist/node/lib/AreStyle/AreStyle.context.mjs +10 -3
- package/dist/node/lib/AreStyle/AreStyle.context.mjs.map +1 -1
- package/dist/node/nodes/AreComment.js +17 -4
- package/dist/node/nodes/AreComment.js.map +1 -1
- package/dist/node/nodes/AreComment.mjs +10 -3
- package/dist/node/nodes/AreComment.mjs.map +1 -1
- package/dist/node/nodes/AreComponent.js +3 -4
- package/dist/node/nodes/AreComponent.js.map +1 -1
- package/dist/node/nodes/AreComponent.mjs +3 -4
- package/dist/node/nodes/AreComponent.mjs.map +1 -1
- package/dist/node/nodes/AreInterpolation.js +17 -4
- package/dist/node/nodes/AreInterpolation.js.map +1 -1
- package/dist/node/nodes/AreInterpolation.mjs +10 -3
- package/dist/node/nodes/AreInterpolation.mjs.map +1 -1
- package/dist/node/nodes/AreRoot.js +3 -4
- package/dist/node/nodes/AreRoot.js.map +1 -1
- package/dist/node/nodes/AreRoot.mjs +3 -4
- package/dist/node/nodes/AreRoot.mjs.map +1 -1
- package/dist/node/nodes/AreText.js +17 -4
- package/dist/node/nodes/AreText.js.map +1 -1
- package/dist/node/nodes/AreText.mjs +10 -3
- package/dist/node/nodes/AreText.mjs.map +1 -1
- package/dist/node/signals/AreRoute.signal.js +18 -5
- package/dist/node/signals/AreRoute.signal.js.map +1 -1
- package/dist/node/signals/AreRoute.signal.mjs +10 -3
- package/dist/node/signals/AreRoute.signal.mjs.map +1 -1
- package/docs/SYNTAX.md +714 -0
- package/docs/arehtml.monaco.json +235 -0
- package/docs/arehtml.monaco.ts +119 -0
- package/examples/dashboard/dist/index.html +1 -1
- package/examples/dashboard/dist/mpioi5ab-8c3oa9.js +13674 -0
- package/examples/jumpstart/dist/index.html +1 -1
- package/examples/{dashboard/dist/mnzfypsd-6zjt7w.js → jumpstart/dist/mor90p6y-0plg7g.js} +1869 -1926
- package/examples/jumpstart/dist/{mnpl1g4i-nobz9g.js → mor90p7p-1898bz.js} +2797 -2282
- package/examples/jumpstart/src/components/List.component.ts +14 -13
- package/examples/jumpstart/src/concept.ts +5 -4
- package/jest.config.ts +1 -1
- package/package.json +10 -6
- package/src/attributes/AreBinding.attribute.ts +5 -0
- package/src/attributes/AreDirective.attribute.ts +5 -0
- package/src/attributes/AreEvent.attribute.ts +5 -0
- package/src/attributes/AreStatic.attribute.ts +5 -0
- package/src/directives/AreDirectiveFor.directive.ts +97 -60
- package/src/directives/AreDirectiveIf.directive.ts +37 -15
- package/src/engine/AreHTML.compiler.ts +64 -36
- package/src/engine/AreHTML.constants.ts +144 -0
- package/src/engine/AreHTML.context.ts +33 -4
- package/src/engine/AreHTML.engine.ts +12 -7
- package/src/engine/AreHTML.interpreter.ts +195 -68
- package/src/engine/AreHTML.lifecycle.ts +5 -0
- package/src/engine/AreHTML.tokenizer.ts +6 -1
- package/src/engine/AreHTML.transformer.ts +5 -0
- package/src/index.ts +2 -2
- package/src/instructions/AddAttribute.instruction.ts +3 -4
- package/src/instructions/AddComment.instruction.ts +3 -4
- package/src/instructions/AddElement.instruction.ts +3 -4
- package/src/instructions/AddInterpolation.instruction.ts +3 -4
- package/src/instructions/AddListener.instruction.ts +3 -4
- package/src/instructions/AddStyle.instruction.ts +3 -4
- package/src/instructions/AddText.instruction.ts +3 -4
- package/src/lib/AreDirective/AreDirective.component.ts +5 -0
- package/src/lib/AreHTMLAttribute/AreHTML.attribute.ts +5 -0
- package/src/lib/AreHTMLNode/AreHTMLNode.ts +3 -4
- package/src/lib/AreRoot/AreRoot.component.ts +3 -4
- package/src/lib/{AreWatcher/AreWatcher.component.ts → AreRouteWatcher/AreRouteWatcher.component.ts} +5 -6
- package/src/lib/AreStyle/AreStyle.context.ts +5 -0
- package/src/nodes/AreComment.ts +5 -0
- package/src/nodes/AreComponent.ts +3 -4
- package/src/nodes/AreInterpolation.ts +5 -0
- package/src/nodes/AreRoot.ts +3 -4
- package/src/nodes/AreText.ts +5 -0
- package/src/signals/AreRoute.signal.ts +5 -0
- package/dist/node/lib/AreWatcher/AreWatcher.component.js.map +0 -1
- package/dist/node/lib/AreWatcher/AreWatcher.component.mjs.map +0 -1
|
@@ -1,15 +1,28 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var attribute = require('@adaas/are-html/attribute');
|
|
4
|
+
var core = require('@adaas/a-frame/core');
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
7
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
8
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
9
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
10
|
+
if (decorator = decorators[i])
|
|
11
|
+
result = (decorator(result)) || result;
|
|
12
|
+
return result;
|
|
13
|
+
};
|
|
14
|
+
exports.AreBindingAttribute = class AreBindingAttribute extends attribute.AreHTMLAttribute {
|
|
6
15
|
// get value(): string {
|
|
7
16
|
// const [firstPart, ...pathPart] = this.content.split('.');
|
|
8
17
|
// const primaryObject = this.owner.store.get(firstPart);
|
|
9
18
|
// return AreCommonHelper.extractPropertyByPath(primaryObject, pathPart.join('.')) as string;
|
|
10
19
|
// }
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
|
|
20
|
+
};
|
|
21
|
+
exports.AreBindingAttribute = __decorateClass([
|
|
22
|
+
core.A_Frame.Define({
|
|
23
|
+
namespace: "a-are-html",
|
|
24
|
+
description: "Attribute type for two-way value bindings (: prefix). Marks that the attribute value should be resolved dynamically from the node store rather than used verbatim, enabling reactive updates whenever the underlying store value changes during a rendering cycle."
|
|
25
|
+
})
|
|
26
|
+
], exports.AreBindingAttribute);
|
|
14
27
|
//# sourceMappingURL=AreBinding.attribute.js.map
|
|
15
28
|
//# sourceMappingURL=AreBinding.attribute.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/attributes/AreBinding.attribute.ts"],"names":["AreHTMLAttribute"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../../src/attributes/AreBinding.attribute.ts"],"names":["AreBindingAttribute","AreHTMLAttribute","A_Frame"],"mappings":";;;;;;;;;;;;;AAYaA,2BAAA,GAAN,kCAAkCC,0BAAA,CAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAW1D;AAXaD,2BAAA,GAAN,eAAA,CAAA;AAAA,EAJNE,aAAQ,MAAA,CAAO;AAAA,IACZ,SAAA,EAAW,YAAA;AAAA,IACX,WAAA,EAAa;AAAA,GAChB;AAAA,CAAA,EACYF,2BAAA,CAAA","file":"AreBinding.attribute.js","sourcesContent":["import { AreHTMLAttribute } from \"@adaas/are-html/attribute\";\nimport { A_Frame } from \"@adaas/a-frame/core\";\n\n\n\n\n\n\n@A_Frame.Define({\n namespace: 'a-are-html',\n description: 'Attribute type for two-way value bindings (: prefix). Marks that the attribute value should be resolved dynamically from the node store rather than used verbatim, enabling reactive updates whenever the underlying store value changes during a rendering cycle.'\n})\nexport class AreBindingAttribute extends AreHTMLAttribute {\n\n // get value(): string {\n\n // const [firstPart, ...pathPart] = this.content.split('.');\n\n // const primaryObject = this.owner.store.get(firstPart);\n\n // return AreCommonHelper.extractPropertyByPath(primaryObject, pathPart.join('.')) as string;\n // }\n\n}\n"]}
|
|
@@ -1,13 +1,20 @@
|
|
|
1
|
-
import '../chunk-EQQGB2QZ.mjs';
|
|
1
|
+
import { __decorateClass } from '../chunk-EQQGB2QZ.mjs';
|
|
2
2
|
import { AreHTMLAttribute } from '@adaas/are-html/attribute';
|
|
3
|
+
import { A_Frame } from '@adaas/a-frame/core';
|
|
3
4
|
|
|
4
|
-
|
|
5
|
+
let AreBindingAttribute = class extends AreHTMLAttribute {
|
|
5
6
|
// get value(): string {
|
|
6
7
|
// const [firstPart, ...pathPart] = this.content.split('.');
|
|
7
8
|
// const primaryObject = this.owner.store.get(firstPart);
|
|
8
9
|
// return AreCommonHelper.extractPropertyByPath(primaryObject, pathPart.join('.')) as string;
|
|
9
10
|
// }
|
|
10
|
-
}
|
|
11
|
+
};
|
|
12
|
+
AreBindingAttribute = __decorateClass([
|
|
13
|
+
A_Frame.Define({
|
|
14
|
+
namespace: "a-are-html",
|
|
15
|
+
description: "Attribute type for two-way value bindings (: prefix). Marks that the attribute value should be resolved dynamically from the node store rather than used verbatim, enabling reactive updates whenever the underlying store value changes during a rendering cycle."
|
|
16
|
+
})
|
|
17
|
+
], AreBindingAttribute);
|
|
11
18
|
|
|
12
19
|
export { AreBindingAttribute };
|
|
13
20
|
//# sourceMappingURL=AreBinding.attribute.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/attributes/AreBinding.attribute.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../../src/attributes/AreBinding.attribute.ts"],"names":[],"mappings":";;;;AAYO,IAAM,mBAAA,GAAN,cAAkC,gBAAA,CAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAW1D;AAXa,mBAAA,GAAN,eAAA,CAAA;AAAA,EAJN,QAAQ,MAAA,CAAO;AAAA,IACZ,SAAA,EAAW,YAAA;AAAA,IACX,WAAA,EAAa;AAAA,GAChB;AAAA,CAAA,EACY,mBAAA,CAAA","file":"AreBinding.attribute.mjs","sourcesContent":["import { AreHTMLAttribute } from \"@adaas/are-html/attribute\";\nimport { A_Frame } from \"@adaas/a-frame/core\";\n\n\n\n\n\n\n@A_Frame.Define({\n namespace: 'a-are-html',\n description: 'Attribute type for two-way value bindings (: prefix). Marks that the attribute value should be resolved dynamically from the node store rather than used verbatim, enabling reactive updates whenever the underlying store value changes during a rendering cycle.'\n})\nexport class AreBindingAttribute extends AreHTMLAttribute {\n\n // get value(): string {\n\n // const [firstPart, ...pathPart] = this.content.split('.');\n\n // const primaryObject = this.owner.store.get(firstPart);\n\n // return AreCommonHelper.extractPropertyByPath(primaryObject, pathPart.join('.')) as string;\n // }\n\n}\n"]}
|
|
@@ -2,8 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
var aConcept = require('@adaas/a-concept');
|
|
4
4
|
var attribute = require('@adaas/are-html/attribute');
|
|
5
|
+
var core = require('@adaas/a-frame/core');
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
8
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
9
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
10
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
11
|
+
if (decorator = decorators[i])
|
|
12
|
+
result = (decorator(result)) || result;
|
|
13
|
+
return result;
|
|
14
|
+
};
|
|
15
|
+
exports.AreDirectiveAttribute = class AreDirectiveAttribute extends attribute.AreHTMLAttribute {
|
|
7
16
|
/**
|
|
8
17
|
* Returns a custom directive component associated with this attribute, if available.
|
|
9
18
|
*
|
|
@@ -13,8 +22,12 @@ class AreDirectiveAttribute extends attribute.AreHTMLAttribute {
|
|
|
13
22
|
const component = this.scope.resolve(`AreDirective${aConcept.A_FormatterHelper.toPascalCase(this.name)}`);
|
|
14
23
|
return component;
|
|
15
24
|
}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
|
|
25
|
+
};
|
|
26
|
+
exports.AreDirectiveAttribute = __decorateClass([
|
|
27
|
+
core.A_Frame.Define({
|
|
28
|
+
namespace: "a-are-html",
|
|
29
|
+
description: "Attribute type for directive invocations ($ prefix). Carries the resolved directive component class and a cloned template node. The associated directive uses these during its Compile phase to emit conditional or repeated instruction groups and to manage per-item or per-condition subscopes."
|
|
30
|
+
})
|
|
31
|
+
], exports.AreDirectiveAttribute);
|
|
19
32
|
//# sourceMappingURL=AreDirective.attribute.js.map
|
|
20
33
|
//# sourceMappingURL=AreDirective.attribute.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/attributes/AreDirective.attribute.ts"],"names":["AreHTMLAttribute","A_FormatterHelper"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../../src/attributes/AreDirective.attribute.ts"],"names":["AreDirectiveAttribute","AreHTMLAttribute","A_FormatterHelper","A_Frame"],"mappings":";;;;;;;;;;;;;;AAaaA,6BAAA,GAAN,oCAAoCC,0BAAA,CAAmD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAW1F,IAAI,SAAA,GAAsC;AACtC,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,KAAA,CAAM,OAAA,CAAsB,CAAA,YAAA,EAAeC,2BAAkB,YAAA,CAAa,IAAA,CAAK,IAAI,CAAC,CAAA,CAAE,CAAA;AAE7G,IAAA,OAAO,SAAA;AAAA,EACX;AAEJ;AAjBaF,6BAAA,GAAN,eAAA,CAAA;AAAA,EAJNG,aAAQ,MAAA,CAAO;AAAA,IACZ,SAAA,EAAW,YAAA;AAAA,IACX,WAAA,EAAa;AAAA,GAChB;AAAA,CAAA,EACYH,6BAAA,CAAA","file":"AreDirective.attribute.js","sourcesContent":["import { A_FormatterHelper } from \"@adaas/a-concept\";\nimport type { AreDirective } from \"@adaas/are-html/directive/AreDirective.component\";\nimport { AreHTMLAttribute } from \"@adaas/are-html/attribute\";\nimport { AreStoreWatchingEntity } from \"@adaas/are\";\nimport { AreHTMLNode } from \"@adaas/are-html/node\";\nimport { A_Frame } from \"@adaas/a-frame/core\";\n\n\n\n@A_Frame.Define({\n namespace: 'a-are-html',\n description: 'Attribute type for directive invocations ($ prefix). Carries the resolved directive component class and a cloned template node. The associated directive uses these during its Compile phase to emit conditional or repeated instruction groups and to manage per-item or per-condition subscopes.'\n})\nexport class AreDirectiveAttribute extends AreHTMLAttribute implements AreStoreWatchingEntity {\n\n cache?: any\n\n template?: AreHTMLNode\n\n /**\n * Returns a custom directive component associated with this attribute, if available.\n * \n * 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.\n */\n get component(): AreDirective | undefined {\n const component = this.scope.resolve<AreDirective>(`AreDirective${A_FormatterHelper.toPascalCase(this.name)}`) as AreDirective | undefined;\n\n return component as AreDirective;\n }\n\n}"]}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import '../chunk-EQQGB2QZ.mjs';
|
|
1
|
+
import { __decorateClass } from '../chunk-EQQGB2QZ.mjs';
|
|
2
2
|
import { A_FormatterHelper } from '@adaas/a-concept';
|
|
3
3
|
import { AreHTMLAttribute } from '@adaas/are-html/attribute';
|
|
4
|
+
import { A_Frame } from '@adaas/a-frame/core';
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
let AreDirectiveAttribute = class extends AreHTMLAttribute {
|
|
6
7
|
/**
|
|
7
8
|
* Returns a custom directive component associated with this attribute, if available.
|
|
8
9
|
*
|
|
@@ -12,7 +13,13 @@ class AreDirectiveAttribute extends AreHTMLAttribute {
|
|
|
12
13
|
const component = this.scope.resolve(`AreDirective${A_FormatterHelper.toPascalCase(this.name)}`);
|
|
13
14
|
return component;
|
|
14
15
|
}
|
|
15
|
-
}
|
|
16
|
+
};
|
|
17
|
+
AreDirectiveAttribute = __decorateClass([
|
|
18
|
+
A_Frame.Define({
|
|
19
|
+
namespace: "a-are-html",
|
|
20
|
+
description: "Attribute type for directive invocations ($ prefix). Carries the resolved directive component class and a cloned template node. The associated directive uses these during its Compile phase to emit conditional or repeated instruction groups and to manage per-item or per-condition subscopes."
|
|
21
|
+
})
|
|
22
|
+
], AreDirectiveAttribute);
|
|
16
23
|
|
|
17
24
|
export { AreDirectiveAttribute };
|
|
18
25
|
//# sourceMappingURL=AreDirective.attribute.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/attributes/AreDirective.attribute.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../../src/attributes/AreDirective.attribute.ts"],"names":[],"mappings":";;;;;AAaO,IAAM,qBAAA,GAAN,cAAoC,gBAAA,CAAmD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAW1F,IAAI,SAAA,GAAsC;AACtC,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,KAAA,CAAM,OAAA,CAAsB,CAAA,YAAA,EAAe,kBAAkB,YAAA,CAAa,IAAA,CAAK,IAAI,CAAC,CAAA,CAAE,CAAA;AAE7G,IAAA,OAAO,SAAA;AAAA,EACX;AAEJ;AAjBa,qBAAA,GAAN,eAAA,CAAA;AAAA,EAJN,QAAQ,MAAA,CAAO;AAAA,IACZ,SAAA,EAAW,YAAA;AAAA,IACX,WAAA,EAAa;AAAA,GAChB;AAAA,CAAA,EACY,qBAAA,CAAA","file":"AreDirective.attribute.mjs","sourcesContent":["import { A_FormatterHelper } from \"@adaas/a-concept\";\nimport type { AreDirective } from \"@adaas/are-html/directive/AreDirective.component\";\nimport { AreHTMLAttribute } from \"@adaas/are-html/attribute\";\nimport { AreStoreWatchingEntity } from \"@adaas/are\";\nimport { AreHTMLNode } from \"@adaas/are-html/node\";\nimport { A_Frame } from \"@adaas/a-frame/core\";\n\n\n\n@A_Frame.Define({\n namespace: 'a-are-html',\n description: 'Attribute type for directive invocations ($ prefix). Carries the resolved directive component class and a cloned template node. The associated directive uses these during its Compile phase to emit conditional or repeated instruction groups and to manage per-item or per-condition subscopes.'\n})\nexport class AreDirectiveAttribute extends AreHTMLAttribute implements AreStoreWatchingEntity {\n\n cache?: any\n\n template?: AreHTMLNode\n\n /**\n * Returns a custom directive component associated with this attribute, if available.\n * \n * 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.\n */\n get component(): AreDirective | undefined {\n const component = this.scope.resolve<AreDirective>(`AreDirective${A_FormatterHelper.toPascalCase(this.name)}`) as AreDirective | undefined;\n\n return component as AreDirective;\n }\n\n}"]}
|
|
@@ -1,10 +1,23 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var attribute = require('@adaas/are-html/attribute');
|
|
4
|
+
var core = require('@adaas/a-frame/core');
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
7
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
8
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
9
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
10
|
+
if (decorator = decorators[i])
|
|
11
|
+
result = (decorator(result)) || result;
|
|
12
|
+
return result;
|
|
13
|
+
};
|
|
14
|
+
exports.AreEventAttribute = class AreEventAttribute extends attribute.AreHTMLAttribute {
|
|
15
|
+
};
|
|
16
|
+
exports.AreEventAttribute = __decorateClass([
|
|
17
|
+
core.A_Frame.Define({
|
|
18
|
+
namespace: "a-are-html",
|
|
19
|
+
description: "Attribute type for DOM event listeners (@ prefix). Marks the attribute as an event binding \u2014 the compiler emits an AddListener instruction that attaches a handler expression resolved from the store to the specified event name on the host element."
|
|
20
|
+
})
|
|
21
|
+
], exports.AreEventAttribute);
|
|
9
22
|
//# sourceMappingURL=AreEvent.attribute.js.map
|
|
10
23
|
//# sourceMappingURL=AreEvent.attribute.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/attributes/AreEvent.attribute.ts"],"names":["AreHTMLAttribute"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../../src/attributes/AreEvent.attribute.ts"],"names":["AreEventAttribute","AreHTMLAttribute","A_Frame"],"mappings":";;;;;;;;;;;;;AAQaA,yBAAA,GAAN,gCAAgCC,0BAAA,CAAiB;AACxD;AADaD,yBAAA,GAAN,eAAA,CAAA;AAAA,EAJNE,aAAQ,MAAA,CAAO;AAAA,IACZ,SAAA,EAAW,YAAA;AAAA,IACX,WAAA,EAAa;AAAA,GAChB;AAAA,CAAA,EACYF,yBAAA,CAAA","file":"AreEvent.attribute.js","sourcesContent":["import { AreHTMLAttribute } from \"@adaas/are-html/attribute\";\nimport { A_Frame } from \"@adaas/a-frame/core\";\n\n\n@A_Frame.Define({\n namespace: 'a-are-html',\n description: 'Attribute type for DOM event listeners (@ prefix). Marks the attribute as an event binding — the compiler emits an AddListener instruction that attaches a handler expression resolved from the store to the specified event name on the host element.'\n})\nexport class AreEventAttribute extends AreHTMLAttribute {\n}"]}
|
|
@@ -1,8 +1,15 @@
|
|
|
1
|
-
import '../chunk-EQQGB2QZ.mjs';
|
|
1
|
+
import { __decorateClass } from '../chunk-EQQGB2QZ.mjs';
|
|
2
2
|
import { AreHTMLAttribute } from '@adaas/are-html/attribute';
|
|
3
|
+
import { A_Frame } from '@adaas/a-frame/core';
|
|
3
4
|
|
|
4
|
-
|
|
5
|
-
}
|
|
5
|
+
let AreEventAttribute = class extends AreHTMLAttribute {
|
|
6
|
+
};
|
|
7
|
+
AreEventAttribute = __decorateClass([
|
|
8
|
+
A_Frame.Define({
|
|
9
|
+
namespace: "a-are-html",
|
|
10
|
+
description: "Attribute type for DOM event listeners (@ prefix). Marks the attribute as an event binding \u2014 the compiler emits an AddListener instruction that attaches a handler expression resolved from the store to the specified event name on the host element."
|
|
11
|
+
})
|
|
12
|
+
], AreEventAttribute);
|
|
6
13
|
|
|
7
14
|
export { AreEventAttribute };
|
|
8
15
|
//# sourceMappingURL=AreEvent.attribute.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/attributes/AreEvent.attribute.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../../src/attributes/AreEvent.attribute.ts"],"names":[],"mappings":";;;;AAQO,IAAM,iBAAA,GAAN,cAAgC,gBAAA,CAAiB;AACxD;AADa,iBAAA,GAAN,eAAA,CAAA;AAAA,EAJN,QAAQ,MAAA,CAAO;AAAA,IACZ,SAAA,EAAW,YAAA;AAAA,IACX,WAAA,EAAa;AAAA,GAChB;AAAA,CAAA,EACY,iBAAA,CAAA","file":"AreEvent.attribute.mjs","sourcesContent":["import { AreHTMLAttribute } from \"@adaas/are-html/attribute\";\nimport { A_Frame } from \"@adaas/a-frame/core\";\n\n\n@A_Frame.Define({\n namespace: 'a-are-html',\n description: 'Attribute type for DOM event listeners (@ prefix). Marks the attribute as an event binding — the compiler emits an AddListener instruction that attaches a handler expression resolved from the store to the specified event name on the host element.'\n})\nexport class AreEventAttribute extends AreHTMLAttribute {\n}"]}
|
|
@@ -1,10 +1,23 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var attribute = require('@adaas/are-html/attribute');
|
|
4
|
+
var core = require('@adaas/a-frame/core');
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
7
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
8
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
9
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
10
|
+
if (decorator = decorators[i])
|
|
11
|
+
result = (decorator(result)) || result;
|
|
12
|
+
return result;
|
|
13
|
+
};
|
|
14
|
+
exports.AreStaticAttribute = class AreStaticAttribute extends attribute.AreHTMLAttribute {
|
|
15
|
+
};
|
|
16
|
+
exports.AreStaticAttribute = __decorateClass([
|
|
17
|
+
core.A_Frame.Define({
|
|
18
|
+
namespace: "a-are-html",
|
|
19
|
+
description: "Attribute type for plain static HTML attributes with no dynamic prefix. Its value is emitted verbatim via an AddAttribute instruction at compile time and does not participate in reactive update cycles."
|
|
20
|
+
})
|
|
21
|
+
], exports.AreStaticAttribute);
|
|
9
22
|
//# sourceMappingURL=AreStatic.attribute.js.map
|
|
10
23
|
//# sourceMappingURL=AreStatic.attribute.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/attributes/AreStatic.attribute.ts"],"names":["AreHTMLAttribute"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../../src/attributes/AreStatic.attribute.ts"],"names":["AreStaticAttribute","AreHTMLAttribute","A_Frame"],"mappings":";;;;;;;;;;;;;AAQaA,0BAAA,GAAN,iCAAiCC,0BAAA,CAAiB;AAEzD;AAFaD,0BAAA,GAAN,eAAA,CAAA;AAAA,EAJNE,aAAQ,MAAA,CAAO;AAAA,IACZ,SAAA,EAAW,YAAA;AAAA,IACX,WAAA,EAAa;AAAA,GAChB;AAAA,CAAA,EACYF,0BAAA,CAAA","file":"AreStatic.attribute.js","sourcesContent":["import { AreHTMLAttribute } from \"@adaas/are-html/attribute\";\nimport { A_Frame } from \"@adaas/a-frame/core\";\n\n\n@A_Frame.Define({\n namespace: 'a-are-html',\n description: 'Attribute type for plain static HTML attributes with no dynamic prefix. Its value is emitted verbatim via an AddAttribute instruction at compile time and does not participate in reactive update cycles.'\n})\nexport class AreStaticAttribute extends AreHTMLAttribute {\n\n}"]}
|
|
@@ -1,8 +1,15 @@
|
|
|
1
|
-
import '../chunk-EQQGB2QZ.mjs';
|
|
1
|
+
import { __decorateClass } from '../chunk-EQQGB2QZ.mjs';
|
|
2
2
|
import { AreHTMLAttribute } from '@adaas/are-html/attribute';
|
|
3
|
+
import { A_Frame } from '@adaas/a-frame/core';
|
|
3
4
|
|
|
4
|
-
|
|
5
|
-
}
|
|
5
|
+
let AreStaticAttribute = class extends AreHTMLAttribute {
|
|
6
|
+
};
|
|
7
|
+
AreStaticAttribute = __decorateClass([
|
|
8
|
+
A_Frame.Define({
|
|
9
|
+
namespace: "a-are-html",
|
|
10
|
+
description: "Attribute type for plain static HTML attributes with no dynamic prefix. Its value is emitted verbatim via an AddAttribute instruction at compile time and does not participate in reactive update cycles."
|
|
11
|
+
})
|
|
12
|
+
], AreStaticAttribute);
|
|
6
13
|
|
|
7
14
|
export { AreStaticAttribute };
|
|
8
15
|
//# sourceMappingURL=AreStatic.attribute.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/attributes/AreStatic.attribute.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../../src/attributes/AreStatic.attribute.ts"],"names":[],"mappings":";;;;AAQO,IAAM,kBAAA,GAAN,cAAiC,gBAAA,CAAiB;AAEzD;AAFa,kBAAA,GAAN,eAAA,CAAA;AAAA,EAJN,QAAQ,MAAA,CAAO;AAAA,IACZ,SAAA,EAAW,YAAA;AAAA,IACX,WAAA,EAAa;AAAA,GAChB;AAAA,CAAA,EACY,kBAAA,CAAA","file":"AreStatic.attribute.mjs","sourcesContent":["import { AreHTMLAttribute } from \"@adaas/are-html/attribute\";\nimport { A_Frame } from \"@adaas/a-frame/core\";\n\n\n@A_Frame.Define({\n namespace: 'a-are-html',\n description: 'Attribute type for plain static HTML attributes with no dynamic prefix. Its value is emitted verbatim via an AddAttribute instruction at compile time and does not participate in reactive update cycles.'\n})\nexport class AreStaticAttribute extends AreHTMLAttribute {\n\n}"]}
|
|
@@ -8,6 +8,12 @@ declare class AreDirectiveFor extends AreDirective {
|
|
|
8
8
|
transform(attribute: AreDirectiveAttribute, scope: A_Scope, store: AreStore, scene: AreScene, logger: A_Logger, ...args: any[]): void;
|
|
9
9
|
compile(attribute: AreDirectiveAttribute, store: AreStore, scene: AreScene, ...args: any[]): void;
|
|
10
10
|
update(attribute: AreDirectiveAttribute, store: AreStore, scene: AreScene, ...args: any[]): void;
|
|
11
|
+
/**
|
|
12
|
+
* Build a key-function that derives a stable identity from each item.
|
|
13
|
+
* If the user provided a `track <expr>` clause, evaluate it as a path on
|
|
14
|
+
* the item; otherwise fall back to the item identity (reference equality).
|
|
15
|
+
*/
|
|
16
|
+
private makeKeyFn;
|
|
11
17
|
/**
|
|
12
18
|
* Parses the $for expression string into its constituent parts.
|
|
13
19
|
*
|
|
@@ -17,6 +23,8 @@ declare class AreDirectiveFor extends AreDirective {
|
|
|
17
23
|
* (item, index) in items
|
|
18
24
|
* item in filter(items)
|
|
19
25
|
* item, index in filter(items, 'active')
|
|
26
|
+
* item in items track item.id
|
|
27
|
+
* (item, i) in items track item.id
|
|
20
28
|
*/
|
|
21
29
|
private parseExpression;
|
|
22
30
|
/**
|
|
@@ -8,6 +8,12 @@ declare class AreDirectiveFor extends AreDirective {
|
|
|
8
8
|
transform(attribute: AreDirectiveAttribute, scope: A_Scope, store: AreStore, scene: AreScene, logger: A_Logger, ...args: any[]): void;
|
|
9
9
|
compile(attribute: AreDirectiveAttribute, store: AreStore, scene: AreScene, ...args: any[]): void;
|
|
10
10
|
update(attribute: AreDirectiveAttribute, store: AreStore, scene: AreScene, ...args: any[]): void;
|
|
11
|
+
/**
|
|
12
|
+
* Build a key-function that derives a stable identity from each item.
|
|
13
|
+
* If the user provided a `track <expr>` clause, evaluate it as a path on
|
|
14
|
+
* the item; otherwise fall back to the item identity (reference equality).
|
|
15
|
+
*/
|
|
16
|
+
private makeKeyFn;
|
|
11
17
|
/**
|
|
12
18
|
* Parses the $for expression string into its constituent parts.
|
|
13
19
|
*
|
|
@@ -17,6 +23,8 @@ declare class AreDirectiveFor extends AreDirective {
|
|
|
17
23
|
* (item, index) in items
|
|
18
24
|
* item in filter(items)
|
|
19
25
|
* item, index in filter(items, 'active')
|
|
26
|
+
* item in items track item.id
|
|
27
|
+
* (item, i) in items track item.id
|
|
20
28
|
*/
|
|
21
29
|
private parseExpression;
|
|
22
30
|
/**
|
|
@@ -6,6 +6,7 @@ var are = require('@adaas/are');
|
|
|
6
6
|
var AreDirective_component = require('@adaas/are-html/directive/AreDirective.component');
|
|
7
7
|
var AddComment_instruction = require('@adaas/are-html/instructions/AddComment.instruction');
|
|
8
8
|
var AreDirective_context = require('@adaas/are-html/directive/AreDirective.context');
|
|
9
|
+
var core = require('@adaas/a-frame/core');
|
|
9
10
|
|
|
10
11
|
var __defProp = Object.defineProperty;
|
|
11
12
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -33,11 +34,9 @@ exports.AreDirectiveFor = class AreDirectiveFor extends AreDirective_component.A
|
|
|
33
34
|
const { key, index, arrayExpr } = this.parseExpression(attribute.content);
|
|
34
35
|
const array = this.resolveArray(store, arrayExpr, attribute.content);
|
|
35
36
|
attribute.value = array;
|
|
36
|
-
console.log('Initial array for "for" directive:', scene);
|
|
37
37
|
for (let i = 0; i < array.length; i++) {
|
|
38
38
|
this.spawnItemNode(attribute.template, attribute.owner, key, index, array[i], i);
|
|
39
39
|
}
|
|
40
|
-
console.log('Template for "for" directive:', forTemplate);
|
|
41
40
|
}
|
|
42
41
|
compile(attribute, store, scene, ...args) {
|
|
43
42
|
const hostInstruction = scene.host;
|
|
@@ -48,49 +47,78 @@ exports.AreDirectiveFor = class AreDirectiveFor extends AreDirective_component.A
|
|
|
48
47
|
scene.unPlan(hostInstruction);
|
|
49
48
|
}
|
|
50
49
|
update(attribute, store, scene, ...args) {
|
|
51
|
-
const { key, index, arrayExpr } = this.parseExpression(attribute.content);
|
|
50
|
+
const { key, index, arrayExpr, trackExpr } = this.parseExpression(attribute.content);
|
|
52
51
|
const newArray = this.resolveArray(store, arrayExpr, attribute.content);
|
|
53
52
|
const owner = attribute.owner;
|
|
54
53
|
const currentChildren = [...owner.children];
|
|
55
54
|
attribute.value = newArray;
|
|
56
|
-
const
|
|
57
|
-
const
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
55
|
+
const computeKey = this.makeKeyFn(key, index, trackExpr);
|
|
56
|
+
const childByKey = /* @__PURE__ */ new Map();
|
|
57
|
+
const remaining = /* @__PURE__ */ new Set();
|
|
58
|
+
for (let i = 0; i < currentChildren.length; i++) {
|
|
59
|
+
const child = currentChildren[i];
|
|
61
60
|
const ctx = child.scope.resolveFlat(AreDirective_context.AreDirectiveContext);
|
|
62
|
-
|
|
63
|
-
|
|
61
|
+
const k = ctx ? computeKey(ctx.scope[key], ctx.scope[index || "index"]) : /* @__PURE__ */ Symbol("orphan");
|
|
62
|
+
childByKey.set(k, child);
|
|
63
|
+
remaining.add(child);
|
|
64
|
+
}
|
|
65
|
+
const newOnes = [];
|
|
66
|
+
for (let i = 0; i < newArray.length; i++) {
|
|
67
|
+
const item = newArray[i];
|
|
68
|
+
const k = computeKey(item, i);
|
|
69
|
+
const existing = childByKey.get(k);
|
|
70
|
+
if (existing) {
|
|
71
|
+
remaining.delete(existing);
|
|
72
|
+
let directiveContext = existing.scope.resolveFlat(AreDirective_context.AreDirectiveContext);
|
|
73
|
+
if (!directiveContext) {
|
|
74
|
+
directiveContext = new AreDirective_context.AreDirectiveContext(existing.aseid);
|
|
75
|
+
existing.scope.register(directiveContext);
|
|
76
|
+
}
|
|
77
|
+
directiveContext.scope = {
|
|
78
|
+
...directiveContext.scope,
|
|
79
|
+
[key]: item,
|
|
80
|
+
[index || "index"]: i
|
|
81
|
+
};
|
|
64
82
|
} else {
|
|
65
|
-
|
|
83
|
+
const itemNode = this.spawnItemNode(attribute.template, owner, key, index, item, i);
|
|
84
|
+
newOnes.push(itemNode);
|
|
66
85
|
}
|
|
67
86
|
}
|
|
68
|
-
for (const child of
|
|
87
|
+
for (const child of remaining) {
|
|
69
88
|
child.unmount();
|
|
70
89
|
owner.removeChild(child);
|
|
71
90
|
}
|
|
72
|
-
for (
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
keptChildren[i].scope.register(directiveContext);
|
|
77
|
-
}
|
|
78
|
-
directiveContext.scope = {
|
|
79
|
-
...directiveContext.scope,
|
|
80
|
-
[key]: newArray[i],
|
|
81
|
-
[index || "index"]: i
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
for (let i = keptChildren.length; i < newLen; i++) {
|
|
85
|
-
const itemNode = this.spawnItemNode(attribute.template, owner, key, index, newArray[i], i);
|
|
86
|
-
itemNode.transform();
|
|
87
|
-
itemNode.compile();
|
|
88
|
-
itemNode.mount();
|
|
91
|
+
for (const child of newOnes) {
|
|
92
|
+
child.transform();
|
|
93
|
+
child.compile();
|
|
94
|
+
child.mount();
|
|
89
95
|
}
|
|
90
96
|
}
|
|
91
97
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
92
98
|
// ── Helpers ──────────────────────────────────────────────────────────────────
|
|
93
99
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
100
|
+
/**
|
|
101
|
+
* Build a key-function that derives a stable identity from each item.
|
|
102
|
+
* If the user provided a `track <expr>` clause, evaluate it as a path on
|
|
103
|
+
* the item; otherwise fall back to the item identity (reference equality).
|
|
104
|
+
*/
|
|
105
|
+
makeKeyFn(key, index, trackExpr) {
|
|
106
|
+
if (!trackExpr) {
|
|
107
|
+
return (item, i) => item ?? i;
|
|
108
|
+
}
|
|
109
|
+
const path = trackExpr.startsWith(key + ".") ? trackExpr.slice(key.length + 1) : trackExpr;
|
|
110
|
+
return (item, i) => {
|
|
111
|
+
if (item == null) return i;
|
|
112
|
+
if (path === key || path === "$index") return path === "$index" ? i : item;
|
|
113
|
+
const parts = path.split(".");
|
|
114
|
+
let v = item;
|
|
115
|
+
for (const p of parts) {
|
|
116
|
+
if (v == null) return i;
|
|
117
|
+
v = v[p];
|
|
118
|
+
}
|
|
119
|
+
return v ?? i;
|
|
120
|
+
};
|
|
121
|
+
}
|
|
94
122
|
/**
|
|
95
123
|
* Parses the $for expression string into its constituent parts.
|
|
96
124
|
*
|
|
@@ -100,16 +128,29 @@ exports.AreDirectiveFor = class AreDirectiveFor extends AreDirective_component.A
|
|
|
100
128
|
* (item, index) in items
|
|
101
129
|
* item in filter(items)
|
|
102
130
|
* item, index in filter(items, 'active')
|
|
131
|
+
* item in items track item.id
|
|
132
|
+
* (item, i) in items track item.id
|
|
103
133
|
*/
|
|
104
134
|
parseExpression(content) {
|
|
105
|
-
|
|
106
|
-
const
|
|
107
|
-
|
|
135
|
+
let trackExpr;
|
|
136
|
+
const trackIdx = content.search(/\s+track\s+/);
|
|
137
|
+
let body = content;
|
|
138
|
+
if (trackIdx !== -1) {
|
|
139
|
+
const m = content.slice(trackIdx).match(/\s+track\s+(.+)$/);
|
|
140
|
+
if (m) {
|
|
141
|
+
trackExpr = m[1].trim();
|
|
142
|
+
body = content.slice(0, trackIdx).trim();
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
const inIndex = body.lastIndexOf(" in ");
|
|
146
|
+
const keyAndIndex = body.slice(0, inIndex).trim().replace(/^\(|\)$/g, "");
|
|
147
|
+
const arrayExpr = body.slice(inIndex + 4).trim();
|
|
108
148
|
const keyParts = keyAndIndex.split(",").map((p) => p.trim());
|
|
109
149
|
return {
|
|
110
150
|
key: keyParts[0],
|
|
111
151
|
index: keyParts[1] || void 0,
|
|
112
|
-
arrayExpr
|
|
152
|
+
arrayExpr,
|
|
153
|
+
trackExpr
|
|
113
154
|
};
|
|
114
155
|
}
|
|
115
156
|
/**
|
|
@@ -200,6 +241,10 @@ __decorateClass([
|
|
|
200
241
|
__decorateParam(2, aConcept.A_Inject(are.AreScene))
|
|
201
242
|
], exports.AreDirectiveFor.prototype, "update", 1);
|
|
202
243
|
exports.AreDirectiveFor = __decorateClass([
|
|
244
|
+
core.A_Frame.Define({
|
|
245
|
+
namespace: "a-are-html",
|
|
246
|
+
description: "Built-in $for directive. Iterates over an array expression resolved from the store and renders a cloned template fragment per item, managing per-item subscopes and comment-node anchors. Supports keyed diffing via an optional track clause to minimise DOM mutations on collection updates."
|
|
247
|
+
}),
|
|
203
248
|
AreDirective_component.AreDirective.Priority(1)
|
|
204
249
|
], exports.AreDirectiveFor);
|
|
205
250
|
//# sourceMappingURL=AreDirectiveFor.directive.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/directives/AreDirectiveFor.directive.ts"],"names":["AreDirectiveFor","AreDirective","AddCommentInstruction","AreDirectiveContext","AreCompilerError","A_Caller","A_Scope","AreStore","AreScene","A_Logger"],"mappings":"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","file":"AreDirectiveFor.directive.js","sourcesContent":["import { A_Caller, A_Inject, A_Scope } from \"@adaas/a-concept\";\nimport { A_Logger } from \"@adaas/a-utils/a-logger\";\nimport { AreDirectiveAttribute } from \"@adaas/are-html/attributes/AreDirective.attribute\";\nimport { AreCompilerError, AreScene, AreStore } from \"@adaas/are\";\nimport { AreDirective } from \"@adaas/are-html/directive/AreDirective.component\";\nimport { AddCommentInstruction } from \"@adaas/are-html/instructions/AddComment.instruction\";\nimport { AreHTMLNode } from \"@adaas/are-html/node\";\nimport { AreDirectiveContext } from \"@adaas/are-html/directive/AreDirective.context\";\n\n\ntype AreForExpression = {\n key: string;\n index: string | undefined;\n arrayExpr: string;\n};\n\n\n@AreDirective.Priority(1)\nexport class AreDirectiveFor extends AreDirective {\n\n\n @AreDirective.Transform\n transform(\n @A_Inject(A_Caller) attribute: AreDirectiveAttribute,\n @A_Inject(A_Scope) scope: A_Scope,\n @A_Inject(AreStore) store: AreStore,\n @A_Inject(AreScene) scene: AreScene,\n @A_Inject(A_Logger) logger: A_Logger,\n ...args: any[]\n ) {\n\n logger.debug(`[Transform] directive $FOR for <${attribute.owner.aseid.toString()}>`)\n\n const node = attribute.owner;\n\n /**\n * Transfer the original node's scope (with all registered attributes and children)\n * to the template clone, and give the owner node a fresh empty scope.\n * This mirrors the $if directive's approach, making the owner a lightweight\n * group container whose sole visible presence is a comment placeholder.\n */\n const forTemplate = node.cloneWithScope();\n\n /**\n * Remove the $for attribute from the template so iterative clones do not\n * re-trigger this directive during their own transform phase.\n * Re-register it on the owner so the reactive compile/update pipeline keeps working.\n */\n const forAttr = forTemplate.attributes.find(d => d.name === attribute.name);\n\n if (forAttr) {\n forTemplate.scope.deregister(forAttr);\n node.scope.register(forAttr);\n }\n\n /**\n * Re-initialize the owner node with its fresh scope so it becomes a valid\n * group container that will own the generated item nodes as children.\n */\n node.init();\n\n /**\n * Store the template for use in compile and update.\n */\n attribute.template = forTemplate;\n\n\n /**\n * Parse the $for expression and evaluate the source array.\n */\n const { key, index, arrayExpr } = this.parseExpression(attribute.content);\n const array = this.resolveArray(store, arrayExpr, attribute.content);\n\n attribute.value = array;\n\n console.log('Initial array for \"for\" directive:', scene);\n\n /**\n * For each item in the array, spawn a clone of the template with the\n * item's store values pre-set and its scene activated.\n *\n * The children are added to the owner node before the main compiler's\n * children iteration loop runs, so the main cycle will compile them —\n * no explicit child.compile() call is needed here.\n */\n for (let i = 0; i < array.length; i++) {\n this.spawnItemNode(attribute.template!, attribute.owner, key, index, array[i], i);\n }\n\n console.log('Template for \"for\" directive:', forTemplate);\n }\n\n\n @AreDirective.Compile\n compile(\n @A_Inject(A_Caller) attribute: AreDirectiveAttribute,\n @A_Inject(AreStore) store: AreStore,\n @A_Inject(AreScene) scene: AreScene,\n ...args: any[]\n ): void {\n /**\n * Replace the group node's default host declaration with a comment placeholder\n * so the owner element itself does not render as a DOM element — the item nodes\n * render as its children instead.\n */\n const hostInstruction = scene.host!;\n const commentIdentifier = ` --- for: ${attribute.template!.id} --- `;\n const declaration = new AddCommentInstruction({ content: commentIdentifier });\n\n scene.setHost(declaration);\n scene.planBefore(declaration, hostInstruction);\n scene.unPlan(hostInstruction);\n }\n\n\n @AreDirective.Update\n update(\n @A_Inject(A_Caller) attribute: AreDirectiveAttribute,\n @A_Inject(AreStore) store: AreStore,\n @A_Inject(AreScene) scene: AreScene,\n ...args: any[]\n ): void {\n /**\n * Re-evaluate the source array.\n */\n const { key, index, arrayExpr } = this.parseExpression(attribute.content);\n const newArray = this.resolveArray(store, arrayExpr, attribute.content);\n\n const owner = attribute.owner;\n const currentChildren = [...owner.children] as AreHTMLNode[];\n\n attribute.value = newArray;\n\n const newLen = newArray.length;\n\n /**\n * Build a set of new items for O(1) identity lookup.\n * Uses reference equality — items that exist in newArray are \"kept\".\n */\n const newItemSet = new Set(newArray);\n\n /**\n * Partition existing children by identity: nodes whose stored item is\n * still present in the new array are kept; the rest are removed.\n * This correctly handles deletions from any position, not just the tail.\n */\n const keptChildren: AreHTMLNode[] = [];\n const removedChildren: AreHTMLNode[] = [];\n\n for (const child of currentChildren) {\n const ctx = child.scope.resolveFlat(AreDirectiveContext);\n\n if (ctx && newItemSet.has(ctx.scope[key])) {\n keptChildren.push(child);\n } else {\n removedChildren.push(child);\n }\n }\n\n /**\n * Unmount and detach nodes whose items are no longer in the array.\n */\n for (const child of removedChildren) {\n child.unmount();\n owner.removeChild(child);\n }\n\n /**\n * Update store values on kept nodes so their reactive bindings pick up\n * the latest data and corrected indices without a full re-render.\n */\n for (let i = 0; i < keptChildren.length; i++) {\n let directiveContext = keptChildren[i].scope.resolveFlat(AreDirectiveContext);\n\n if (!directiveContext) {\n directiveContext = new AreDirectiveContext(keptChildren[i].aseid);\n keptChildren[i].scope.register(directiveContext);\n }\n\n directiveContext.scope = {\n ...directiveContext.scope,\n [key]: newArray[i],\n [index || 'index']: i,\n };\n }\n\n /**\n * Append nodes for items added beyond the current kept count.\n * These are created outside the main compile cycle so they need an\n * explicit compile + mount to appear in the DOM.\n */\n for (let i = keptChildren.length; i < newLen; i++) {\n const itemNode = this.spawnItemNode(attribute.template!, owner, key, index, newArray[i], i);\n\n itemNode.transform();\n itemNode.compile();\n itemNode.mount();\n }\n }\n\n\n // ─────────────────────────────────────────────────────────────────────────────\n // ── Helpers ──────────────────────────────────────────────────────────────────\n // ─────────────────────────────────────────────────────────────────────────────\n\n /**\n * Parses the $for expression string into its constituent parts.\n *\n * Supported formats:\n * item in items\n * item, index in items\n * (item, index) in items\n * item in filter(items)\n * item, index in filter(items, 'active')\n */\n private parseExpression(content: string): AreForExpression {\n const inIndex = content.lastIndexOf(' in ');\n const keyAndIndex = content.slice(0, inIndex).trim().replace(/^\\(|\\)$/g, '');\n const arrayExpr = content.slice(inIndex + 4).trim();\n const keyParts = keyAndIndex.split(',').map(p => p.trim());\n\n return {\n key: keyParts[0],\n index: keyParts[1] || undefined,\n arrayExpr,\n };\n }\n\n /**\n * Resolves the array expression against the store.\n * Supports both plain key lookups and function-call expressions:\n * items → store.get('items')\n * filter(items) → store.get('filter')(store.get('items'))\n */\n private resolveArray(store: AreStore, arrayExpr: string, fullContent: string): any[] {\n let result: any;\n const callMatch = arrayExpr.match(/^([^(]+)\\((.+)\\)$/);\n\n if (callMatch) {\n const fnName = callMatch[1].trim();\n const fn = store.get(fnName as any);\n\n if (typeof fn !== 'function')\n throw new AreCompilerError({\n title: 'Invalid \"for\" Directive Function',\n description: `The expression \"${fnName}\" in the \"for\" directive does not resolve to a function in the store. Received: ${typeof fn}`,\n });\n\n const rawArgs = callMatch[2].split(',').map(a => a.trim());\n const resolvedArgs = rawArgs.map(arg => {\n if (arg.startsWith(\"'\") && arg.endsWith(\"'\")) return arg.slice(1, -1);\n if (arg.startsWith('\"') && arg.endsWith('\"')) return arg.slice(1, -1);\n if (!isNaN(Number(arg))) return Number(arg);\n return store.get(arg as any);\n });\n\n result = (fn as Function)(...resolvedArgs);\n } else {\n result = store.get(arrayExpr as any);\n }\n\n if (!Array.isArray(result))\n throw new AreCompilerError({\n title: 'Invalid \"for\" Directive Value',\n description: `The \"for\" directive expects an array but got ${typeof result}. Expression: \"${fullContent}\". Received: ${JSON.stringify(result)}`,\n });\n\n return result;\n }\n\n /**\n * Creates a single item node from the template, registers it as a child of\n * the owner, initialises it, injects item-scoped store values, and activates\n * its scene so the mount/compile cycle will include it.\n *\n * NOTE: This method does NOT call compile() or mount() — the caller is\n * responsible for doing so when the main lifecycle cycle won't cover it\n * (i.e. during update, but not during the initial compile phase).\n */\n private spawnItemNode(\n template: AreHTMLNode,\n owner: AreHTMLNode,\n key: string,\n index: string | undefined,\n item: any,\n i: number,\n ): AreHTMLNode {\n const itemNode = template.clone() as AreHTMLNode;\n\n owner.addChild(itemNode);\n\n const queue = [itemNode];\n\n while (queue.length > 0) {\n const current = queue.shift()!\n\n current.init();\n\n queue.push(...current.children as AreHTMLNode[]);\n }\n\n /**\n * Resolve or create a directive context for the item node. This is needed to hold the item-specific store values (e.g. the \"item\" and \"index\" in a \"for\" loop) that the template's bindings will reference during compile and update. The context is shared among all clones of the same template, but that's fine because each clone gets its own scope values assigned here.\n */\n let directiveContext = itemNode.scope.resolveFlat(AreDirectiveContext);\n\n if (!directiveContext) {\n directiveContext = new AreDirectiveContext(itemNode.aseid);\n itemNode.scope.register(directiveContext);\n }\n\n directiveContext.scope = {\n ...directiveContext.scope,\n [key]: item,\n [index || 'index']: i,\n }\n\n itemNode.scene.activate();\n\n return itemNode;\n }\n}"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/directives/AreDirectiveFor.directive.ts"],"names":["AreDirectiveFor","AreDirective","AddCommentInstruction","AreDirectiveContext","AreCompilerError","A_Caller","A_Scope","AreStore","AreScene","A_Logger","A_Frame"],"mappings":"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","file":"AreDirectiveFor.directive.js","sourcesContent":["import { A_Caller, A_Inject, A_Scope } from \"@adaas/a-concept\";\nimport { A_Logger } from \"@adaas/a-utils/a-logger\";\nimport { AreDirectiveAttribute } from \"@adaas/are-html/attributes/AreDirective.attribute\";\nimport { AreCompilerError, AreScene, AreStore } from \"@adaas/are\";\nimport { AreDirective } from \"@adaas/are-html/directive/AreDirective.component\";\nimport { AddCommentInstruction } from \"@adaas/are-html/instructions/AddComment.instruction\";\nimport { AreHTMLNode } from \"@adaas/are-html/node\";\nimport { AreDirectiveContext } from \"@adaas/are-html/directive/AreDirective.context\";\nimport { A_Frame } from \"@adaas/a-frame/core\";\n\n\ntype AreForExpression = {\n key: string;\n index: string | undefined;\n arrayExpr: string;\n /** Optional `track <expr>` clause, e.g. `track row.id` */\n trackExpr: string | undefined;\n};\n\n\n@A_Frame.Define({\n namespace: 'a-are-html',\n description: 'Built-in $for directive. Iterates over an array expression resolved from the store and renders a cloned template fragment per item, managing per-item subscopes and comment-node anchors. Supports keyed diffing via an optional track clause to minimise DOM mutations on collection updates.'\n})\n@AreDirective.Priority(1)\nexport class AreDirectiveFor extends AreDirective {\n\n\n @AreDirective.Transform\n transform(\n @A_Inject(A_Caller) attribute: AreDirectiveAttribute,\n @A_Inject(A_Scope) scope: A_Scope,\n @A_Inject(AreStore) store: AreStore,\n @A_Inject(AreScene) scene: AreScene,\n @A_Inject(A_Logger) logger: A_Logger,\n ...args: any[]\n ) {\n\n logger.debug(`[Transform] directive $FOR for <${attribute.owner.aseid.toString()}>`)\n\n const node = attribute.owner;\n\n /**\n * Transfer the original node's scope (with all registered attributes and children)\n * to the template clone, and give the owner node a fresh empty scope.\n * This mirrors the $if directive's approach, making the owner a lightweight\n * group container whose sole visible presence is a comment placeholder.\n */\n const forTemplate = node.cloneWithScope();\n\n /**\n * Remove the $for attribute from the template so iterative clones do not\n * re-trigger this directive during their own transform phase.\n * Re-register it on the owner so the reactive compile/update pipeline keeps working.\n */\n const forAttr = forTemplate.attributes.find(d => d.name === attribute.name);\n\n if (forAttr) {\n forTemplate.scope.deregister(forAttr);\n node.scope.register(forAttr);\n }\n\n /**\n * Re-initialize the owner node with its fresh scope so it becomes a valid\n * group container that will own the generated item nodes as children.\n */\n node.init();\n\n /**\n * Store the template for use in compile and update.\n */\n attribute.template = forTemplate;\n\n\n /**\n * Parse the $for expression and evaluate the source array.\n */\n const { key, index, arrayExpr } = this.parseExpression(attribute.content);\n const array = this.resolveArray(store, arrayExpr, attribute.content);\n\n attribute.value = array;\n\n /**\n * For each item in the array, spawn a clone of the template with the\n * item's store values pre-set and its scene activated.\n *\n * The children are added to the owner node before the main compiler's\n * children iteration loop runs, so the main cycle will compile them —\n * no explicit child.compile() call is needed here.\n */\n for (let i = 0; i < array.length; i++) {\n this.spawnItemNode(attribute.template!, attribute.owner, key, index, array[i], i);\n }\n }\n\n\n @AreDirective.Compile\n compile(\n @A_Inject(A_Caller) attribute: AreDirectiveAttribute,\n @A_Inject(AreStore) store: AreStore,\n @A_Inject(AreScene) scene: AreScene,\n ...args: any[]\n ): void {\n /**\n * Replace the group node's default host declaration with a comment placeholder\n * so the owner element itself does not render as a DOM element — the item nodes\n * render as its children instead.\n */\n const hostInstruction = scene.host!;\n const commentIdentifier = ` --- for: ${attribute.template!.id} --- `;\n const declaration = new AddCommentInstruction({ content: commentIdentifier });\n\n scene.setHost(declaration);\n scene.planBefore(declaration, hostInstruction);\n scene.unPlan(hostInstruction);\n }\n\n\n @AreDirective.Update\n update(\n @A_Inject(A_Caller) attribute: AreDirectiveAttribute,\n @A_Inject(AreStore) store: AreStore,\n @A_Inject(AreScene) scene: AreScene,\n ...args: any[]\n ): void {\n /**\n * Re-evaluate the source array.\n */\n const { key, index, arrayExpr, trackExpr } = this.parseExpression(attribute.content);\n const newArray = this.resolveArray(store, arrayExpr, attribute.content);\n\n const owner = attribute.owner;\n const currentChildren = [...owner.children] as AreHTMLNode[];\n\n attribute.value = newArray;\n\n const computeKey = this.makeKeyFn(key, index, trackExpr);\n\n // ── 1. Index existing children by stable key ────────────────────────\n const childByKey = new Map<any, AreHTMLNode>();\n const remaining = new Set<AreHTMLNode>();\n\n for (let i = 0; i < currentChildren.length; i++) {\n const child = currentChildren[i];\n const ctx = child.scope.resolveFlat(AreDirectiveContext);\n const k = ctx ? computeKey(ctx.scope[key], ctx.scope[index || 'index']) : Symbol('orphan');\n childByKey.set(k, child);\n remaining.add(child);\n }\n\n // ── 2. Walk desired list; reuse existing or spawn new ───────────────\n const desired: AreHTMLNode[] = [];\n const newOnes: AreHTMLNode[] = [];\n\n for (let i = 0; i < newArray.length; i++) {\n const item = newArray[i];\n const k = computeKey(item, i);\n const existing = childByKey.get(k);\n\n if (existing) {\n remaining.delete(existing);\n\n let directiveContext = existing.scope.resolveFlat(AreDirectiveContext);\n if (!directiveContext) {\n directiveContext = new AreDirectiveContext(existing.aseid);\n existing.scope.register(directiveContext);\n }\n directiveContext.scope = {\n ...directiveContext.scope,\n [key]: item,\n [index || 'index']: i,\n };\n desired.push(existing);\n } else {\n const itemNode = this.spawnItemNode(attribute.template!, owner, key, index, item, i);\n desired.push(itemNode);\n newOnes.push(itemNode);\n }\n }\n\n // ── 3. Unmount + detach removed children ─────────────────────────────\n for (const child of remaining) {\n child.unmount();\n owner.removeChild(child);\n }\n\n // ── 4. Mount only the new ones (kept children stay where they are). ─\n for (const child of newOnes) {\n child.transform();\n child.compile();\n child.mount();\n }\n }\n\n\n // ─────────────────────────────────────────────────────────────────────────────\n // ── Helpers ──────────────────────────────────────────────────────────────────\n // ─────────────────────────────────────────────────────────────────────────────\n\n /**\n * Build a key-function that derives a stable identity from each item.\n * If the user provided a `track <expr>` clause, evaluate it as a path on\n * the item; otherwise fall back to the item identity (reference equality).\n */\n private makeKeyFn(key: string, index: string | undefined, trackExpr: string | undefined): (item: any, i: number) => any {\n if (!trackExpr) {\n return (item, i) => item ?? i;\n }\n\n // Strip any leading `key.` so users can write `track row.id`.\n const path = trackExpr.startsWith(key + '.') ? trackExpr.slice(key.length + 1) : trackExpr;\n\n return (item, i) => {\n if (item == null) return i;\n if (path === key || path === '$index') return path === '$index' ? i : item;\n\n // dotted path lookup\n const parts = path.split('.');\n let v: any = item;\n for (const p of parts) {\n if (v == null) return i;\n v = v[p];\n }\n return v ?? i;\n };\n }\n\n /**\n * Parses the $for expression string into its constituent parts.\n *\n * Supported formats:\n * item in items\n * item, index in items\n * (item, index) in items\n * item in filter(items)\n * item, index in filter(items, 'active')\n * item in items track item.id\n * (item, i) in items track item.id\n */\n private parseExpression(content: string): AreForExpression {\n // Strip optional `track <expr>` suffix first.\n let trackExpr: string | undefined;\n const trackIdx = content.search(/\\s+track\\s+/);\n let body = content;\n if (trackIdx !== -1) {\n const m = content.slice(trackIdx).match(/\\s+track\\s+(.+)$/);\n if (m) {\n trackExpr = m[1].trim();\n body = content.slice(0, trackIdx).trim();\n }\n }\n\n const inIndex = body.lastIndexOf(' in ');\n const keyAndIndex = body.slice(0, inIndex).trim().replace(/^\\(|\\)$/g, '');\n const arrayExpr = body.slice(inIndex + 4).trim();\n const keyParts = keyAndIndex.split(',').map(p => p.trim());\n\n return {\n key: keyParts[0],\n index: keyParts[1] || undefined,\n arrayExpr,\n trackExpr,\n };\n }\n\n /**\n * Resolves the array expression against the store.\n * Supports both plain key lookups and function-call expressions:\n * items → store.get('items')\n * filter(items) → store.get('filter')(store.get('items'))\n */\n private resolveArray(store: AreStore, arrayExpr: string, fullContent: string): any[] {\n let result: any;\n const callMatch = arrayExpr.match(/^([^(]+)\\((.+)\\)$/);\n\n if (callMatch) {\n const fnName = callMatch[1].trim();\n const fn = store.get(fnName as any);\n\n if (typeof fn !== 'function')\n throw new AreCompilerError({\n title: 'Invalid \"for\" Directive Function',\n description: `The expression \"${fnName}\" in the \"for\" directive does not resolve to a function in the store. Received: ${typeof fn}`,\n });\n\n const rawArgs = callMatch[2].split(',').map(a => a.trim());\n const resolvedArgs = rawArgs.map(arg => {\n if (arg.startsWith(\"'\") && arg.endsWith(\"'\")) return arg.slice(1, -1);\n if (arg.startsWith('\"') && arg.endsWith('\"')) return arg.slice(1, -1);\n if (!isNaN(Number(arg))) return Number(arg);\n return store.get(arg as any);\n });\n\n result = (fn as Function)(...resolvedArgs);\n } else {\n result = store.get(arrayExpr as any);\n }\n\n if (!Array.isArray(result))\n throw new AreCompilerError({\n title: 'Invalid \"for\" Directive Value',\n description: `The \"for\" directive expects an array but got ${typeof result}. Expression: \"${fullContent}\". Received: ${JSON.stringify(result)}`,\n });\n\n return result;\n }\n\n /**\n * Creates a single item node from the template, registers it as a child of\n * the owner, initialises it, injects item-scoped store values, and activates\n * its scene so the mount/compile cycle will include it.\n *\n * NOTE: This method does NOT call compile() or mount() — the caller is\n * responsible for doing so when the main lifecycle cycle won't cover it\n * (i.e. during update, but not during the initial compile phase).\n */\n private spawnItemNode(\n template: AreHTMLNode,\n owner: AreHTMLNode,\n key: string,\n index: string | undefined,\n item: any,\n i: number,\n ): AreHTMLNode {\n const itemNode = template.clone() as AreHTMLNode;\n\n owner.addChild(itemNode);\n\n const queue = [itemNode];\n\n while (queue.length > 0) {\n const current = queue.shift()!\n\n current.init();\n\n queue.push(...current.children as AreHTMLNode[]);\n }\n\n /**\n * Resolve or create a directive context for the item node. This is needed to hold the item-specific store values (e.g. the \"item\" and \"index\" in a \"for\" loop) that the template's bindings will reference during compile and update. The context is shared among all clones of the same template, but that's fine because each clone gets its own scope values assigned here.\n */\n let directiveContext = itemNode.scope.resolveFlat(AreDirectiveContext);\n\n if (!directiveContext) {\n directiveContext = new AreDirectiveContext(itemNode.aseid);\n itemNode.scope.register(directiveContext);\n }\n\n directiveContext.scope = {\n ...directiveContext.scope,\n [key]: item,\n [index || 'index']: i,\n }\n\n itemNode.scene.activate();\n\n return itemNode;\n }\n}"]}
|