arrmatura 6.3.1 → 6.3.2

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.
@@ -1,38 +1,46 @@
1
+ import type { IPlatform, IArrmatron, IManifestNode } from "arrmatura/types";
1
2
  import { nextId } from "ultimus";
2
- import { compilePipeExpression } from "../utils/compileExpression";
3
3
  import type { Delta, ExpressionText, Hash, Uid } from "ultimus/types";
4
- import type { IPlatform, IEntitron, IManifestNode } from "arrmatura/types";
4
+
5
+ import { compilePipeExpression } from "../utils/compileExpression";
6
+
7
+ import { Arrmatron } from "./Arrmatron";
5
8
  import { resolveExpression } from "./resolveExpression";
6
9
 
7
- type PropertyResolver = (c: IEntitron, acc: Delta) => Delta;
8
10
 
9
- type PropertyGetter = (c: IEntitron) => unknown;
11
+ type PropertyResolver = (c: IArrmatron, acc: Delta) => Delta;
12
+
13
+ type PropertyGetter = (c: IArrmatron) => unknown;
10
14
 
11
15
  /**
12
- * ManifestNode is a abstract factory for Entitron.
16
+ * ManifestNode is a abstract factory for Arrmatron.
13
17
  *
14
- * Each specific kind of Entitron has its own descending implementation of ManifestNode.
18
+ * Each specific kind of Arrmatron has its own descending implementation of ManifestNode.
15
19
  */
