Skip to content

Commit c6f7d33

Browse files
committed
Shrink-size release:
* reduced N classes to 1 * made all instances predictable * added 100% code coverage
1 parent 3ca9f17 commit c6f7d33

File tree

4 files changed

+115
-117
lines changed

4 files changed

+115
-117
lines changed

cjs/index.js

Lines changed: 32 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
'use strict';
2-
module.exports = (() => {
3-
const ATTRIBUTE = 1;
4-
const COMPONENT = 2;
5-
const ELEMENT = 3;
6-
const FRAGMENT = 4;
7-
const INTERPOLATION = 5;
8-
const STATIC = 6;
9-
10-
const {assign} = Object;
11-
const _ = [];
12-
2+
module.exports = ((
3+
properties, _,
4+
ATTRIBUTE,
5+
COMPONENT,
6+
ELEMENT,
7+
FRAGMENT,
8+
INTERPOLATION,
9+
STATIC
10+
) => (
1311
class ESXToken {
1412
static ATTRIBUTE = ATTRIBUTE;
1513
static COMPONENT = COMPONENT;
@@ -19,57 +17,34 @@ module.exports = (() => {
1917
static STATIC = STATIC;
2018

2119
// transformer utilities
22-
/** @protected */ static _ = _;
23-
/** @protected */ static a = (dynamic, name, value) => ({type: ATTRIBUTE, dynamic, name, value});
24-
/** @protected */ static i = value => ({type: INTERPOLATION, value});
25-
/** @protected */ static s = value => ({type: STATIC, value});
26-
/** @protected */ static c = (id, value, attributes, children = _) => new ESXComponent(id, value, attributes, children);
27-
/** @protected */ static e = (id, name, attributes, children = _) => new ESXElement(id, name, attributes, children);
28-
/** @protected */ static f = (id, children) => new ESXFragment(id, children);
29-
30-
// subclasses super constructor
31-
/** @protected */ constructor(type) {
20+
/** @private */ static _ = _;
21+
/** @private */ static a = (dynamic, name, value) => ({type: ATTRIBUTE, dynamic, name, value});
22+
/** @private */ static i = value => ({type: INTERPOLATION, value});
23+
/** @private */ static s = value => ({type: STATIC, value});
24+
/** @private */ static c = (id, value, attributes, children = _) => new ESXToken(COMPONENT, id, children, attributes, value);
25+
/** @private */ static e = (id, name, attributes, children = _) => new ESXToken(ELEMENT, id, children, attributes, name);
26+
/** @private */ static f = (id, children) => new ESXToken(FRAGMENT, id, children, null, null);
27+
28+
/** @private */
29+
constructor(type, id, children, attributes, value) {
3230
this.type = type;
33-
}
34-
}
35-
36-
class ESXNode extends ESXToken {
37-
constructor(type, id, attributes, children) {
38-
super(type).id = id;
39-
this.attributes = attributes;
31+
this.id = id;
4032
this.children = children;
33+
this.attributes = attributes;
34+
this.value = value;
4135
}
36+
37+
/** @type {object?} an accessor to forward properties */
4238
get properties() {
4339
const {attributes} = this;
4440
return attributes === _ ? null : attributes.reduce(properties, {});
4541
}
4642
}
47-
48-
class ESXFragment extends ESXNode {
49-
constructor(id, children) {
50-
super(FRAGMENT, id, _, children);
51-
}
52-
}
53-
54-
class ESXElement extends ESXNode {
55-
constructor(id, name, attributes, children) {
56-
super(ELEMENT, id, attributes, children).name = name;
57-
}
58-
}
59-
60-
class ESXComponent extends ESXNode {
61-
constructor(id, value, attributes, children) {
62-
super(COMPONENT, id, attributes, children).value = value;
63-
}
64-
}
65-
66-
return ESXToken;
67-
68-
function properties(props, attr) {
69-
if (attr.type === INTERPOLATION)
70-
assign(props, attr.value);
71-
else
72-
props[attr.name] = attr.value;
73-
return props;
74-
}
75-
})();
43+
))(
44+
(props, item) => (
45+
item.type === 5 ?
46+
Object.assign(props, item.value) :
47+
((props[item.name] = item.value), props)
48+
),
49+
[], 1, 2, 3, 4, 5, 6
50+
);

esm/index.js

Lines changed: 32 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
1-
export default (() => {
2-
const ATTRIBUTE = 1;
3-
const COMPONENT = 2;
4-
const ELEMENT = 3;
5-
const FRAGMENT = 4;
6-
const INTERPOLATION = 5;
7-
const STATIC = 6;
8-
9-
const {assign} = Object;
10-
const _ = [];
11-
1+
export default ((
2+
properties, _,
3+
ATTRIBUTE,
4+
COMPONENT,
5+
ELEMENT,
6+
FRAGMENT,
7+
INTERPOLATION,
8+
STATIC
9+
) => (
1210
class ESXToken {
1311
static ATTRIBUTE = ATTRIBUTE;
1412
static COMPONENT = COMPONENT;
@@ -18,57 +16,34 @@ export default (() => {
1816
static STATIC = STATIC;
1917

2018
// transformer utilities
21-
/** @protected */ static _ = _;
22-
/** @protected */ static a = (dynamic, name, value) => ({type: ATTRIBUTE, dynamic, name, value});
23-
/** @protected */ static i = value => ({type: INTERPOLATION, value});
24-
/** @protected */ static s = value => ({type: STATIC, value});
25-
/** @protected */ static c = (id, value, attributes, children = _) => new ESXComponent(id, value, attributes, children);
26-
/** @protected */ static e = (id, name, attributes, children = _) => new ESXElement(id, name, attributes, children);
27-
/** @protected */ static f = (id, children) => new ESXFragment(id, children);
28-
29-
// subclasses super constructor
30-
/** @protected */ constructor(type) {
19+
/** @private */ static _ = _;
20+
/** @private */ static a = (dynamic, name, value) => ({type: ATTRIBUTE, dynamic, name, value});
21+
/** @private */ static i = value => ({type: INTERPOLATION, value});
22+
/** @private */ static s = value => ({type: STATIC, value});
23+
/** @private */ static c = (id, value, attributes, children = _) => new ESXToken(COMPONENT, id, children, attributes, value);
24+
/** @private */ static e = (id, name, attributes, children = _) => new ESXToken(ELEMENT, id, children, attributes, name);
25+
/** @private */ static f = (id, children) => new ESXToken(FRAGMENT, id, children, null, null);
26+
27+
/** @private */
28+
constructor(type, id, children, attributes, value) {
3129
this.type = type;
32-
}
33-
}
34-
35-
class ESXNode extends ESXToken {
36-
constructor(type, id, attributes, children) {
37-
super(type).id = id;
38-
this.attributes = attributes;
30+
this.id = id;
3931
this.children = children;
32+
this.attributes = attributes;
33+
this.value = value;
4034
}
35+
36+
/** @type {object?} an accessor to forward properties */
4137
get properties() {
4238
const {attributes} = this;
4339
return attributes === _ ? null : attributes.reduce(properties, {});
4440
}
4541
}
46-
47-
class ESXFragment extends ESXNode {
48-
constructor(id, children) {
49-
super(FRAGMENT, id, _, children);
50-
}
51-
}
52-
53-
class ESXElement extends ESXNode {
54-
constructor(id, name, attributes, children) {
55-
super(ELEMENT, id, attributes, children).name = name;
56-
}
57-
}
58-
59-
class ESXComponent extends ESXNode {
60-
constructor(id, value, attributes, children) {
61-
super(COMPONENT, id, attributes, children).value = value;
62-
}
63-
}
64-
65-
return ESXToken;
66-
67-
function properties(props, attr) {
68-
if (attr.type === INTERPOLATION)
69-
assign(props, attr.value);
70-
else
71-
props[attr.name] = attr.value;
72-
return props;
73-
}
74-
})();
42+
))(
43+
(props, item) => (
44+
item.type === 5 ?
45+
Object.assign(props, item.value) :
46+
((props[item.name] = item.value), props)
47+
),
48+
[], 1, 2, 3, 4, 5, 6
49+
);

package.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44
"description": "The ESXToken class",
55
"main": "./cjs/index.js",
66
"scripts": {
7-
"build": "npm run cjs",
8-
"cjs": "ascjs --no-default esm cjs"
7+
"build": "npm run cjs && npm test",
8+
"cjs": "ascjs --no-default esm cjs",
9+
"test": "c8 node test/index.js"
910
},
1011
"keywords": [
1112
"esx",
@@ -14,7 +15,8 @@
1415
"author": "Andrea Giammarchi",
1516
"license": "ISC",
1617
"devDependencies": {
17-
"ascjs": "^5.0.1"
18+
"ascjs": "^5.0.1",
19+
"c8": "^7.12.0"
1820
},
1921
"module": "./esm/index.js",
2022
"types": "./types/index.d.ts",

test/index.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import ESXToken from '../esm/index.js';
2+
3+
const assert = (value, expected, message = `expected ${expected} but got ${value}`) => {
4+
console.assert(value === expected, message);
5+
if (value !== expected)
6+
throw new Error(message);
7+
};
8+
9+
const a = ESXToken.a(true, 'a', 1);
10+
assert(a.type, ESXToken.ATTRIBUTE);
11+
assert(a.name, 'a');
12+
assert(a.value, 1);
13+
14+
const o = {b: 345};
15+
const i = ESXToken.i(o);
16+
assert(i.type, ESXToken.INTERPOLATION);
17+
assert(i.value, o);
18+
19+
const s = ESXToken.s(123);
20+
assert(s.type, ESXToken.STATIC);
21+
assert(s.value, 123);
22+
23+
const f = ESXToken.f(1, [2, 3, 4]);
24+
assert(f.type, ESXToken.FRAGMENT);
25+
assert(f.id, 1);
26+
assert(f.children.join(','), '2,3,4');
27+
assert(f.attributes, null);
28+
assert(f.value, null);
29+
30+
const e = ESXToken.e(f, 'div', [a, i], [3, 4]);
31+
assert(e.type, ESXToken.ELEMENT);
32+
assert(e.id, f);
33+
assert(e.children.join(','), '3,4');
34+
assert(e.attributes.length, 2);
35+
assert(e.attributes[0], a);
36+
assert(e.attributes[1], i);
37+
assert(e.value, 'div');
38+
assert(JSON.stringify(e.properties), '{"a":1,"b":345}');
39+
40+
const c = ESXToken.c(e, Object, ESXToken._, [2, 3, 4]);
41+
assert(c.type, ESXToken.COMPONENT);
42+
assert(c.id, e);
43+
assert(c.children.join(','), '2,3,4');
44+
assert(c.attributes.join(','), '');
45+
assert(c.value, Object);
46+
assert(c.properties, null)

0 commit comments

Comments
 (0)