Skip to content

Commit e65bd31

Browse files
committed
Merge branch 'voby' of https://github.com/fabiospampinato/js-framework-benchmark into fabiospampinato-voby
2 parents 82d6118 + cc597aa commit e65bd31

File tree

3 files changed

+229
-0
lines changed

3 files changed

+229
-0
lines changed

frameworks/keyed/voby/index.html

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8"/>
5+
<title>Voby-keyed</title>
6+
<link href="/css/currentStyle.css" rel="stylesheet"/>
7+
</head>
8+
<body>
9+
<div id='main'></div>
10+
<script src='dist/main.js'></script>
11+
</body>
12+
</html>

frameworks/keyed/voby/package.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"name": "js-framework-benchmark-voby",
3+
"version": "0.0.1",
4+
"main": "dist/main.js",
5+
"js-framework-benchmark": {
6+
"frameworkVersionFromPackage": "voby"
7+
},
8+
"scripts": {
9+
"build-prod": "rm -rf dist && mkdir dist && esbuild --bundle --minify --target=es2015 ./src/main.tsx > ./dist/main.js"
10+
},
11+
"author": "Fabio Spampinato",
12+
"license": "MIT",
13+
"homepage": "https://github.com/krausest/js-framework-benchmark",
14+
"repository": {
15+
"type": "git",
16+
"url": "https://github.com/krausest/js-framework-benchmark.git"
17+
},
18+
"dependencies": {
19+
"voby": "0.1.0"
20+
},
21+
"devDependencies": {
22+
"esbuild": "0.14.23"
23+
}
24+
}