16
20
  export abstract class ManifestNode implements IManifestNode {
17
21
  protected $content?: Map<Uid, IManifestNode> | undefined;
18
- uid: Uid = nextId("N");
22
+ uid: Uid;
19
23
  refId?: string;
20
24
  private readonly propertyResolvers: PropertyResolver[] = [];
21
- private initialState: Hash<(c: IEntitron) => any> = {};
22
- connectors?: Map<string, (c: IEntitron, x: unknown) => unknown>;
25
+ private initialState: Hash<(c: IArrmatron) => any> = {};
26
+ connectors?: Map<string, (c: IArrmatron, x: unknown) => unknown>;
23
27
  tag: any;
24
28
 
25
- abstract get EntitronConstructor(): new (platform: IPlatform, node: typeof this, parent?: IEntitron, scope?: IEntitron) => IEntitron;
29
+ constructor(xid: Uid) {
30
+ this.uid = `${nextId("N")}:${xid}`;
31
+ }
32
+
33
+ abstract get EntitronConstructor(): new (platform: IPlatform, node: typeof this, parent?: Arrmatron, scope?: Arrmatron) => Arrmatron;
26
34
 
27
35
  /**
28
36
  * Create a context object.
29
37
  *
30
38
  * @param {IPlatform} platform - The platform object.
31
- * @param {IEntitron} parent - The parent context object (optional).
32
- * @param {IEntitron} scope - The scope context object (optional).
33
- * @return {IEntitron} The created context object.
39
+ * @param {IArrmatron} parent - The parent context object (optional).
40
+ * @param {IArrmatron} scope - The scope context object (optional).
41
+ * @return {IArrmatron} The created context object.
34
42
  */
35
- createEntitron(platform: IPlatform, parent?: IEntitron, scope?: IEntitron): IEntitron {
43
+ createArrmatron(platform: IPlatform, parent?: Arrmatron, scope?: Arrmatron): Arrmatron {
36
44
  return new this.EntitronConstructor(platform, this, parent, scope);
37
45
  }
38
46
 
@@ -41,7 +49,7 @@ export abstract class ManifestNode implements IManifestNode {
41
49
  }
42
50
 
43
51
  addPropertyResolver(getter: PropertyGetter, propKey: string) {
44
- this.propertyResolvers.push((c: IEntitron, delta: Delta) => {
52
+ this.propertyResolvers.push((c: IArrmatron, delta: Delta) => {
45
53
  delta[propKey] = getter(c);
46
54
  return delta;
47
55
  });
@@ -49,7 +57,7 @@ export abstract class ManifestNode implements IManifestNode {
49
57
  }
50
58
 
51
59
  private addDataPropertyResolver(getter: PropertyGetter, propKey: string) {
52
- this.propertyResolvers.push((c: IEntitron, delta: Delta) => {
60
+ this.propertyResolvers.push((c: IArrmatron, delta: Delta) => {
53
61
  const val = getter(c);
54
62
  delta.data = Object.assign((delta.data as object) || {}, {
55
63
  [propKey]: val,
@@ -60,7 +68,7 @@ export abstract class ManifestNode implements IManifestNode {
60
68
  }
61
69
 
62
70
  private addPropertiesResolver(getter: PropertyGetter) {
63
- this.propertyResolvers.push((c: IEntitron, delta: Delta) => {
71
+ this.propertyResolvers.push((c: IArrmatron, delta: Delta) => {
64
72
  const value = getter(c);
65
73
  if (value && typeof value === "object") {
66
74
  Object.entries(value).forEach(([key, val]) => {
@@ -79,10 +87,11 @@ export abstract class ManifestNode implements IManifestNode {
79
87
 
80
88
  private addEmitter(expr: ExpressionText, k: string) {
81
89
  const { key, pipec } = compilePipeExpression(expr);
82
- this.initialState[k] = (c) => (data: unknown) => c.scope?.emit(key, pipec(c, data) as Delta);
90
+ const rkey = key + (expr.endsWith(")") ? "()" : '');
91
+ this.initialState[k] = (c) => (data: unknown) => c.scope?.emit(rkey, pipec(c, data) as Delta);
83
92
  }
84
93
 
85
- resolveInitialProps(c: IEntitron) {
94
+ resolveInitialProps(c: IArrmatron) {
86
95
  return this.propertyResolvers.reduce(
87
96
  (delta, resolver) => resolver(c, delta),
88
97
  Object.entries(this.initialState).reduce((acc, [key, fn]) => {
@@ -92,17 +101,17 @@ export abstract class ManifestNode implements IManifestNode {
92
101
  );
93
102
  }
94
103
 
95
- resolveProps(c: IEntitron) {
104
+ resolveProps(c: IArrmatron) {
96
105
  return this.propertyResolvers.reduce((delta, resolver) => resolver(c, delta), {});
97
106
  }
98
107
 
99
108
  compileAttribute(k: string, v: unknown) {
100
109
  if (k.startsWith("data-")) {
101
110
  this.addDataPropertyResolver(resolveExpression(v), k.slice(5));
102
- } else if (k === "ref") {
111
+ } else if (k === "Ref") {
103
112
  this.refId = String(v);
104
- } else if (k === "props" || k.startsWith('{...')) {
105
- const sv = k.startsWith('{...') ? k.slice(4, -1) : String(v);
113
+ } else if (k === '(...)') {
114
+ const sv = String(v);
106
115
  if (sv[0] === "<" && sv[1] === "-") {
107
116
  this.addConnector(sv.slice(2), "");
108
117
  } else {
@@ -116,11 +125,13 @@ export abstract class ManifestNode implements IManifestNode {
116
125
  this.addConnector(v.slice(2), k);
117
126
  } else if (v[0] === "-" && v[1] === ">") {
118
127
  this.addEmitter(v.slice(2), k);
128
+ } else if (v[0] === "d" && v.startsWith("data->")) {
129
+ this.addEmitter(v.slice(6), k);
119
130
  } else {
120
- if (!v.includes("{") && v[0] !== "@") {
131
+ if (!v.includes("{")) {
121
132
  this.initialState[k] = () => v;
122
133
  } else {
123
- if (v[0] === "@" && v[1] === "@" && v.match(/^@@[a-z0-9\-_.]+$/i) != null) {
134
+ if (v[0] === "R" && v[1] === "." && v.match(/^@@[a-z0-9\-_.]+$/i) != null) {
124
135
  this.initialState[k] = (c) => c.platform.getResource(v.slice(2));
125
136
  } else {
126
137
  this.addPropertyResolver(resolveExpression(v), k);
@@ -1,17 +1,22 @@
1
1
  import { createStringInterpolator } from "ultimus/src/parsing/createStringInterpolator";
2
+
2
3
  import { compileConstant, compileJsExpression, compilePlaceholder } from "../utils/compileExpression";
4
+ // \{\{([\w\.]+)\}\}
3
5
 
4
6
  const CACHE = new Map();
5
7
 
6
8
  function compileExpression(v: unknown) {
7
9
  if (typeof v !== "string") return () => v;
8
10
 
9
- if (v[0] === "@") return compilePlaceholder(v);
10
-
11
11
  if (v.startsWith("js:")) return compileJsExpression(v.slice(3));
12
12
 
13
- if (v.includes("{")) return createStringInterpolator(v.replace(/\s+/g, " "), compilePlaceholder);
14
-
13
+ if (v.includes("{")) {
14
+ const vCutOne = v.slice(1, -1);
15
+ if (v[0] === "{" && v[v.length - 1] === "}" && !vCutOne.includes("{")) {
16
+ return compilePlaceholder(vCutOne)
17
+ }
18
+ return createStringInterpolator(v.replace(/\s+/g, " "), compilePlaceholder);
19
+ }
15
20
  return compileConstant(v);
16
21
  }
17
22
 
@@ -1,14 +1,15 @@
1
- import { ManifestNode } from "../core/ManifestNode";
2
- import { Entitron } from "../core/Entitron";
3
- import type { Hash, XmlNode } from "ultimus/types";
4
1
  import type { EContent, IManifestNode, IPlatform } from "arrmatura/types";
2
+ import type { Hash, XmlNode } from "ultimus/types";
3
+
4
+ import { Arrmatron } from "../core/Arrmatron";
5
+ import { ManifestNode } from "../core/ManifestNode";
5
6
 
6
- export class Composite extends Entitron<CCompositeNode> {
7
+ export class Composite extends Arrmatron<CCompositeNode> {
7
8
  get displayName(): string {
8
9
  return `💠${this.manifest.tag}`;
9
10
  }
10
11
 
11
- get recontentScope(): Entitron {
12
+ get recontentScope(): Arrmatron {
12
13
  return this;
13
14
  }
14
15
 
@@ -27,8 +28,8 @@ export class CCompositeNode extends ManifestNode {
27
28
  nodes?: XmlNode["nodes"];
28
29
  #content?: Map<string, IManifestNode>;
29
30
 
30
- constructor({ tag, attrs, nodes }: XmlNode) {
31
- super();
31
+ constructor({ id, tag, attrs, nodes }: XmlNode) {
32
+ super(id);
32
33
  this.tag = tag;
33
34
  this.nodes = nodes;
34
35
  this.compileAttributes(attrs);
@@ -53,7 +54,7 @@ export class CCompositeNode extends ManifestNode {
53
54
  }, {});
54
55
  }
55
56
 
56
- return this.slotContent[slotId ?? "default"] ?? undefined;
57
+ return this.slotContent[slotId || "default"] ?? undefined;
57
58
  }
58
59
 
59
60
  getSubNodes(platform: IPlatform) {
@@ -1,14 +1,16 @@
1
- import { ManifestNode } from "../core/ManifestNode";
2
- import { Composite } from "./composition";
3
- import { Entitron } from "../core/Entitron";
4
- import type { EContent, IEntitron, IPlatform } from "arrmatura/types";
1
+ import type { EContent, IArrmatron, IPlatform } from "arrmatura/types";
5
2
  import type { XmlNode } from "ultimus/types";
3
+
4
+ import { Arrmatron } from "../core/Arrmatron";
5
+ import { ManifestNode } from "../core/ManifestNode";
6
6
  import { compilePlaceholder } from "../utils/compileExpression";
7
7
 
8
- class Conditional extends Entitron<CIfNode> {
8
+ import { Composite } from "./composition";
9
+
10
+ class Conditional extends Arrmatron<CIfNode> {
9
11
  get contentManifests() {
10
12
  const branches = this.manifest.getBranches(this.platform);
11
- return this.component.condition ? branches.then : branches.else;
13
+ return this.$component.condition ? branches.then : branches.else;
12
14
  }
13
15
 
14
16
  get displayName(): string {
@@ -20,7 +22,7 @@ export class CIfNode extends ManifestNode {
20
22
  #xml: XmlNode;
21
23
  #branches?: { then?: EContent; else?: EContent };
22
24
  constructor(xml: XmlNode, expr: string) {
23
- super();
25
+ super(xml.id);
24
26
  this.#xml = xml;
25
27
  this.compileCondition(expr);
26
28
  }
@@ -66,7 +68,7 @@ export class CIfNode extends ManifestNode {
66
68
  } else if (expr.slice(0, 5) === "slot(") {
67
69
  const slotId = expr.slice(5, -1);
68
70
  // DO NOT place inside iterations.
69
- this.addPropertyResolver((c: IEntitron) => !!(c.scope as Composite).slotContent?.(slotId)?.size, "condition");
71
+ this.addPropertyResolver((c: IArrmatron) => !!(c.scope as Composite).slotContent?.(slotId)?.size, "condition");
70
72
  } else {
71
73
  const resolver = compilePlaceholder(expr);
72
74
  this.addPropertyResolver((c) => !!resolver(c), "condition");
@@ -0,0 +1,47 @@
1
+ import { Fn, XmlNode } from "ultimus";
2
+
3
+ import { Arrmatron } from "../core/Arrmatron";
4
+ import { ManifestNode } from "../core/ManifestNode";
5
+ import { objectFingerprint } from "../utils/FingerprintMashine";
6
+
7
+ class Connector extends Arrmatron<ConnectorNode> {
8
+ prevkey: any;
9
+
10
+ counter = 0;
11
+
12
+ /**
13
+ * Triggers an with changes after a specified timeout.
14
+ *
15
+ * @return {void} No return value.
16
+ */
17
+ touch() {
18
+ super.touch();
19
+ // if (this.isDone) return;
20
+ const { trigger, data, change } = this.$component;
21
+ const key = 'trigger' in this.$component ? trigger : data;
22
+ const fprint = objectFingerprint(key);
23
+ const changed = !('prevkey' in this) || this.prevkey != fprint;
24
+
25
+ if (!changed) return;
26
+
27
+ this.prevkey = fprint;
28
+
29
+ (change as Fn)?.(data);
30
+ }
31
+
32
+ get displayName(): string {
33
+ return "🔹Connector";
34
+ }
35
+ }
36
+
37
+ export class ConnectorNode extends ManifestNode {
38
+ constructor({ attrs, id }: XmlNode) {
39
+ super(id);
40
+ this.compileAttributes(attrs);
41
+ }
42
+
43
+ get EntitronConstructor() {
44
+ return Connector;
45
+ }
46
+
47
+ }
@@ -1,9 +1,10 @@
1
- import { ManifestNode } from "../core/ManifestNode";
2
- import { Entitron } from "../core/Entitron";
3
- import type { Hash, XmlNode } from "ultimus/types";
4
1
  import { IPlatform } from "arrmatura/types";
2
+ import type { Hash, XmlNode } from "ultimus/types";
3
+
4
+ import { Arrmatron } from "../core/Arrmatron";
5
+ import { ManifestNode } from "../core/ManifestNode";
5
6
 
6
- class NativeElementEntitron extends Entitron<CElementNode> {
7
+ class NativeElementEntitron extends Arrmatron<CElementNode> {
7
8
  get displayName(): string {
8
9
  return this.manifest.tag;
9
10
  }
@@ -16,8 +17,8 @@ class NativeElementEntitron extends Entitron<CElementNode> {
16
17
  export class CElementNode extends ManifestNode {
17
18
  #nodes: XmlNode[] | undefined;
18
19
 
19
- constructor({ tag, attrs, nodes, text }: XmlNode) {
20
- super();
20
+ constructor({ id, tag, attrs, nodes, text }: XmlNode) {
21
+ super(id);
21
22
  this.tag = tag;
22
23
  this.compileAttributes(attrs);
23
24
  if (text) {
@@ -1,13 +1,14 @@
1
- import { ManifestNode } from "../core/ManifestNode";
2
- import { Entitron } from "../core/Entitron";
3
- import type { XmlNode } from "ultimus/types";
4
1
  import type { IPlatform } from "arrmatura/types";
2
+ import type { XmlNode } from "ultimus/types";
3
+
4
+ import { Arrmatron } from "../core/Arrmatron";
5
+ import { ManifestNode } from "../core/ManifestNode";
5
6
 
6
7
  export class CFragmentNode extends ManifestNode {
7
8
  #nodes: XmlNode[] | undefined;
8
9
 
9
- constructor({ nodes }: XmlNode) {
10
- super();
10
+ constructor({ id, nodes }: XmlNode) {
11
+ super(id);
11
12
  this.#nodes = nodes;
12
13
  }
13
14
 
@@ -16,6 +17,6 @@ export class CFragmentNode extends ManifestNode {
16
17
  }
17
18
 
18
19
  get EntitronConstructor() {
19
- return Entitron;
20
+ return Arrmatron;
20
21
  }
21
22
  }
@@ -1,25 +1,18 @@
1
- import { CForNode } from "./iterations";
1
+ import { Uid, XmlNode } from "ultimus";
2
+
3
+ import { IManifestNode } from "../../types";
4
+
2
5
  import { CCompositeNode } from "./composition";
3
6
  import { CIfNode } from "./conditionals";
7
+ import { ConnectorNode } from "./connector";
4
8
  import { CElementNode } from "./elementary";
5
- import { CDynamicTagNode } from "./routing";
6
- import { CSlotNode } from "./slot";
7
9
  import { CFragmentNode } from "./fragment";
10
+ import { CForNode } from "./iterations";
11
+ import { CDynamicTagNode } from "./routing";
8
12
  import { CSelectorNode } from "./selection";
13
+ import { CSlotNode } from "./slot";
9
14
 
10
- import { Uid, XmlNode } from "ultimus";
11
- import { IManifestNode } from "../../types";
12
15
 
13
- export const Registry = {
14
- CForNode,
15
- CIfNode,
16
- CDynamicTagNode,
17
- CSlotNode,
18
- CFragmentNode,
19
- CCompositeNode,
20
- CSelectorNode,
21
- CElementNode,
22
- };
23
16
 
24
17
  const cloneNode = (x: XmlNode, eliminateAttr: string): XmlNode => {
25
18
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
@@ -35,28 +28,31 @@ const cloneNode = (x: XmlNode, eliminateAttr: string): XmlNode => {
35
28
 
36
29
  const __compileManifestNode = (x: XmlNode): IManifestNode => {
37
30
  const { tag = 'div', attrs } = x;
38
- if (attrs?.["each"]) {
39
- return new Registry.CForNode(cloneNode(x, "each"), String(attrs["each"]).trim().split(" "));
31
+ if (attrs?.["Each"]) {
32
+ return new CForNode(cloneNode(x, "Each"), String(attrs["Each"]).trim().split(" "));
40
33
  }
41
- if (attrs?.["if"]) {
42
- return new Registry.CIfNode(cloneNode(x, "if"), String(attrs["if"]));
34
+ if (attrs?.["If"]) {
35
+ return new CIfNode(cloneNode(x, "If"), String(attrs["If"]));
43
36
  }
44
37
  if (tag === "div" || tag[0]?.match(/[A-Z0-9]/) == null) {
45
- return new Registry.CElementNode(x);
38
+ return new CElementNode(x);
46
39
  }
47
40
  if (tag === "Dynamic") {
48
- return new Registry.CDynamicTagNode(cloneNode(x, "as"), String(attrs?.as ?? "Error.Dynamic"));
41
+ return new CDynamicTagNode(cloneNode(x, "As"), String(attrs?.As ?? "Error.Dynamic"));
49
42
  }
50
43
  if (tag === "Slot") {
51
- return new Registry.CSlotNode(x);
44
+ return new CSlotNode(x);
52
45
  }
53
46
  if (tag === "Selector") {
54
- return new Registry.CSelectorNode(x);
47
+ return new CSelectorNode(x);
48
+ }
49
+ if (tag === "Connector") {
50
+ return new ConnectorNode(x);
55
51
  }
56
52
  if (tag === "Fragment" || tag === "Then" || tag === "Else") {
57
- return new Registry.CFragmentNode(x);
53
+ return new CFragmentNode(x);
58
54
  }
59
- return new Registry.CCompositeNode(x);
55
+ return new CCompositeNode(x);
60
56
  };
61
57
 
62
58
  const CTXNODES = new Map();
@@ -1,9 +1,12 @@
1
- import { ManifestNode } from "../core/ManifestNode";
2
- import { Entitron } from "../core/Entitron";
3
- import type { Datum, Delta, Hash, Uid, XmlNode } from "ultimus/types";
4
1
  import type { EContent, IManifestNode, IPlatform } from "arrmatura/types";
2
+ import { mapEntries } from "ultimus";
3
+ import type { Datum, Delta, Hash, Uid, XmlNode } from "ultimus/types";
4
+
5
+ import { Arrmatron } from "../core/Arrmatron";
6
+ import { ManifestNode } from "../core/ManifestNode";
5
7
  import { compilePlaceholder } from "../utils/compileExpression";
6
8
 
9
+
7
10
  const narrowData = (data: any) => {
8
11
  if (!data) {
9
12
  return [];
@@ -11,11 +14,11 @@ const narrowData = (data: any) => {
11
14
  if (Array.isArray(data)) return data;
12
15
  if (typeof data[Symbol.iterator] === 'function') return [...data];
13
16
  if (typeof data === "string") return data.split(',').map(id => ({ id, name: id }));
14
- if (typeof data === "object") return Object.values(data);
17
+ if (typeof data === "object") return mapEntries(data, (key, value) => ({ ...value, id: key }));
15
18
  return [{ id: String(data), name: String(data) }];
16
19
  }
17
20
 
18
- class Iterative extends Entitron<CForNode> {
21
+ class Iterative extends Arrmatron<CForNode> {
19
22
  pkHash: Hash<Datum> = {};
20
23
 
21
24
  get displayName(): string {
@@ -23,30 +26,36 @@ class Iterative extends Entitron<CForNode> {
23
26
  }
24
27
 
25
28
  get contentManifests() {
26
- const each: any = narrowData(this.component.each);
29
+ const each: any = narrowData(this.$component.each);
27
30
  const itemNode = this.manifest.getItemCtxNode(this.platform);
28
31
  const nodes: Map<Uid, IManifestNode> = new Map();
29
32
  this.pkHash = {};
30
33
  if (each?.length) {
31
34
  if (!each.forEach) {
32
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
35
+
33
36
  throw new Error(`[each] Items has no forEach() ${each.toString()}`);
34
37
  }
35
- each.forEach((datum: Datum, index: number) => {
38
+ each.forEach((_datum: Datum, index: number) => {
39
+ const datum = typeof _datum === "string" ? { id: _datum } : _datum;
36
40
  let id = datum.id;
41
+
37
42
  if (id == null) {
38
43
  this.logError("ERROR: empty item id: ", datum);
39
44
  id = String(index);
40
45
  }
46
+
41
47
  const pk = String(id);
42
48
  if (this.pkHash[pk]) {
43
49
  this.logError(`ERROR: duplicate item id : ${pk} (skipped)`, datum);
44
50
  return;
45
51
  }
52
+
46
53
  this.pkHash[pk] = datum;
54
+
47
55
  const inode = itemNode
48
56
  .cloneWithDatum(datum, this.platform)
49
57
  .addPropertyResolver(() => this.pkHash[pk], itemNode.itemName);
58
+
50
59
  nodes.set(inode.uid, inode);
51
60
  });
52
61
  }
@@ -59,9 +68,12 @@ export class CForNode extends ManifestNode {
59
68
  #itemName: string;
60
69
  #xmlNode: XmlNode;
61
70
  constructor(xmlNode: XmlNode, [itemName, prep, expr = prep]: string[]) {
62
- super();
71
+ super(xmlNode.id);
72
+
63
73
  this.#xmlNode = xmlNode;
64
- this.#itemName = itemName;
74
+
75
+ this.#itemName = itemName.startsWith("@") ? itemName.slice(1) : itemName;
76
+
65
77
  if (expr[0] === "<" && expr[1] === "-") {
66
78
  this.addConnector(expr.slice(2), "each");
67
79
  } else {
@@ -71,7 +83,7 @@ export class CForNode extends ManifestNode {
71
83
 
72
84
  getItemCtxNode(platform: IPlatform) {
73
85
  return (
74
- this.#itemNode ?? (this.#itemNode = new CItemNode(this.#itemName, platform.getCompiledNodes([this.#xmlNode])))
86
+ this.#itemNode ?? (this.#itemNode = new CItemNode(this.#xmlNode.id, this.#itemName, platform.getCompiledNodes([this.#xmlNode])))
75
87
  );
76
88
  }
77
89
 
@@ -80,8 +92,8 @@ export class CForNode extends ManifestNode {
80
92
  }
81
93
  }
82
94
 
83
- class IterativeItem extends Entitron<CItemNode> {
84
- get recontentScope(): Entitron {
95
+ class IterativeItem extends Arrmatron<CItemNode> {
96
+ get recontentScope(): Arrmatron {
85
97
  return this;
86
98
  }
87
99
 
@@ -103,17 +115,17 @@ class IterativeItem extends Entitron<CItemNode> {
103
115
 
104
116
  class CItemNode extends ManifestNode {
105
117
  itemName: string;
106
- constructor(itemName: string, content?: EContent) {
107
- super();
118
+ constructor(id: string, itemName: string, content?: EContent) {
119
+ super(id);
108
120
  this.itemName = itemName;
109
121
  this.$content = content;
110
122
  }
111
123
 
112
124
  cloneWithDatum(datum: Datum, platform: IPlatform) {
113
125
  const uid = `${String(this.uid)}#${datum.id}`;
114
- return Object.assign(new CItemNode(this.itemName, this.getSubNodes(platform)), {
115
- uid,
116
- });
126
+ const c = new CItemNode(uid, this.itemName, this.getSubNodes(platform));
127
+ c.uid = uid;
128
+ return c;
117
129
  }
118
130
 
119
131
  get EntitronConstructor() {
@@ -1,16 +1,18 @@
1
- import { ManifestNode } from "../core/ManifestNode";
2
- import { Entitron } from "../core/Entitron";
3
- import type { Hash, XmlNode } from "ultimus/types";
4
1
  import type { EContent, IPlatform } from "arrmatura/types";
5
2
  import { xmlParse } from "ultimus";
3
+ import type { Hash, XmlNode } from "ultimus/types";
4
+
5
+ import { Arrmatron } from "../core/Arrmatron";
6
+ import { ManifestNode } from "../core/ManifestNode";
7
+
6
8
  import { CCompositeNode } from "./composition";
7
9
 
8
- class RootCtx extends Entitron<CCompositeNode> {
10
+ class RootCtx extends Arrmatron<CCompositeNode> {
9
11
  get displayName(): string {
10
12
  return `ROOT`;
11
13
  }
12
14
 
13
- get recontentScope(): Entitron {
15
+ get recontentScope(): Arrmatron {
14
16
  return this;
15
17
  }
16
18
 
@@ -28,7 +30,7 @@ export class CRootNode extends ManifestNode {
28
30
  nodes?: XmlNode["nodes"];
29
31
 
30
32
  constructor(private template: string) {
31
- super();
33
+ super('R0');
32
34
  this.slotContent = {};
33
35
  }
34
36
 
@@ -1,14 +1,15 @@
1
- import { ManifestNode } from "../core/ManifestNode";
2
- import { Entitron } from "../core/Entitron";
3
1
  import type { XmlNode } from "ultimus/types";
4
2
 
5
- class DynamicTag extends Entitron<CDynamicTagNode> {
3
+ import { Arrmatron } from "../core/Arrmatron";
4
+ import { ManifestNode } from "../core/ManifestNode";
5
+
6
+ class DynamicTag extends Arrmatron<CDynamicTagNode> {
6
7
  get displayName(): string {
7
8
  return "dynamics";
8
9
  }
9
10
 
10
11
  get contentManifests() {
11
- const tag = this.component.tag;
12
+ const tag = this.$component.tag;
12
13
  const uid = `${this.uid}:${String(tag ?? "")}`;
13
14
  return new Map([
14
15
  [uid, Object.assign(this.platform.getCompiledNodes({ ...this.manifest.xml, tag } as XmlNode), { uid })],
@@ -20,7 +21,7 @@ export class CDynamicTagNode extends ManifestNode {
20
21
  xml: XmlNode & { tag: string };
21
22
 
22
23
  constructor(xml: XmlNode, expr: string) {
23
- super();
24
+ super(xml.id);
24
25
  this.compileAttribute("tag", expr);
25
26
  this.xml = xml;
26
27
  }
@@ -1,9 +1,10 @@
1
- import { ManifestNode } from "../core/ManifestNode";
2
- import { Entitron } from "../core/Entitron";
3
- import type { Hash, XmlNode } from "ultimus/types";
4
1
  import type { EContent, IPlatform } from "arrmatura/types";
2
+ import type { Hash, XmlNode } from "ultimus/types";
3
+
4
+ import { Arrmatron } from "../core/Arrmatron";
5
+ import { ManifestNode } from "../core/ManifestNode";
5
6
 
6
- export class Selector extends Entitron<CSelectorNode> {
7
+ export class Selector extends Arrmatron<CSelectorNode> {
7
8
  get displayName(): string {
8
9
  return `💠Selector`;
9
10
  }
@@ -15,9 +16,10 @@ export class Selector extends Entitron<CSelectorNode> {
15
16
  */
16
17
  get contentManifests() {
17
18
  const cases = this.manifest.getCases(this.platform);
18
- const matchedCase = cases?.[this.component.on as string];
19
+ const onKey = this.$component.On as string;
20
+ const matchedCase = cases?.[onKey];
19
21
  if (!matchedCase) {
20
- this.log("unmatched case", this.component.on, cases);
22
+ this.log("unmatched case", onKey, cases);
21
23
  }
22
24
  return matchedCase ?? cases?.["default"] ?? Object.values(cases)[0];
23
25
  }
@@ -28,8 +30,8 @@ export class CSelectorNode extends ManifestNode {
28
30
  key = "";
29
31
  nodes?: XmlNode["nodes"];
30
32
 
31
- constructor({ tag, attrs, nodes }: XmlNode) {
32
- super();
33
+ constructor({ id, tag, attrs, nodes }: XmlNode) {
34
+ super(id);
33
35
  this.tag = tag;
34
36
  this.nodes = nodes;
35
37
  this.compileAttributes(attrs);
@@ -45,7 +47,7 @@ export class CSelectorNode extends ManifestNode {
45
47
  return (
46
48
  this.cases ??
47
49
  (this.cases = (this.nodes ?? []).reduce<Hash<EContent>>((groups, node) => {
48
- groups[node.attrs?.when as string] = platform.getCompiledNodes(node.nodes ?? []);
50
+ groups[node.attrs?.When as string] = platform.getCompiledNodes(node.nodes ?? []);
49
51
  return groups;
50
52
  }, {}))
51
53
  );