arrmatura 6.2.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.
@@ -0,0 +1,128 @@
1
+ const CACHE = new Map();
2
+
3
+ function upnum(r: number, n: number) {
4
+ const rr = ((r << 5) - r) + n;
5
+ return rr & rr;
6
+ }
7
+
8
+ const COLON_NUM = ":".charCodeAt(0);
9
+
10
+ function stringHash(x: string) {
11
+ let h = 0;
12
+ if (CACHE.has(x)) {
13
+ h = CACHE.get(x) as number;
14
+ } else {
15
+ for (let i = 0; i < x.length; i++) {
16
+ h = upnum(h, x.charCodeAt(i));
17
+ }
18
+ CACHE.set(x, h);
19
+ }
20
+ return h;
21
+ }
22
+
23
+ export class FingerprintMashine {
24
+ r = 0;
25
+ x?: any;
26
+ $path?: Set<unknown>;
27
+
28
+ get path() {
29
+ return this.$path ?? (this.$path = new Set());
30
+ }
31
+
32
+ upNumber(n: number) {
33
+ return (this.r = upnum(this.r, n));
34
+ }
35
+
36
+ upString(x: string) {
37
+ return this.upNumber(stringHash(x))
38
+ }
39
+
40
+ upObject(x) {
41
+
42
+ if (x.$hash) return x.$hash;
43
+
44
+ if (x instanceof Date) return this.upNumber(x.getTime());
45
+
46
+ if (this.path.size > 10 || this.path.has(x)) {
47
+ return;
48
+ }
49
+
50
+ this.path.add(x);
51
+
52
+ if (x instanceof Map) {
53
+ this.upString("$$$Map$$$");
54
+ x.forEach((v, k) => {
55
+ this.upString(k);
56
+ this.upNumber(COLON_NUM);
57
+ this.upAny(v);
58
+ })
59
+ } else if (x instanceof Set) {
60
+ this.upString("$$$Set$$$");
61
+ x.forEach((v) => this.upAny(v))
62
+ } else if (Array.isArray(x)) {
63
+ this.upString("$$$Array$$$");
64
+ x.forEach((v) => this.upAny(v))
65
+ } else {
66
+ this.upString("$$$Object$$$");
67
+ for (const k in x) {
68
+ if (Object.prototype.hasOwnProperty.call(x, k) && k[0] !== '$') {
69
+ this.upString(k)
70
+ this.upNumber(COLON_NUM);
71
+ this.upAny(x[k]);
72
+ }
73
+ }
74
+ }
75
+
76
+ this.path.delete(x);
77
+
78
+ return this.r;
79
+ }
80
+ upAny(x: any): void {
81
+
82
+ if (x == null) {
83
+ this.upString(String(x));
84
+ } else if (typeof x === 'number') {
85
+ if (isNaN(x)) {
86
+ this.upString(`$$$NaN$$$`);
87
+ } else {
88
+ this.upNumber(x);
89
+ }
90
+ } else if (typeof x === 'object') {
91
+ this.upObject(x);
92
+ } else if (typeof x === 'string') {
93
+ this.upString(x);
94
+ } else if (typeof x === 'boolean') {
95
+ this.upString(`$$$Boolean$$$${x}`);
96
+ } else if (typeof x === 'function') {
97
+ // this.upString(`$$$Function$$$${x}`);
98
+ } else {
99
+ this.upString(String(x))
100
+ }
101
+ }
102
+
103
+ do(x: any) {
104
+
105
+ if (x == null) return x;
106
+
107
+ if (typeof x !== "object") return x;
108
+
109
+ if (Object.isFrozen(x)) return x;
110
+
111
+ if (x.$hash) return x.$hash;
112
+
113
+ this.r = 0;
114
+ this.x = x;
115
+ if (this.$path) {
116
+ this.$path?.clear();
117
+ }
118
+
119
+ this.upObject(x);
120
+
121
+ return this.r;
122
+ }
123
+
124
+ }
125
+
126
+ const FM = new FingerprintMashine();
127
+
128
+ export const objectFingerprint = (x: any) => FM.do(x)
@@ -0,0 +1,18 @@
1
+ import { capitalize } from "ultimus";
2
+
3
+ import type { IComponent } from "../../types";
4
+
5
+ export function applyStateChangedToImpl(changes: Map<string, unknown>, impl: IComponent) {
6
+ if (impl.__stateChanged) {
7
+ impl.__stateChanged(changes);
8
+ } else {
9
+ changes.forEach((v, k) => {
10
+ const setter = impl[`set${capitalize(k)}`];
11
+ if (typeof setter === "function") {
12
+ setter.call(impl, v);
13
+ } else {
14
+ impl[k] = v;
15
+ }
16
+ });
17
+ }
18
+ }
@@ -1,9 +1,88 @@
1
- import { scalarParse } from "ultimus";
2
- import type { Expression, Fn, StringHash } from "ultimus/types";
3
- import type { ICtx } from "arrmatura-api/types";
4
- import { createStringInterpolator } from "ultimus/src/parsing/createStringInterpolator";
1
+ import type { IArrmatron } from "arrmatura/types";
2
+ import { scalarParse, gettus } from "ultimus";
3
+ import type { ExpressionText, Fn, StringHash } from "ultimus/types";
4
+
5
+ type PipeFn = (c: IArrmatron, argValue: unknown) => unknown;
6
+
7
+ // function tokenize(expression) {
8
+ // return expression.split(/[\(\)\<\>=\?!:']+/g);
9
+ // }
10
+ // class Node {
11
+ // constructor(public type, public value: string | null = null, public left = null, public right = null) {
12
+ // }
13
+ // }
14
+
15
+ // function parse(tokens) {
16
+ // let current = 0;
17
+
18
+ // function walk(priority = 0) {
19
+ // const token = tokens[current++];
20
+ // const nextToken = tokens[current];
21
+
22
+ // if (priority >= 0 && token === '(') {
23
+ // const node = walk();
24
+ // current++;
25
+ // return node;
26
+ // }
27
+
28
+ // if (priority >= 0 && ['>', '<', '==', '!=', '&&', '||', '??'].includes(nextToken)) {
29
+ // return new Node('binary', nextToken, walk(), walk());
30
+ // }
31
+
32
+ // if (priority >= 0 && ['>', '<', '==', '!=', '&&', '||', '??'].includes(nextToken)) {
33
+ // return new Node('binary', nextToken, walk(), walk());
34
+ // }
35
+
36
+ // if (priority >= 0 && ['>', '<', '==', '!=', '&&', '||', '??'].includes(nextToken)) {
37
+ // return new Node('binary', nextToken, walk(), walk());
38
+ // }
39
+
40
+ // if (priority >= 0 && nextToken === '?') {
41
+ // const node = new Node('coalesce', walk());
42
+ // if (tokens[current] !== ':') {
43
+ // throw new TypeError('Expected colon after "?" in coalesce operation');
44
+ // }
45
+ // current++;
46
+ // node.right = new Node('colon', token, walk(), walk());
47
+ // return node;
48
+ // }
49
+ // return new Node('operand', (token));;
50
+ // }
51
+
52
+ // return walk();
53
+ // }
54
+
55
+ // function evaluate(node) {
56
+ // switch (node.type) {
57
+ // case 'number':
58
+ // return node.value;
59
+ // case 'operator':
60
+ // switch (node.value) {
61
+ // case '>':
62
+ // return evaluate(node.left) > evaluate(node.right);
63
+ // case '<':
64
+ // return evaluate(node.left) < evaluate(node.right);
65
+ // case '==':
66
+ // return evaluate(node.left) == evaluate(node.right);
67
+ // case '!=':
68
+ // return evaluate(node.left) != evaluate(node.right);
69
+ // default:
70
+ // throw new TypeError(`Unknown operator: ${node.value}`);
71
+ // }
72
+ // case 'coalesce':
73
+ // const condition = evaluate(node.left);
74
+ // return condition ? evaluate(node.middle) : evaluate(node.right);
75
+ // default:
76
+ // throw new TypeError(`Unknown node type: ${node.type}`);
77
+ // }
78
+ // }
79
+
80
+ // // Example usage
81
+ // const expression = '1 < 2 ? 3 : 4';
82
+ // const tokens = tokenize(expression);
83
+ // const ast = parse(tokens);
84
+ // console.log(evaluate(ast)); // Outputs: 3
5
85
 
