Skip to content

Commit fa124e3

Browse files
committed
Merge branch 'localvoid-master'
2 parents 492d00b + d257fa0 commit fa124e3

File tree

3 files changed

+117
-130
lines changed

3 files changed

+117
-130
lines changed

frameworks/keyed/ivi/package.json

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,22 @@
99
"repository": "https://github.com/krausest/js-framework-benchmark",
1010
"keywords": [],
1111
"js-framework-benchmark": {
12-
"frameworkVersionFromPackage": "ivi-core"
12+
"frameworkVersionFromPackage": "ivi"
1313
},
1414
"scripts": {
1515
"build-dev": "rollup -c rollup.config.js",
1616
"build-prod": "rollup -c rollup.config.js"
1717
},
1818
"dependencies": {
19-
"ivi-core": "0.13.0",
20-
"ivi-scheduler": "0.13.0",
21-
"ivi-html": "0.13.0",
22-
"ivi-state": "0.13.0",
23-
"ivi": "0.13.0"
19+
"ivi-scheduler": "0.15.0",
20+
"ivi-html": "0.15.0",
21+
"ivi-state": "0.15.0",
22+
"ivi": "0.15.0"
2423
},
2524
"devDependencies": {
26-
"rollup": "0.59.4",
25+
"rollup": "0.63.5",
2726
"rollup-plugin-node-resolve-main-fields": "3.3.0",
2827
"rollup-plugin-replace": "2.0.0",
2928
"rollup-plugin-terser": "1.0.1"
3029
}
31-
}
30+
}

frameworks/keyed/ivi/src/main.js

Lines changed: 110 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,129 @@
1-
import { Component, statefulComponent, connect, render, map, element, onClick, stopDirtyChecking } from "ivi";
1+
import { statelessComponent, render, map, element, onClick, stopDirtyChecking, setupScheduler, invalidateHandler } from "ivi";
22
import { h1, div, span, table, tbody, tr, td, a, button } from "ivi-html";
3-
import { store } from "./store";
3+
import { createStore } from "ivi-state";
44

5-
const GlyphIcon = element(span("glyphicon glyphicon-remove").a({ "aria-hidden": "true" }));
5+
function random(max) {
6+
return Math.round(Math.random() * 1000) % max;
7+
}
68