frameworks/keyed/voby/src/main.tsx

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
2+
/* IMPORT */
3+
4+
import {Observable, ObservableMaybe} from 'voby';
5+
import {$, createElement, render, template, For, Fragment} from 'voby';
6+
7+
window.React = {createElement, Fragment};
8+
9+
/* TYPES */
10+
11+
type IDatum = Observable<{ id: string, label: Observable<string>, selected: Observable<boolean>, className: Observable<string> }>;
12+
13+
type IData = IDatum[];
14+
15+
/* HELPERS */
16+
17+
const rand = ( max: number ): number => {
18+
return Math.round ( Math.random () * 1000 ) % max;
19+
};
20+
21+
const uuid = (() => {
22+
let counter = 0;
23+
return (): string => {
24+
return String ( counter++ );
25+
};
26+
})();
27+
28+
const buildData = (() => {
29+
const adjectives = ['pretty', 'large', 'big', 'small', 'tall', 'short', 'long', 'handsome', 'plain', 'quaint', 'clean', 'elegant', 'easy', 'angry', 'crazy', 'helpful', 'mushy', 'odd', 'unsightly', 'adorable', 'important', 'inexpensive', 'cheap', 'expensive', 'fancy'];
30+
const colors = ['red', 'yellow', 'blue', 'green', 'pink', 'brown', 'purple', 'brown', 'white', 'black', 'orange'];
31+
const nouns = ['table', 'chair', 'house', 'bbq', 'desk', 'car', 'pony', 'cookie', 'sandwich', 'burger', 'pizza', 'mouse', 'keyboard'];
32+
return ( length: number ): IData => {
33+
const data: IData = new Array ( length );
34+
for ( let i = 0; i < length; i++ ) {
35+
const id = uuid ();
36+
const adjective = adjectives[rand ( adjectives.length )];
37+
const color = colors[rand ( colors.length )];
38+
const noun = nouns[rand ( nouns.length )];
39+
const label = $(`${adjective} ${color} ${noun}`);
40+
const selected = $(false);
41+
const className = $('');
42+
const datum = $( { id, label, selected, className } );
43+
data[i] = datum;
44+
};
45+
return data;
46+
};
47+
})();
48+
49+
/* MODEL */
50+
51+
const Model = (() => {
52+
53+
/* STATE */
54+
55+
let $data = $<IDatum[]>( [] );
56+
let $selected: IDatum | null = null;
57+
58+
/* API */
59+
60+
const run = (): void => {
61+
runWith ( 1000 );
62+
};
63+
64+
const runLots = (): void => {
65+
runWith ( 10000 );
66+
};
67+
68+
const runWith = ( length: number ): void => {
69+
clear ();
70+
$data ( buildData ( length ) );
71+
};
72+
73+
const add = (): void => {
74+
$data ( [...$data (), ...buildData ( 1000 )] );
75+
};
76+
77+
const update = (): void => {
78+
const data = $data ();
79+
for ( let i = 0, l = data.length; i < l; i += 10 ) {
80+
const $datum = data[i];
81+
const datum = $datum ();
82+
datum.label ( datum.label () + ' !!!' );
83+
}
84+
};
85+
86+
const swapRows = (): void => {
87+
const data = $data ();
88+
if ( data.length <= 998 ) return;
89+
const pos1$ = data[1];
90+
const pos998$ = data[998];
91+
const data2 = data.slice ();
92+
data2[1] = pos998$;
93+
data2[998] = pos1$;
94+
$data ( data2 );
95+
};
96+
97+
const clear = (): void => {
98+
$data ( [] );
99+
};
100+
101+
const remove = ( id: string ): void => {
102+
const data = $data ();
103+
const index = data.findIndex ( datum => datum.sample ().id === id );
104+
$data ( [...data.slice ( 0, index ), ...data.slice ( index + 1 )] );
105+
};
106+
107+
const select = ( id: string ): void => {
108+
if ( $selected ) {
109+
const datum = $selected ();
110+
datum.selected ( false );
111+
datum.className ( '' );
112+
}
113+
const data = $data ();
114+
const $datum = data.find ( datum => datum.sample ().id === id )!;
115+
const datum = $datum ();
116+
datum.selected ( true );
117+
datum.className ( 'danger' );
118+
$selected = $datum;
119+
};
120+
121+
return { $data, $selected, run, runLots, runWith, add, update, swapRows, clear, remove, select };
122+
123+
})();
124+
125+
/* MAIN */
126+
127+
const Button = ({ id, text, onClick }: { id: string, text: string, onClick: (( event: MouseEvent ) => any) }): JSX.Element => (
128+
<div class="col-sm-6 smallpad">
129+
<button id={id} class="btn btn-primary btn-block" type="button" onClick={onClick}>{text}</button>
130+
</div>
131+
);
132+
133+
const RowDynamic = ({ id, label, className, onSelect, onRemove }: { id: ObservableMaybe<string>, label: ObservableMaybe<string>, className: ObservableMaybe<string>, onSelect: ObservableMaybe<(( event: MouseEvent ) => any)>, onRemove: ObservableMaybe<(( event: MouseEvent ) => any)> }): JSX.Element => (
134+
<tr class={className}>
135+
<td class="col-md-1">{id}</td>
136+
<td class="col-md-4">
137+
<a onClick={onSelect}>{label}</a>
138+
</td>
139+
<td class="col-md-1">
140+
<a onClick={onRemove}>
141+
<span class="glyphicon glyphicon-remove" ariaHidden={true}></span>
142+
</a>
143+
</td>
144+
<td class="col-md-6"></td>
145+
</tr>
146+
);
147+
148+
const RowTemplate = template ( RowDynamic );
149+
150+
const App = (): JSX.Element => {
151+
152+
const {$data, run, runLots, add, update, clear, swapRows, select, remove} = Model;
153+
154+
return (
155+
<div class="container">
156+
<div class="jumbotron">
157+
<div class="row">
158+
<div class="col-md-6">
159+
<h1>Voby</h1>
160+
</div>
161+
<div class="col-md-6">
162+
<div class="row">
163+
<Button id="run" text="Create 1,000 rows" onClick={run} />
164+
<Button id="runlots" text="Create 10,000 rows" onClick={runLots} />
165+
<Button id="add" text="Append 1,000 rows" onClick={add} />
166+
<Button id="update" text="Update every 10th row" onClick={update} />
167+
<Button id="clear" text="Clear" onClick={clear} />
168+
<Button id="swaprows" text="Swap Rows" onClick={swapRows} />
169+
</div>
170+
</div>
171+
</div>
172+
</div>
173+
<table class="table table-hover table-striped test-data">
174+
<tbody>
175+
<For values={$data}>
176+
{( $datum: IDatum ) => {
177+
const {id, label, className} = $datum ();
178+
const onSelect = () => select ( id );
179+
const onRemove = () => remove ( id );
180+
const props = {id, label, className, onSelect, onRemove};
181+
return RowTemplate ( props );
182+
// return RowDynamic ( props );
183+
}}
184+
</For>
185+
</tbody>
186+
</table>
187+
<span class="preloadicon glyphicon glyphicon-remove" ariaHidden={true}></span>
188+
</div>
189+
);
190+
191+
};
192+
193+
render ( <App />, document.getElementById ( 'main' ) );

0 commit comments

Comments
 (0)