6
- type PipeFn = (c: ICtx, argValue: unknown) => unknown;
7
86
 
8
87
  const OP_SHORTCUTS: StringHash = {
9
88
  "&&": "|and:",
@@ -20,27 +99,34 @@ const OP_SHORTCUTS: StringHash = {
20
99
 
21
100
  const withNoPipes = (_: unknown, v: unknown) => v;
22
101
 
23
- function compileConstant(a: string) {
102
+ const isConstKey = (key: string) => "'+-0123456789".includes(key[0]) || key === 'true' || key === 'false';
103
+
104
+ export function compileConstant(a: string) {
24
105
  const vv = scalarParse(a[0] === "'" ? a.slice(1, a.length - 1) : a);
25
106
  return () => vv;
26
107
  }
27
108
 
28
109
  const compilePropGet = (key: string) => {
29
- return (c: ICtx) => c.getFromScope(key);
110
+ return (c: IArrmatron) => c.getFromScope(key);
30
111
  };
31
112
 
32
- const compileArgument = (a: string) => {
33
- if (a[0] !== "@") return compileConstant(a);
113
+ const compileArgument = (a: string, strings?: string[]) => {
114
+ if (a[0] === "!") {
115
+ const getter = compilePropGet(a.slice(1));
116
+ return (c: IArrmatron) => !getter(c);
117
+ };
34
118
 
35
- if (a.endsWith("#not")) {
36
- const getter = compilePropGet(a.slice(1, a.length - 4));
37
- return (c: ICtx) => !getter(c);
119
+ if (a[0] === "#" && a[1] === "#") {
120
+ const vv = strings?.[Number(a.slice(2))];
121
+ return () => vv;
38
122
  }
39
123
 
40
- return compilePropGet(a.slice(1));
124
+ if (isConstKey(a)) return compileConstant(a);
125
+
126
+ return compilePropGet(a);
41
127
  };
42
128
 
43
- const splitExpression = (v: Expression) =>
129
+ const splitExpression = (v: ExpressionText) =>
44
130
  v
45
131
  .replace(/(&&|!=|==|>|<|\[|\]|\|\||\?\??)/g, (_, s) => `${OP_SHORTCUTS[s]}`)
46
132
  .split("|")
@@ -50,22 +136,37 @@ function withPipes(pipes: string[]) {
50
136
  if (!pipes.length) return withNoPipes;
51
137
 
52
138
  const compiledPipes = pipes.map((key) => {
53
- const [pipeId, ...args] = key.split(":").map((s) => s.trim());
139
+ const strings: string[] = [];
140
+
141
+ const expr = key.replaceAll(/'[^']*'/g, (s) => {
142
+ strings.push(s.slice(1, -1))
143
+ return `##${strings.length - 1}`
144
+ });
145
+
146
+ const [pipeId, ...args] = expr.split(":").map((s) => s.trim());
54
147
  return {
55
148
  pipeId,
56
- args: args.map((a) => compileArgument(a)),
149
+ args: args.map((a) => compileArgument(a, strings)),
57
150
  };
58
151
  });
59
152
 
60
- return (c: ICtx, initialValue: unknown) =>
153
+ return (c: IArrmatron, initialValue: unknown) =>
61
154
  compiledPipes.reduce((value, { pipeId, args }) => {
62
155
  try {
63
156
  const fn = c.platform.getFunction(pipeId);
64
157
  if (typeof fn !== "function") {
65
158
  throw new Error(`${fn != null ? "must be a function" : "not found"}`);
66
159
  }
67
- const args0 = [value, ...args.map((fn) => fn(c))];
68
- return fn.apply(c, args0);
160
+ if (value instanceof Promise) {
161
+ return value.then((val) => {
162
+ const args0 = [val, ...args.map((fn) => fn(c))];
163
+ const result = fn.apply(c, args0);
164
+ return result;
165
+ });
166
+ } else {
167
+ const args0 = [value, ...args.map((fn) => fn(c))];
168
+ return fn.apply(c, args0);
169
+ }
69
170
  } catch (ex) {
70
171
  c.logError(`ERROR: Function ${pipeId || "<empty>"}`, ex);
71
172
  return value;
@@ -73,54 +174,42 @@ function withPipes(pipes: string[]) {
73
174
  }, initialValue);
74
175
  }
75
176
 
76
- function withHardValue(hardValue: Expression, pipec: PipeFn): PipeFn {
77
- if (hardValue === undefined) return pipec;
78
- const iniFn =
79
- hardValue[0] === "@"
80
- ? compilePlaceholder(hardValue)
81
- : compileConstant(hardValue);
82
- return (c: ICtx) => pipec(c, iniFn(c));
177
+ function withHardValue(hardValue: ExpressionText, pipec: PipeFn): PipeFn {
178
+ if (!hardValue || hardValue === '*') return pipec;
179
+
180
+ if (hardValue.startsWith('*.')) {
181
+ const propKey = hardValue.slice(2)
182
+ return (c: IArrmatron, ini: any) => pipec(c, gettus(ini, propKey));
183
+ }
184
+
185
+ const iniFn = isConstKey(hardValue) ? compileConstant(hardValue) : compilePlaceholder(hardValue);
186
+
187
+ return (c: IArrmatron) => pipec(c, iniFn(c));
83
188
  }
84
189
 
85
- export function compilePipeExpression(v: Expression) {
190
+ export function compilePipeExpression(v: ExpressionText) {
191
+ if (v.endsWith(')')) {
192
+ const parts = v.slice(0, -1).split('(')
193
+ return compilePipeExpression(`${parts[0]}=${parts[1]}`);
194
+ }
195
+
86
196
  const [_key, ...pipes] = splitExpression(v);
87
197
  const [key, hardValue] = _key.split("=").map((s) => s.trim());
198
+
88
199
  return { key, pipec: withHardValue(hardValue, withPipes(pipes)) };
89
200
  }
90
201
 
91
202
  export function compilePlaceholder(expr: string): Fn {
92
-
93
203
  const [key, ...pipesExpressions] = splitExpression(expr);
94
- const pipec = withPipes(pipesExpressions);
95
204
 
96
- let fn: any = null;
205
+ const pipec = withPipes(pipesExpressions);
97
206
 
98
- if (key[0] === "'") {
99
- fn = compileConstant(key);
100
- } else {
101
- if (key[0] !== "@") {
102
- console.warn(`Invalid placeholder "${expr}"`);
103
- }
104
- fn = compileArgument(key[0] === "@" ? key : `@${key}`);
105
- }
207
+ const fn = compileArgument(key);
106
208
 
107
- return (c) => pipec(c as ICtx, fn(c));
209
+ return (c) => pipec(c as IArrmatron, fn(c));
108
210
  }
109
211
 
110
- const JS = {}
111
212
  export function compileJsExpression(x: string) {
112
- return JS[x] ?? (JS[x] = new Function('c', x.replaceAll(/[^'a-z]([a-z][a-z0-9-\.]+)/ig, 'c.prop("$1")')))
213
+ return new Function("c", x.replaceAll(/[^'a-z]([a-z][a-z0-9-.]+)/gi, 'c.prop("$1")'));
113
214
  }
114
215
 
115
- export function compileExpression(v: unknown) {
116
- if (typeof v !== "string") return () => v;
117
-
118
- if (v[0] === "@") return compilePlaceholder(v);
119
-
120
- if (v.startsWith("js:")) return compileJsExpression(v.slice(3));
121
-
122
- if (v.includes("{"))
123
- return createStringInterpolator(v.replace(/\s+/g, " "), compilePlaceholder);
124
-
125
- return compileConstant(v);
126
- }
@@ -0,0 +1,70 @@
1
+ import { objectFingerprint } from './FingerprintMashine';
2
+
3
+ describe('objectFingerprint', () => {
4
+ it('should return 0 for null or undefined input', () => {
5
+ expect(objectFingerprint(null)).toBe(null);
6
+ expect(objectFingerprint(undefined)).toBe(undefined);
7
+ expect(objectFingerprint(0)).toBe(0);
8
+ expect(objectFingerprint("")).toBe("");
9
+ });
10
+
11
+ it('should return the same hash value for the same input string, regardless of the case of its characters', () => {
12
+ const str1 = 'Hello World';
13
+ const str2 = 'Hello World';
14
+ const str3 = 'Hello world';
15
+ expect(objectFingerprint(str1)).toBe(objectFingerprint(str2));
16
+ expect(objectFingerprint(str1)).not.toBe(objectFingerprint(str3));
17
+ });
18
+
19
+ it('should return a unique hash value for different input objects', () => {
20
+ const obj1 = { foo: 'bar' };
21
+ const obj2 = { bar: 'baz' };
22
+ expect(objectFingerprint(obj1)).not.toBe(objectFingerprint(obj2));
23
+ });
24
+
25
+ it('should return the same hash value for the same input object, regardless of the order of its properties', () => {
26
+ const obj0 = { foo: 'bar', baz: 'qux' };
27
+ const obj1 = { foo: 'bar', baz: 'qux' };
28
+ const obj2 = { baz: 'qux', foo: 'bar' };
29
+ expect(objectFingerprint(obj1)).toBe(objectFingerprint(obj0));
30
+ expect(objectFingerprint(obj1)).not.toBe(objectFingerprint(obj2));
31
+ });
32
+
33
+ it('should return the same hash value for the same input array, regardless of the order of its elements', () => {
34
+ const arr0 = [1, 2, 3];
35
+ const arr1 = [1, 2, 3];
36
+ const arr2 = [3, 2, 1];
37
+ expect(objectFingerprint(arr1)).toBe(objectFingerprint(arr0));
38
+ expect(objectFingerprint(arr1)).not.toBe(objectFingerprint(arr2));
39
+ });
40
+
41
+ it('should return the same hash value for the same input map, regardless of the order of its entries', () => {
42
+ const map0 = new Map([[1, 'one'], [2, 'two']]);
43
+ const map1 = new Map([[1, 'one'], [2, 'two']]);
44
+ const map2 = new Map([[2, 'two'], [1, 'one']]);
45
+ expect(objectFingerprint(map1)).toBe(objectFingerprint(map0));
46
+ expect(objectFingerprint(map1)).not.toBe(objectFingerprint(map2));
47
+ });
48
+
49
+ it('should return the same hash value for the same input set, regardless of the order of its elements', () => {
50
+ const set0 = new Set([1, 2, 3]);
51
+ const set1 = new Set([1, 2, 3]);
52
+ const set2 = new Set([3, 2, 1]);
53
+ expect(objectFingerprint(set1)).toBe(objectFingerprint(set0));
54
+ expect(objectFingerprint(set1)).not.toBe(objectFingerprint(set2));
55
+ });
56
+
57
+
58
+ it('should return the same hash value for the same input number, regardless of its precision', () => {
59
+ const num1 = 3.14159;
60
+ const num2 = 3.14159;
61
+ const num3 = 3.14158;
62
+ expect(objectFingerprint(num1)).toBe(objectFingerprint(num2));
63
+ expect(objectFingerprint(num1)).not.toBe(objectFingerprint(num3));
64
+ });
65
+
66
+ it('should return the same hash value for the same input boolean, regardless of its value', () => {
67
+ expect(objectFingerprint(true)).toBe(objectFingerprint(true));
68
+ expect(objectFingerprint(false)).toBe(objectFingerprint(false))
69
+ });
70
+ })
@@ -2,9 +2,7 @@ import { Hash } from "ultimus";
2
2
  const attributesToString = (v?: Hash): string => {
3
3
  if (typeof v === "object") {
4
4
  if (Array.isArray(v)) {
5
- return !v.length
6
- ? "[]"
7
- : `[${attributesToString(v[0]) ?? ""} x${String(v.length)}]`;
5
+ return !v.length ? "[]" : `[${attributesToString(v[0]) ?? ""} x${String(v.length)}]`;
8
6
  }
9
7
  return `{${Object.keys(v).toString()}}`;
10
8
  }
@@ -29,11 +27,7 @@ const stringifyState = (attrs?: object | Hash) => {
29
27
  export const stringify = (T: any, tab = ""): string => {
30
28
  const { uid, displayName: tag = uid, component: impl, children } = T;
31
29
 
32
- const ssubs: string = children?.size
33
- ? [...children.values()].map((c) => stringify(c, ` ${tab}`)).join("\n")
34
- : "";
30
+ const ssubs: string = children?.size ? [...children.values()].map((c) => stringify(c, ` ${tab}`)).join("\n") : "";
35
31
 
36
- return `${tab}<${tag}${stringifyState(impl)}${
37
- !ssubs ? "/>" : `>\n${ssubs}\n${tab}</${tag}>`
38
- }`;
32
+ return `${tab}<${tag}${stringifyState(impl)}${!ssubs ? "/>" : `>\n${ssubs}\n${tab}</${tag}>`}`;
39
33
  };
package/types.ts ADDED
@@ -0,0 +1,82 @@
1
+ import { Uid, Delta, Data, LogEntry, Hash, XmlNode } from "ultimus/types";
2
+
3
+ import { Arrmatron } from "./src/core/Arrmatron";
4
+
5
+ export type IComponent = {
6
+ // optional Lifecycle method called when the component is done.
7
+ done?: (c: IArrmatron) => void;
8
+ // optional Lifecycle method called during initialization.
9
+
10
+ init?: (c: IArrmatron) => Delta | null | undefined | unknown | void;
11
+ // optional Lifecycle method called when the state changes.
12
+ __stateChanged?: (changes: Map<string, unknown>) => void;
13
+ // state key/values
14
+ [key: string]: unknown;
15
+ }
16
+
17
+ export type IArrmatron = {
18
+ isDone: any;
19
+ readonly uid: Uid;
20
+ parent?: IArrmatron;
21
+ children?: Map<Uid, IArrmatron>;
22
+ scope?: IArrmatron;
23
+ $component: IComponent;
24
+ root: IArrmatron;
25
+ platform: IPlatform;
26
+
27
+ // state access
28
+ get: (propId: string) => unknown;
29
+ getFromScope: (key: string) => unknown;
30
+ up: (d: Delta | null | void | unknown, force?: boolean) => void;
31
+
32
+ touch: () => void;
33
+ emit: (key: string, arg1: Delta) => void;
34
+
35
+ // done life-cycle hook
36
+ done: () => void;
37
+ defer: (fn: () => void) => void;
38
+
39
+ // get registered arrmatron instance by reference. look up recurrsively from current to root scopes.
40
+ readonly refId?: string;
41
+ getByRef: (refId: string) => IArrmatron | undefined;
42
+
43
+ log: (val: unknown, ...arg1: unknown[]) => void;
44
+ logError: (error: unknown, ...arg1: unknown[]) => void;
45
+ toast(t: LogEntry): void;
46
+ }
47
+
48
+ export type IManifestNode = {
49
+ connectors?: Map<string, (c: IArrmatron, x: unknown) => unknown>;
50
+ refId?: string;
51
+ readonly uid: Uid;
52
+ getSubNodes(platform: IPlatform): Map<Uid, IManifestNode> | undefined;
53
+ resolveProps: (c: IArrmatron) => Delta | Promise<unknown> | undefined;
54
+ resolveInitialProps: (c: IArrmatron) => Hash;
55
+
56
+ createArrmatron: (platform: IPlatform, parent?: Arrmatron, scope?: Arrmatron) => Arrmatron;
57
+ }
58
+
59
+ export type IPlatform = {
60
+ log(arg0: LogEntry): void;
61
+ toast(t: LogEntry, ctx: IArrmatron): void;
62
+ getCompiledNodes(tag: string): Map<Uid, IManifestNode>;
63
+ getCompiledNodes(tag: XmlNode): IManifestNode;
64
+ getCompiledNodes(tag: XmlNode[]): Map<Uid, IManifestNode>;
65
+ updateResources(delta: any): void;
66
+ getResource(key: string | string[]): Data;
67
+ getFunction(id: string): (...args: unknown[]) => unknown;
68
+ redraw(source: IArrmatron, root: IArrmatron): void;
69
+ createComponent(def: IComponentDescriptor | string, initials: Hash, ctx: IArrmatron): IComponent | Hash;
70
+ }
71
+
72
+ export type ComponentConstructor = new (initials: Hash, c: IArrmatron) => IComponent;
73
+
74
+ export type IComponentDescriptor = {
75
+ tag?: string;
76
+ template?: string;
77
+ Ctor?: ComponentConstructor;
78
+ unknown?: boolean;
79
+ native?: boolean;
80
+ }
81
+
82
+ export type EContent = Map<Uid, IManifestNode>;
@@ -1,40 +0,0 @@
1
- import { CtxNode } from "../ctx/CtxNode";
2
- import { Ctx } from "../ctx/Ctx";
3
- import type { Hash, XmlNode } from "ultimus/types";
4
- import { IPlatform } from "arrmatura-api/types";
5
-
6
- class Element extends Ctx<CElementNode> {
7
- get displayName(): string {
8
- return this.node.tag;
9
- }
10
-
11
- createComponent(initials: Hash) {
12
- return this.platform.createComponent(
13
- { tag: this.node.tag, native: true },
14
- initials,
15
- this
16
- );
17
- }
18
- }
19
-
20
- export class CElementNode extends CtxNode {
21
- #nodes: XmlNode[] | undefined;
22
-
23
- constructor({ tag, attrs, nodes, text }: XmlNode) {
24
- super();
25
- this.tag = tag;
26
- this.compileAttributes(attrs);
27
- if (text) {
28
- this.compileAttribute("#text", text);
29
- }
30
- this.#nodes = nodes;
31
- }
32
-
33
- getContent(platform: IPlatform) {
34
- return this.#nodes ? platform.getCompiledNodes(this.#nodes) : undefined;
35
- }
36
-
37
- get EntityConstructor() {
38
- return Element;
39
- }
40
- }
@@ -1,21 +0,0 @@
1
- import { CtxNode } from "../ctx/CtxNode";
2
- import { Ctx } from "../ctx/Ctx";
3
- import type { XmlNode } from "ultimus/types";
4
- import type { IPlatform } from "arrmatura-api/types";
5
-
6
- export class CFragmentNode extends CtxNode {
7
- #nodes: XmlNode[] | undefined;
8
-
9
- constructor({ nodes }: XmlNode) {
10
- super();
11
- this.#nodes = nodes;
12
- }
13
-
14
- getContent(platform: IPlatform) {
15
- return this.#nodes ? platform.getCompiledNodes(this.#nodes) : undefined;
16
- }
17
-
18
- get EntityConstructor() {
19
- return Ctx;
20
- }
21
- }
package/src/core/index.ts DELETED
@@ -1,19 +0,0 @@
1
- import { CForNode } from "./iterations";
2
- import { CCompositeNode } from "./composition";
3
- import { CIfNode } from "./conditionals";
4
- import { CElementNode } from "./elementary";
5
- import { CDynamicTagNode } from "./routing";
6
- import { CSlotNode } from "./slot";
7
- import { CFragmentNode } from "./fragment";
8
- import { CSelectorNode } from "./selection";
9
-
10
- export const Registry = {
11
- CForNode,
12
- CIfNode,
13
- CDynamicTagNode,
14
- CSlotNode,
15
- CFragmentNode,
16
- CCompositeNode,
17
- CSelectorNode,
18
- CElementNode,
19
- };