7-
const Row = statefulComponent(class extends Component {
8-
constructor(props) {
9-
super(props);
10-
this.click = onClick(() => { store.dispatch({ type: "select", item: this.props.item }); });
11-
this.del = onClick(() => { store.dispatch({ type: "delete", item: this.props.item }); });
12-
}
9+
const A = ["pretty", "large", "big", "small", "tall", "short", "long", "handsome", "plain", "quaint", "clean",
10+
"elegant", "easy", "angry", "crazy", "helpful", "mushy", "odd", "unsightly", "adorable", "important", "inexpensive",
11+
"cheap", "expensive", "fancy"];
12+
const C = ["red", "yellow", "blue", "green", "pink", "brown", "purple", "brown", "white", "black", "orange"];
13+
const N = ["table", "chair", "house", "bbq", "desk", "car", "pony", "cookie", "sandwich", "burger", "pizza", "mouse",
14+
"keyboard"];
1315

14-
render() {
15-
const { item, selected } = this.props;
16-
return stopDirtyChecking(
17-
tr(selected ? "danger" : "").c(
18-
td("col-md-1").c(item.id),
19-
td("col-md-4").c(a().e(this.click).c(item.label)),
20-
td("col-md-1").c(
21-
a().e(this.del).c(GlyphIcon()),
22-
),
23-
td("col-md-6"),
24-
),
25-
);
16+
let nextId = 1;
17+
18+
function buildData(count) {
19+
const data = new Array(count);
20+
for (let i = 0; i < count; i++) {
21+
data[i] = {
22+
id: nextId++,
23+
label: `${A[random(A.length)]} ${C[random(C.length)]} ${N[random(N.length)]}`,
24+
};
2625
}
27-
});
26+
return data;
27+
}
2828

29-
const RowConnector = connect(
30-
(prev, id) => {
31-
const item = store.getState().data.value[id];
32-
const selected = store.getState().selected === item;
33-
return (prev !== null && prev.item === item && prev.selected === selected) ? prev :
34-
{ item, selected };
29+
const STORE = createStore(
30+
{ data: [], selected: null },
31+
function (state, action) {
32+
const data = state.data;
33+
const selected = state.selected;
34+
switch (action.type) {
35+
case "delete":
36+
data.splice(data.findIndex((d) => d.id === action.id), 1);
37+
return { data, selected };
38+
case "run":
39+
return { data: buildData(1000), selected: null };
40+
case "add":
41+
return { data: state.data.concat(buildData(1000)), selected };
42+
case "update":
43+
for (let i = 0; i < data.length; i += 10) {
44+
const r = data[i];
45+
data[i] = { id: r.id, label: r.label + " !!!" };
46+
}
47+
return { data, selected };
48+
case "select":
49+
return { data, selected: data.find((d) => d.id === action.id) };
50+
case "runlots":
51+
return { data: buildData(10000), selected: null };
52+
case "clear":
53+
return { data: [], selected: null };
54+
case "swaprows":
55+
if (data.length > 998) {
56+
const a = data[1];
57+
data[1] = data[998];
58+
data[998] = a;
59+
}
60+
return { data, selected };
61+
}
62+
return state;
3563
},
36-
Row,
64+
update,
3765
);
3866

39-
const RowListConnector = connect(
40-
(prev) => {
41-
const rows = store.getState().data;
42-
return (prev !== null && prev.rows === rows) ? prev :
43-
{ rows, value: rows.value };
44-
},
45-
({ value }) => tbody().c(map(value, (r, i) => RowConnector(i).k(r.id))),
46-
);
67+
const GlyphIcon = element(span("", { "aria-hidden": "true" }));
68+
69+
const Row = statelessComponent(({ id, label, selected }) => (
70+
stopDirtyChecking(
71+
tr(selected ? "danger" : "").c(
72+
td("col-md-1").c(id),
73+
td("col-md-4").c(a().c(label)),
74+
td("col-md-1").c(a().c(GlyphIcon("glyphicon glyphicon-remove delete"))),
75+
td("col-md-6"),
76+
),
77+
)
78+
));
4779

4880
function Button(text, id) {
4981
return div("col-sm-6 smallpad").c(
50-
button("btn btn-primary btn-block")
51-
.e(onClick(() => { store.dispatch({ type: id }); }))
52-
.a({ "type": "button", "id": id })
82+
button("btn btn-primary btn-block", { type: "button", id })
83+
.e(onClick(() => { STORE.dispatch({ type: id }); }))
5384
.c(text),
5485
);
5586
}
5687

57-
render(
58-
div("container").c(
59-
div("jumbotron").c(
60-
div("row").c(
61-
div("col-md-6").c(h1().c("ivi")),
62-
div("col-md-6").c(
63-
div("row").c(
64-
Button("Create 1,000 rows", "run"),
65-
Button("Create 10,000 rows", "runlots"),
66-
Button("Append 1,000 rows", "add"),
67-
Button("Update every 10th row", "update"),
68-
Button("Clear", "clear"),
69-
Button("Swap Rows", "swaprows"),
70-
),
88+
const Jumbotron = statelessComponent(() => (
89+
div("jumbotron").c(
90+
div("row").c(
91+
div("col-md-6").c(h1().c("ivi")),
92+
div("col-md-6").c(
93+
div("row").c(
94+
Button("Create 1,000 rows", "run"),
95+
Button("Create 10,000 rows", "runlots"),
96+
Button("Append 1,000 rows", "add"),
97+
Button("Update every 10th row", "update"),
98+
Button("Clear", "clear"),
99+
Button("Swap Rows", "swaprows"),
71100
),
72101
),
73102
),
74-
table("table table-hover table-striped test-data").c(RowListConnector()),
75-
GlyphIcon("preloadicon glyphicon glyphicon-remove"),
76-
),
77-
document.getElementById("main"),
78-
);
103+
)
104+
));
105+
106+
setupScheduler(invalidateHandler);
107+
const CONTAINER = document.getElementById("main");
108+
function update() {
109+
const { data, selected } = STORE.state;
110+
render(
111+
div("container").c(
112+
Jumbotron(),
113+
table("table table-hover table-striped test-data").c(
114+
tbody()
115+
.e(onClick((ev) => {
116+
const target = ev.target;
117+
STORE.dispatch({
118+
type: target.matches(".delete") ? "delete" : "select",
119+
id: +target.closest("tr").firstChild.textContent,
120+
});
121+
}))
122+
.c(map(data, (item) => Row(item === selected ? { id: item.id, label: item.label, selected: item === selected } : item).k(item.id))),
123+
),
124+
GlyphIcon("preloadicon glyphicon glyphicon-remove"),
125+
),
126+
CONTAINER,
127+
);
128+
}
129+
update();

frameworks/keyed/ivi/src/store.js

Lines changed: 0 additions & 63 deletions
This file was deleted.

0 commit comments

Comments
 (0)