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,10 +1,11 @@
1
- import { ManifestNode } from "../core/ManifestNode";
2
- import { Entitron } from "../core/Entitron";
3
1
  import type { XmlNode } from "ultimus/types";
4
- import type { IEntitron } from "arrmatura/types";
2
+
3
+ import { Arrmatron } from "../core/Arrmatron";
4
+ import { ManifestNode } from "../core/ManifestNode";
5
+
5
6
  import { Composite } from "./composition";
6
7
 
7
- class Slot extends Entitron {
8
+ class Slot extends Arrmatron {
8
9
  get displayName(): string {
9
10
  return "🔸";
10
11
  }
@@ -17,7 +18,7 @@ class Slot extends Entitron {
17
18
  return this.compositeScope.slotContent((this.manifest as CSlotNode).key);
18
19
  }
19
20
 
20
- get recontentScope(): IEntitron {
21
+ get recontentScope(): Arrmatron {
21
22
  return this.compositeScope.scope;
22
23
  }
23
24
  }
@@ -26,8 +27,8 @@ export class CSlotNode extends ManifestNode {
26
27
  key?: string;
27
28
 
28
29
  constructor(x: XmlNode) {
29
- super();
30
- this.key = x.attrs?.key as string;
30
+ super(x.id);
31
+ this.key = x.attrs?.Key as string;
31
32
  }
32
33
 
33
34
  get EntitronConstructor() {
@@ -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,8 +1,88 @@
1
- import { scalarParse } from "ultimus";
1
+ import type { IArrmatron } from "arrmatura/types";
2
+ import { scalarParse, gettus } from "ultimus";
2
3
  import type { ExpressionText, Fn, StringHash } from "ultimus/types";
3
- import type { IEntitron } from "arrmatura/types";
4
4
 
5
- type PipeFn = (c: IEntitron, argValue: unknown) => unknown;
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
85
+
6
86
 
7
87
  const OP_SHORTCUTS: StringHash = {
8
88
  "&&": "|and:",
@@ -19,24 +99,31 @@ const OP_SHORTCUTS: StringHash = {
19
99
 
20
100
  const withNoPipes = (_: unknown, v: unknown) => v;
21
101
 
102
+ const isConstKey = (key: string) => "'+-0123456789".includes(key[0]) || key === 'true' || key === 'false';
103
+
22
104
  export function compileConstant(a: string) {
23
105
  const vv = scalarParse(a[0] === "'" ? a.slice(1, a.length - 1) : a);
24
106
  return () => vv;
25
107
  }
26
108
 
27
109
  const compilePropGet = (key: string) => {
28
- return (c: IEntitron) => c.getFromScope(key);
110
+ return (c: IArrmatron) => c.getFromScope(key);
29
111
  };
30
112
 
31
- const compileArgument = (a: string) => {
32
- 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
+ };
33
118
 
34
- if (a.endsWith("#not")) {
35
- const getter = compilePropGet(a.slice(1, a.length - 4));
36
- return (c: IEntitron) => !getter(c);
119
+ if (a[0] === "#" && a[1] === "#") {
120
+ const vv = strings?.[Number(a.slice(2))];
121
+ return () => vv;
37
122
  }
38
123
 
39
- return compilePropGet(a.slice(1));
124
+ if (isConstKey(a)) return compileConstant(a);
125
+
126
+ return compilePropGet(a);
40
127
  };
41
128
 
42
129
  const splitExpression = (v: ExpressionText) =>
@@ -49,22 +136,37 @@ function withPipes(pipes: string[]) {
49
136
  if (!pipes.length) return withNoPipes;
50
137
 
51
138
  const compiledPipes = pipes.map((key) => {
52
- 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());
53
147
  return {
54
148
  pipeId,
55
- args: args.map((a) => compileArgument(a)),
149
+ args: args.map((a) => compileArgument(a, strings)),
56
150
  };
57
151
  });
58
152
 
59
- return (c: IEntitron, initialValue: unknown) =>
153
+ return (c: IArrmatron, initialValue: unknown) =>
60
154
  compiledPipes.reduce((value, { pipeId, args }) => {
61
155
  try {
62
156
  const fn = c.platform.getFunction(pipeId);
63
157
  if (typeof fn !== "function") {
64
158
  throw new Error(`${fn != null ? "must be a function" : "not found"}`);
65
159
  }
66
- const args0 = [value, ...args.map((fn) => fn(c))];
67
- 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
+ }
68
170
  } catch (ex) {
69
171
  c.logError(`ERROR: Function ${pipeId || "<empty>"}`, ex);
70
172
  return value;
@@ -74,35 +176,40 @@ function withPipes(pipes: string[]) {
74
176
 
75
177
  function withHardValue(hardValue: ExpressionText, pipec: PipeFn): PipeFn {
76
178
  if (!hardValue || hardValue === '*') return pipec;
77
- const iniFn = hardValue[0] === "@" ? compilePlaceholder(hardValue) : compileConstant(hardValue);
78
- return (c: IEntitron) => pipec(c, iniFn(c));
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));
79
188
  }
80
189
 
81
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
+
82
196
  const [_key, ...pipes] = splitExpression(v);
83
197
  const [key, hardValue] = _key.split("=").map((s) => s.trim());
198
+
84
199
  return { key, pipec: withHardValue(hardValue, withPipes(pipes)) };
85
200
  }
86
201
 
87
202
  export function compilePlaceholder(expr: string): Fn {
88
203
  const [key, ...pipesExpressions] = splitExpression(expr);
89
- const pipec = withPipes(pipesExpressions);
90
204
 
91
- let fn: any = null;
205
+ const pipec = withPipes(pipesExpressions);
92
206
 
93
- if (key[0] === "'") {
94
- fn = compileConstant(key);
95
- } else {
96
- if (key[0] !== "@") {
97
- console.warn(`Invalid placeholder: missed @-prefix: "${expr}"`);
98
- }
99
- fn = compileArgument(key[0] === "@" ? key : `@${key}`);
100
- }
207
+ const fn = compileArgument(key);
101
208
 
102
- return (c) => pipec(c as IEntitron, fn(c));
209
+ return (c) => pipec(c as IArrmatron, fn(c));
103
210
  }
104
211
 
105
212
  export function compileJsExpression(x: string) {
106
- return new Function("c", x.replaceAll(/[^'a-z]([a-z][a-z0-9-\.]+)/gi, 'c.prop("$1")'));
213
+ return new Function("c", x.replaceAll(/[^'a-z]([a-z][a-z0-9-.]+)/gi, 'c.prop("$1")'));
107
214
  }
108
215
 
@@ -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
+ })
package/types.ts CHANGED
@@ -1,64 +1,75 @@
1
1
  import { Uid, Delta, Data, LogEntry, Hash, XmlNode } from "ultimus/types";
2
2
 
3
+ import { Arrmatron } from "./src/core/Arrmatron";
4
+
3
5
  export type IComponent = {
4
- $element?: unknown; // native implementation
5
- done?: (c: IEntitron) => void;
6
- // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
7
- init?: (c: IEntitron) => Delta | null | undefined | unknown | void;
8
- stateChanged?: (changes: Map<string, unknown>) => void;
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
9
14
  [key: string]: unknown;
10
15
  }
11
16
 
12
- export type IEntitron = {
17
+ export type IArrmatron = {
13
18
  isDone: any;
14
19
  readonly uid: Uid;
15
- parent?: IEntitron;
16
- children?: Map<Uid, IEntitron>;
17
- scope?: IEntitron;
18
- component: IComponent;
19
- root: IEntitron;
20
+ parent?: IArrmatron;
21
+ children?: Map<Uid, IArrmatron>;
22
+ scope?: IArrmatron;
23
+ $component: IComponent;
24
+ root: IArrmatron;
20
25
  platform: IPlatform;
21
26
 
27
+ // state access
28
+ get: (propId: string) => unknown;
29
+ getFromScope: (key: string) => unknown;
22
30
  up: (d: Delta | null | void | unknown, force?: boolean) => void;
31
+
23
32
  touch: () => void;
24
33
  emit: (key: string, arg1: Delta) => void;
25
- res: (key: string | string[]) => Data;
26
- log: (val: unknown, ...arg1: unknown[]) => void;
27
- logError: (error: unknown, ...arg1: unknown[]) => void;
28
- defer: (fn: () => void) => void;
29
- get: (propId: string) => unknown;
30
34
 
35
+ // done life-cycle hook
31
36
  done: () => void;
37
+ defer: (fn: () => void) => void;
32
38
 
33
- addReference: (refId: string, r: IEntitron) => void;
34
- getByRef: (refId: string) => IEntitron | undefined;
35
- getFromScope: (key: string) => unknown;
36
- settleAsChild: () => void;
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;
37
46
  }
38
47
 
39
48
  export type IManifestNode = {
40
- connectors?: Map<string, (c: IEntitron, x: unknown) => unknown>;
49
+ connectors?: Map<string, (c: IArrmatron, x: unknown) => unknown>;
41
50
  refId?: string;
42
51
  readonly uid: Uid;
43
52
  getSubNodes(platform: IPlatform): Map<Uid, IManifestNode> | undefined;
44
- resolveProps: (c: IEntitron) => Delta | Promise<unknown> | undefined;
45
- resolveInitialProps: (c: IEntitron) => Hash;
53
+ resolveProps: (c: IArrmatron) => Delta | Promise<unknown> | undefined;
54
+ resolveInitialProps: (c: IArrmatron) => Hash;
46
55
 
47
- createEntitron: (platform: IPlatform, parent?: IEntitron, scope?: IEntitron) => IEntitron;
56
+ createArrmatron: (platform: IPlatform, parent?: Arrmatron, scope?: Arrmatron) => Arrmatron;
48
57
  }
49
58
 
50
59
  export type IPlatform = {
51
60
  log(arg0: LogEntry): void;
61
+ toast(t: LogEntry, ctx: IArrmatron): void;
52
62
  getCompiledNodes(tag: string): Map<Uid, IManifestNode>;
53
63
  getCompiledNodes(tag: XmlNode): IManifestNode;
54
64
  getCompiledNodes(tag: XmlNode[]): Map<Uid, IManifestNode>;
65
+ updateResources(delta: any): void;
55
66
  getResource(key: string | string[]): Data;
56
67
  getFunction(id: string): (...args: unknown[]) => unknown;
57
- redraw(source: IEntitron, root: IEntitron): void;
58
- createComponent(def: IComponentDescriptor | string, initials: Hash, ctx: IEntitron): IComponent | Hash;
68
+ redraw(source: IArrmatron, root: IArrmatron): void;
69
+ createComponent(def: IComponentDescriptor | string, initials: Hash, ctx: IArrmatron): IComponent | Hash;
59
70
  }
60
71
 
61
- export type ComponentConstructor = new (initials: Hash, c: IEntitron) => IComponent;
72
+ export type ComponentConstructor = new (initials: Hash, c: IArrmatron) => IComponent;
62
73
 
63
74
  export type IComponentDescriptor = {
64
75
  tag?: string;
@@ -68,6 +79,4 @@ export type IComponentDescriptor = {
68
79
  native?: boolean;
69
80
  }
70
81
 
71
- export type EclecticTypeInfo = string | IComponentDescriptor | ComponentConstructor;
72
-
73
82
  export type EContent = Map<Uid, IManifestNode>;