Comparing version 1.3.0 to 1.4.0
@@ -25,8 +25,8 @@ { | ||
"dependencies": { | ||
"evolui": "^1.1.1", | ||
"evolui": "^1.3.0", | ||
"hyperx": "^2.3.2", | ||
"immutable-deep-update": "^1.0.1", | ||
"rxjs": "^5.4.3", | ||
"socket.io-client": "^2.0.4", | ||
"virtual-dom": "^2.1.1" | ||
"socket.io-client": "^2.0.4" | ||
} | ||
} |
@@ -7,2 +7,5 @@ const path = require('path') | ||
module.exports = { | ||
style: { | ||
cssModules: false | ||
}, | ||
pages: ['index'], | ||
@@ -9,0 +12,0 @@ additionalWebpackConfig: { |
@@ -12,2 +12,4 @@ import { Observable, Subject } from 'rxjs' | ||
const rand = (start, end) => start + Math.random() * (end - start) | ||
const mouse$ = Observable.merge( | ||
@@ -23,19 +25,6 @@ Observable.fromEvent(window, 'mousemove').map(addPosition), | ||
const createHandler = names => | ||
names.reduce( | ||
(acc, name) => ({ | ||
...acc, | ||
[name]: (() => { | ||
const sub = new Subject() | ||
const f = x => sub.next(x) | ||
f.$ = sub | ||
return f | ||
})() | ||
}), | ||
{} | ||
) | ||
const createDragHandler = () => { | ||
const { start } = createHandler(['start']) | ||
const start$ = start.$.map(addPosition) | ||
const start = new Subject() | ||
const onDragStart = e => start.next(e) | ||
const start$ = start.map(addPosition) | ||
@@ -62,3 +51,3 @@ const drag$ = start$ | ||
return { | ||
start, | ||
onDragStart, | ||
drag$, | ||
@@ -71,48 +60,39 @@ dragStart$: start.$, | ||
const Circle = ({ | ||
onDragStart, | ||
position$, | ||
isDragging$, | ||
color = 'purple', | ||
radius = 25, | ||
stiffness = 120, | ||
damping = 20 | ||
} = {}) => { | ||
return html` | ||
<div | ||
ontouchstart="${onDragStart}" | ||
onmousedown="${onDragStart}" | ||
style=" | ||
position: absolute; | ||
left: 0; | ||
right: 0; | ||
width: ${radius * 2}px; | ||
height: ${radius * 2}px; | ||
background: ${color}; | ||
border-radius: 100%; | ||
transform: translate( | ||
${position$.map(p => p.x).switchMap(ease(stiffness, damping))}px, | ||
${position$.map(p => p.y).switchMap(ease(stiffness, damping))}px | ||
); | ||
cursor: ${isDragging$.map( | ||
isDraging => (isDraging ? '-webkit-grabbing' : '-webkit-grab') | ||
)}; | ||
user-select: none; | ||
"> | ||
</div> | ||
` | ||
} | ||
const Circle = props$ => | ||
props$.map( | ||
({ | ||
onDragStart, | ||
position$, | ||
isDragging$, | ||
color = 'purple', | ||
radius = 25, | ||
stiffness = 120, | ||
damping = 20 | ||
}) => | ||
html` | ||
<div | ||
ontouchstart="${onDragStart}" | ||
onmousedown="${onDragStart}" | ||
style=" | ||
position: absolute; | ||
left: 0; | ||
top: 0; | ||
width: ${radius * 2}px; | ||
height: ${radius * 2}px; | ||
background: ${color}; | ||
border-radius: 100%; | ||
transform: translate( | ||
${position$.map(p => p.x).switchMap(ease(stiffness, damping))}px, | ||
${position$.map(p => p.y).switchMap(ease(stiffness, damping))}px | ||
); | ||
cursor: ${isDragging$.map( | ||
isDraging => (isDraging ? '-webkit-grabbing' : '-webkit-grab') | ||
)}; | ||
user-select: none; | ||
"> | ||
</div> | ||
` | ||
) | ||
const rand = (start, end) => start + Math.random() * (end - start) | ||
const GrabbableCircle = ({ | ||
exploadEvery, | ||
onDragStart, | ||
drag$, | ||
isDragging$, | ||
radius = 25, | ||
r, | ||
g, | ||
b | ||
}) => { | ||
const GrabbableCircle = props$ => { | ||
const randomPosition = () => ({ | ||
@@ -127,78 +107,102 @@ x: rand(0.15, 0.85) * window.innerWidth, | ||
const position$ = drag$ | ||
.map(drag => ({ | ||
x: drag.x + drag.left, | ||
y: drag.y + drag.top | ||
})) | ||
.merge( | ||
isDragging$.switchMap( | ||
bool => | ||
bool | ||
? Observable.empty() | ||
: Observable.interval(900) | ||
.map(x => x) | ||
.map(x => (x % exploadEvery ? randomPosition() : center())) | ||
.startWith(randomPosition()) | ||
) | ||
) | ||
.startWith(center()) | ||
return props$.switchMap( | ||
({ | ||
exploadEvery, | ||
onDragStart, | ||
drag$, | ||
isDragging$, | ||
radius = 25, | ||
r, | ||
g, | ||
b | ||
}) => { | ||
const position$ = drag$ | ||
.map(drag => ({ | ||
x: drag.x + drag.left, | ||
y: drag.y + drag.top | ||
})) | ||
.merge( | ||
isDragging$.switchMap( | ||
bool => | ||
bool | ||
? Observable.empty() | ||
: Observable.interval(900) | ||
.map(x => x) | ||
.map(x => (x % exploadEvery ? randomPosition() : center())) | ||
.startWith(randomPosition()) | ||
) | ||
) | ||
.startWith(center()) | ||
return html` | ||
<div> | ||
${Array(7) | ||
.fill(0) | ||
.map((_, i, xs) => | ||
Circle({ | ||
onDragStart, | ||
position$: position$.map(({ x, y }) => ({ | ||
x: x - (radius + i), | ||
y: y - (radius + i) | ||
})), | ||
isDragging$, | ||
stiffness: 120 + 15 * i, | ||
damping: 25 - i * 2, | ||
radius: radius + i, | ||
color: `rgba(${r}, ${g}, ${b}, ${i / xs.length})` | ||
}) | ||
)} | ||
</div> | ||
` | ||
return html` | ||
<div> | ||
${Array(7) | ||
.fill(0) | ||
.map( | ||
(_, i, xs) => | ||
html` | ||
<${Circle} | ||
${{ | ||
isDragging$, | ||
position$: position$.map(({ x, y }) => ({ | ||
x: x - (radius + i), | ||
y: y - (radius + i) | ||
})), | ||
onDragStart: onDragStart, | ||
stiffness: 120 + 15 * i, | ||
damping: 25 - i * 2, | ||
radius: radius + i, | ||
color: `rgba(${r}, ${g}, ${b}, ${i / xs.length})` | ||
}} | ||
/> | ||
` | ||
)} | ||
</div> | ||
` | ||
} | ||
) | ||
} | ||
export default () => { | ||
const { start, drag$, isDragging$ } = createDragHandler() | ||
const { onDragStart, drag$, isDragging$ } = createDragHandler() | ||
return html` | ||
<div mount="${() => console.log('complex create')}"> | ||
${GrabbableCircle({ | ||
radius: 50, | ||
r: 57, | ||
g: 77, | ||
b: 255, | ||
onDragStart: start, | ||
drag$, | ||
isDragging$, | ||
exploadEvery: 2 | ||
})} | ||
${GrabbableCircle({ | ||
radius: 30, | ||
r: 249, | ||
g: 0, | ||
b: 114, | ||
onDragStart: start, | ||
drag$, | ||
isDragging$, | ||
exploadEvery: 2 | ||
})} | ||
${GrabbableCircle({ | ||
radius: 15, | ||
r: 5, | ||
g: 241, | ||
b: 163, | ||
onDragStart: start, | ||
drag$, | ||
isDragging$, | ||
exploadEvery: 4 | ||
})} | ||
<${GrabbableCircle} | ||
${{ | ||
radius: 50, | ||
r: 57, | ||
g: 77, | ||
b: 255, | ||
onDragStart, | ||
drag$, | ||
isDragging$, | ||
exploadEvery: 2 | ||
}} | ||
/> | ||
<${GrabbableCircle} | ||
${{ | ||
radius: 30, | ||
r: 249, | ||
g: 0, | ||
b: 114, | ||
onDragStart, | ||
drag$, | ||
isDragging$, | ||
exploadEvery: 2 | ||
}} | ||
/> | ||
<${GrabbableCircle} | ||
${{ | ||
radius: 15, | ||
r: 5, | ||
g: 241, | ||
b: 163, | ||
onDragStart, | ||
drag$, | ||
isDragging$, | ||
exploadEvery: 4 | ||
}} | ||
/> | ||
</div> | ||
` | ||
} |
@@ -1,32 +0,12 @@ | ||
import { Observable, Subject } from 'rxjs' | ||
import html, { ease } from 'evolui' | ||
import { createFetcher, createState, all } from '../../../utils' | ||
import { Observable } from 'rxjs' | ||
import html, { ease, createState, all } from 'evolui' | ||
import { createFetcher } from '../../../utils' | ||
import Select from './../../Select' | ||
import classNames from './index.css' | ||
import './index.css' | ||
import { getLikes } from './Api' | ||
import ModelCard from './ModelCard' | ||
const raf = new Observable(observer => { | ||
let isSubscribed = true | ||
const loop = () => { | ||
if (isSubscribed) { | ||
observer.next() | ||
window.requestAnimationFrame(loop) | ||
} | ||
} | ||
window.requestAnimationFrame(loop) | ||
return { | ||
unsubscribe: () => { | ||
isSubscribed = false | ||
} | ||
} | ||
}) | ||
const windowDimension$ = Observable.fromEvent(window, 'resize') | ||
.map(() => ({ width: window.innerWidth, height: window.innerHeight })) | ||
.sample(raf) | ||
.startWith({ width: window.innerWidth, height: window.innerHeight }) | ||
@@ -41,104 +21,101 @@ .shareReplay(1) | ||
const likesFetcher = createFetcher(getLikes) | ||
const Grid = props$ => | ||
props$.map(({ models }) => { | ||
const state = createState({ sort: 'none' }) | ||
const Grid = ({ userId$ }) => { | ||
const sort = createState('none') | ||
const sortOptions = [ | ||
{ title: 'none', value: 'none' }, | ||
{ title: 'viewCount', value: 'viewCount' }, | ||
{ title: 'createdAt', value: 'createdAt' }, | ||
{ title: 'shuffle', value: 'shuffle' } | ||
] | ||
const sortOptions = [ | ||
{ title: 'none', value: 'none' }, | ||
{ title: 'viewCount', value: 'viewCount' }, | ||
{ title: 'createdAt', value: 'createdAt' }, | ||
{ title: 'shuffle', value: 'shuffle' } | ||
] | ||
const models$ = userId$.switchMap(userId => | ||
Observable.fromPromise(likesFetcher(userId)) | ||
) | ||
const modelsAndDimensions$ = all([state.sort, colCount$]).map( | ||
([sort, colCount]) => { | ||
const sortedModels = models | ||
.slice() | ||
.sort( | ||
(a, b) => | ||
sort === 'none' | ||
? 0 | ||
: sort === 'viewCount' | ||
? b.viewCount - a.viewCount | ||
: sort === 'createdAt' | ||
? new Date(b.createdAt).getTime() - | ||
new Date(a.createdAt).getTime() | ||
: sort === 'shuffle' ? (Math.random() > 0.5 ? 1 : -1) : 0 | ||
) | ||
const sortedModels$ = sort.stream.combineLatest(models$, (sort, models) => | ||
models | ||
.slice() | ||
.sort( | ||
(a, b) => | ||
sort === 'none' | ||
? 0 | ||
: sort === 'viewCount' | ||
? b.viewCount - a.viewCount | ||
: sort === 'createdAt' | ||
? new Date(b.createdAt).getTime() - | ||
new Date(a.createdAt).getTime() | ||
: sort === 'shuffle' ? (Math.random() > 0.5 ? 1 : -1) : 0 | ||
) | ||
) | ||
// [Model] -> [[{ width, height, x, y }, Model]] | ||
return sortedModels.reduce((grid, model, index) => { | ||
const cardAbove = grid[index - colCount] | ||
return html` | ||
<div class="${classNames.grid}"> | ||
${Select({ | ||
value$: sort.stream, | ||
onChange: sort.set, | ||
options: sortOptions | ||
})} | ||
const height = Math.max(300, Math.min(800, model.name.length * 30)) | ||
<button onclick="${() => sort.set('shuffle')}"> | ||
Shuffle | ||
</button> | ||
const width$ = windowDimension$.map( | ||
({ width }) => | ||
width / colCount - (gutterSize * 2 + gutterSize * (colCount - 1)) | ||
) | ||
<div class="${classNames.container}"> | ||
${all([sortedModels$, colCount$]) | ||
.map(([models, colCount]) => | ||
// [Model] -> [[{ width, height, x, y }, Model]] | ||
models.reduce((grid, model, index) => { | ||
const cardAbove = grid[index - colCount] | ||
const x$ = width$.map(width => { | ||
const col = index % colCount | ||
return col * (width + gutterSize) | ||
}) | ||
const height = Math.max( | ||
300, | ||
Math.min(800, model.name.length * 30) | ||
) | ||
const y = cardAbove | ||
? cardAbove[0].y + cardAbove[0].height + gutterSize | ||
: 0 | ||
const width$ = windowDimension$.map( | ||
({ width }) => | ||
width / colCount - | ||
(gutterSize * 2 + gutterSize * (colCount - 1)) | ||
) | ||
const dimension = { | ||
height, | ||
y, | ||
width$, | ||
x$, | ||
height$: Observable.of(height), | ||
y$: Observable.of(y) | ||
} | ||
const x$ = width$.map(width => { | ||
const col = index % colCount | ||
return col * (width + gutterSize) | ||
}) | ||
return grid.concat([[dimension, model]]) | ||
}, []) | ||
} | ||
) | ||
const y = cardAbove | ||
? cardAbove[0].y + cardAbove[0].height + gutterSize | ||
: 0 | ||
return html` | ||
<div class="grid"> | ||
<${Select} | ||
value=${state.sort} | ||
onChange=${state.sort.set} | ||
options=${sortOptions} | ||
/> | ||
const dimension = { | ||
height, | ||
y, | ||
width$, | ||
x$, | ||
height$: Observable.of(height), | ||
y$: Observable.of(y) | ||
} | ||
<button onclick="${() => state.sort.set('shuffle')}"> | ||
Shuffle | ||
</button> | ||
return grid.concat([[dimension, model]]) | ||
}, []) | ||
<div class="container"> | ||
${modelsAndDimensions$.map(modelsAndDimensions => | ||
modelsAndDimensions.map( | ||
([dimension, model]) => | ||
html` | ||
<${ModelCard} | ||
model=${model} | ||
x=${dimension.x$.switchMap(ease(150, 18, model.uid + 'x'))} | ||
y=${dimension.y$.switchMap(ease(120, 25, model.uid + 'y'))} | ||
height=${dimension.height$.switchMap( | ||
ease(170, 20, model.uid + 'height') | ||
)} | ||
width=${dimension.width$.switchMap( | ||
ease(170, 20, model.uid + 'width') | ||
)} | ||
/> | ||
` | ||
) | ||
.map(models => | ||
models.map(([dimension, model]) => | ||
ModelCard({ | ||
model, | ||
x: dimension.x$.switchMap(ease(150, 18, model.uid + 'x')), | ||
y: dimension.y$.switchMap(ease(120, 25, model.uid + 'y')), | ||
height: dimension.height$.switchMap( | ||
ease(170, 20, model.uid + 'height') | ||
), | ||
width: dimension.width$.switchMap( | ||
ease(170, 20, model.uid + 'width') | ||
) | ||
}) | ||
) | ||
)} | ||
)} | ||
</div> | ||
</div> | ||
` | ||
} | ||
}) | ||
const likesFetcher = createFetcher(getLikes) | ||
const SketchfabGrid = () => { | ||
@@ -149,12 +126,18 @@ const users = [ | ||
] | ||
const userId = createState(users[0].id) | ||
const state = createState({ userId: users[0].id }) | ||
const models$ = state.userId | ||
.switchMap(userId => Observable.fromPromise(likesFetcher(userId))) | ||
.startWith([]) | ||
return html` | ||
<div> | ||
${Select({ | ||
value$: userId.stream, | ||
onChange: userId.set, | ||
options: users.map(({ name, id }) => ({ title: name, value: id })) | ||
})} | ||
${Grid({ userId$: userId.stream })} | ||
<${Select} | ||
value=${state.userId} | ||
onChange=${state.userId.set} | ||
options=${users.map(({ name, id }) => ({ title: name, value: id }))} | ||
/> | ||
<${Grid} models=${models$} /> | ||
</div> | ||
@@ -161,0 +144,0 @@ ` |
import html from 'evolui' | ||
import classNames from './index.css' | ||
import './index.css' | ||
@@ -13,20 +13,27 @@ const getImageUrl = ({ thumbnails: { images } }) => | ||
const ModelCard = ({ model, x, y, width, height }) => html` | ||
<a | ||
key="${model.uid}" | ||
target="_blank" | ||
href="${model.viewerUrl}" | ||
class="${classNames.card}" | ||
style=" | ||
const ModelCard = props$ => { | ||
const style$ = props$.map( | ||
({ x, y, width, height }) => ` | ||
transform: translate(${x}px, ${y}px); | ||
height: ${height}px; | ||
width: ${width}px; | ||
"> | ||
<div | ||
class="${classNames.cardImage}" | ||
style="background-image: url(${getImageUrl(model)});"></div> | ||
<p class="${classNames.name}">${model.name}</p> | ||
</a> | ||
` | ||
` | ||
) | ||
return html` | ||
<a | ||
target="_blank" | ||
href="${props$.map(p => p.model.viewerUrl)}" | ||
class="card" | ||
style="${style$}"> | ||
<div | ||
class="cardImage" | ||
style="background-image: url(${props$.map(p => | ||
getImageUrl(p.model) | ||
)});"></div> | ||
<p class="name">${props$.map(p => p.model.name)}</p> | ||
</a> | ||
` | ||
} | ||
export default ModelCard |
@@ -1,2 +0,2 @@ | ||
import { Observable, Subject } from 'rxjs' | ||
import { Observable } from 'rxjs' | ||
import html, { ease } from 'evolui' | ||
@@ -17,39 +17,32 @@ | ||
const Circle = ({ | ||
color = 'purple', | ||
radius = 25, | ||
stiffness = 120, | ||
damping = 20 | ||
} = {}) => { | ||
return html` | ||
<div | ||
style=" | ||
position: absolute; | ||
left: 0; | ||
right: 0; | ||
width: ${radius * 2}px; | ||
height: ${radius * 2}px; | ||
background: ${color}; | ||
border-radius: 100%; | ||
z-index: -1; | ||
transform: translate( | ||
${position$ | ||
.map(p => p.x - radius) | ||
.switchMap(ease(stiffness, damping))}px, | ||
${position$ | ||
.map(p => p.y - radius) | ||
.switchMap(ease(stiffness, damping))}px | ||
); | ||
"> | ||
</div> | ||
` | ||
} | ||
const Circle = props$ => | ||
props$.map( | ||
({ color = 'purple', radius = 25, stiffness = 120, damping = 20 } = {}) => { | ||
return html` | ||
<div | ||
style=" | ||
position: absolute; | ||
left: 0; | ||
top: 0; | ||
width: ${radius * 2}px; | ||
height: ${radius * 2}px; | ||
background: ${color}; | ||
border-radius: 100%; | ||
z-index: -1; | ||
transform: translate( | ||
${position$ | ||
.map(p => p.x - radius) | ||
.switchMap(ease(stiffness, damping))}px, | ||
${position$ | ||
.map(p => p.y - radius) | ||
.switchMap(ease(stiffness, damping))}px | ||
); | ||
"> | ||
</div> | ||
` | ||
} | ||
) | ||
export default () => html` | ||
<div> | ||
${Circle({ | ||
radius: 35, | ||
color: 'rgb(5, 241, 163)' | ||
})} | ||
</div> | ||
<${Circle} radius=${35} color="rgb(5, 241, 163)" /> | ||
` |
@@ -1,2 +0,2 @@ | ||
import html, { ease } from 'evolui' | ||
import html, { ease, all, createState } from 'evolui' | ||
import { Observable } from 'rxjs' | ||
@@ -11,3 +11,3 @@ | ||
const position$ = Observable.fromEvent(window, 'mousemove') | ||
const mouse$ = Observable.fromEvent(window, 'mousemove') | ||
.map(e => ({ | ||
@@ -19,13 +19,29 @@ x: e.clientX, | ||
const log = (x, label = '') => (console.log(label, x), x) | ||
export default () => html` | ||
<svg | ||
height="${window$.map(w => w.height)}" | ||
width="${window$.map(w => w.width)}"> | ||
<circle | ||
cx="${position$.map(p => p.x).map(ease(120, 18))}" | ||
cy="${position$.map(p => p.y).map(ease(120, 18))}" | ||
r="40" | ||
fill="rgba(57, 77, 255)" /> | ||
</svg> | ||
` | ||
const SvgAnimation = () => { | ||
const state = createState({ elPosition: { x: 0, y: 0 } }) | ||
const onMount = el => { | ||
const { left, top } = el.getBoundingClientRect() | ||
state.elPosition.set({ x: left, y: top }) | ||
} | ||
const position$ = all([state.elPosition, mouse$]).map(([el, mouse]) => ({ | ||
x: mouse.x - el.x, | ||
y: mouse.y - el.y | ||
})) | ||
return html` | ||
<svg | ||
mount=${onMount} | ||
height="${window$.map(w => w.height)}" | ||
width="${window$.map(w => w.width)}"> | ||
<circle | ||
cx="${position$.map(p => p.x).map(ease(120, 18))}" | ||
cy="${position$.map(p => p.y).map(ease(120, 18))}" | ||
r="40" | ||
fill="rgba(57, 77, 255)" /> | ||
</svg> | ||
` | ||
} | ||
export default SvgAnimation |
@@ -11,2 +11,3 @@ import io from 'socket.io-client' | ||
}) | ||
const sendMessage = message => socket.emit('message', message) | ||
@@ -13,0 +14,0 @@ |
import html from 'evolui' | ||
import { Observable } from 'rxjs' | ||
const getCharacter = id => | ||
fetch(`https://swapi.co/api/people/${id}`) | ||
.then(res => res.json()) | ||
.then(character => character.name) | ||
const HttpRequest = () => html` | ||
@@ -9,7 +14,3 @@ <div> | ||
<h1> | ||
${Observable.fromPromise( | ||
fetch(`https://swapi.co/api/people/${id}`) | ||
.then(res => res.json()) | ||
.then(character => character.name) | ||
).startWith('Loading...')} | ||
${Observable.fromPromise(getCharacter(id)).startWith('Loading...')} | ||
</h1> | ||
@@ -16,0 +17,0 @@ ` |
@@ -5,6 +5,3 @@ import html from 'evolui' | ||
const mouse = Observable.fromEvent(window, 'mousemove') | ||
.map(e => ({ | ||
x: e.clientX, | ||
y: e.clientY | ||
})) | ||
.map(e => ({ x: e.clientX, y: e.clientY })) | ||
.startWith({ x: 0, y: 0 }) | ||
@@ -11,0 +8,0 @@ |
import html from 'evolui' | ||
const Select = ({ options, onChange, value$ }) => html` | ||
<select onchange="${e => onChange(e.target.value)}"> | ||
${options.map(({ title, value }) => | ||
value$.map( | ||
v => html` | ||
<option | ||
${value === v ? 'selected' : ''} | ||
value="${value}">${title}</option> | ||
` | ||
) | ||
)} | ||
</select> | ||
` | ||
const Select = props$ => | ||
props$.map( | ||
({ options, onChange, value }) => html` | ||
<select onchange="${e => onChange(e.target.value)}"> | ||
${options.map( | ||
option => html` | ||
<option | ||
${option.value === value ? 'selected' : ''} | ||
value="${option.value}">${option.title}</option> | ||
` | ||
)} | ||
</select> | ||
` | ||
) | ||
export default Select |
@@ -5,5 +5,9 @@ import html from 'evolui' | ||
const Ticker = () => html` | ||
<span>${Observable.interval(1000).startWith(0)}</span> | ||
<span> | ||
${Observable.interval(1000) | ||
.map(x => x + 1) | ||
.startWith(0)} | ||
</span> | ||
` | ||
export default Ticker |
@@ -8,10 +8,6 @@ import html from 'evolui' | ||
const store = configureStore() | ||
return html` | ||
<div> | ||
${InputBar({ store })} | ||
${store.state | ||
.pluck('todos') | ||
.distinctUntilChanged() | ||
.switchMap(todos => TodoList({ todos, store }))} | ||
<${InputBar} store=${store} /> | ||
<${TodoList} store=${store} /> | ||
</div> | ||
@@ -18,0 +14,0 @@ ` |
import html from 'evolui' | ||
import { ADD_TODO, UPDATE_TEXT } from './actions' | ||
const InputBar = ({ store }) => { | ||
const onKeyDown = e => { | ||
if (e.which === 13) store.dispatch({ type: ADD_TODO, text: e.target.value }) | ||
} | ||
const InputBar = props$ => | ||
props$.map(({ store }) => { | ||
const onKeyDown = e => { | ||
if (e.which === 13) | ||
store.dispatch({ type: ADD_TODO, text: e.target.value }) | ||
} | ||
const onInput = e => | ||
store.dispatch({ type: UPDATE_TEXT, text: e.target.value }) | ||
const onInput = e => | ||
store.dispatch({ type: UPDATE_TEXT, text: e.target.value }) | ||
return html` | ||
<input | ||
value="${store.state.map(({ text }) => text)}" | ||
oninput=${onInput} | ||
onkeydown=${onKeyDown} /> | ||
return html` | ||
<input | ||
value="${store.state.map(({ text }) => text)}" | ||
oninput=${onInput} | ||
onkeydown=${onKeyDown} /> | ||
` | ||
} | ||
}) | ||
export default InputBar |
import html from 'evolui' | ||
import { | ||
UPDATE_TODO, | ||
TOGGLE_EDIT_TODO, | ||
STOP_EDIT_TODO, | ||
REMOVE_TODO, | ||
TOGGLE_TODO | ||
} from './actions' | ||
const Todo = ({ todo, store }) => { | ||
const onToggleComplete = () => | ||
store.dispatch({ type: TOGGLE_TODO, id: todo.id }) | ||
const Todo = props$ => { | ||
return props$.map( | ||
({ todo, onToggleComplete, onStopEdit, onToggle, onInput, onRemove }) => { | ||
const onKeyDown = e => { | ||
if (e.which === 13) onStopEdit() | ||
} | ||
const onStopEdit = () => store.dispatch({ type: STOP_EDIT_TODO, id: todo.id }) | ||
const onToggle = () => store.dispatch({ type: TOGGLE_EDIT_TODO, id: todo.id }) | ||
const onInput = e => { | ||
store.dispatch({ type: UPDATE_TODO, id: todo.id, text: e.target.value }) | ||
} | ||
const onKeyDown = e => { | ||
if (e.which === 13) onStopEdit() | ||
} | ||
const onRemove = () => store.dispatch({ type: REMOVE_TODO, id: todo.id }) | ||
return html` | ||
<li | ||
key="${todo.id}" | ||
mount="${() => console.log('todo created!', todo.text)}" | ||
update="${() => console.log('todo updated!', todo.text)}" | ||
unmount="${() => console.log('todo removed ;(', todo.text)}"> | ||
${ | ||
todo.isEditing | ||
? html` | ||
<input | ||
autofocus | ||
value="${todo.text}" | ||
oninput=${onInput} | ||
onkeydown=${onKeyDown} | ||
onblur=${onStopEdit} /> | ||
` | ||
: html` | ||
<span | ||
onclick=${onToggleComplete} | ||
style="text-decoration: ${ | ||
todo.isComplete ? 'line-through' : 'none' | ||
};"> | ||
${todo.text} | ||
</span> | ||
` | ||
} | ||
<button onclick=${onRemove}>X</button> | ||
<button onclick=${onToggle}>Edit</button> | ||
</li> | ||
` | ||
return html` | ||
<li | ||
mount="${() => console.log('todo created!', todo.text)}" | ||
update="${() => console.log('todo updated!', todo.text)}" | ||
unmount="${() => console.log('todo removed ;(', todo.text)}"> | ||
${ | ||
todo.isEditing | ||
? html` | ||
<input | ||
autofocus | ||
value="${todo.text}" | ||
onInput="${onInput}" | ||
onKeyDown="${onKeyDown}" | ||
onBlur="${onStopEdit}" /> | ||
` | ||
: html` | ||
<span | ||
onClick="${onToggleComplete}" | ||
style=${{ | ||
textDecoration: todo.isComplete ? 'line-through' : 'none' | ||
}}> | ||
${todo.text} | ||
</span> | ||
` | ||
} | ||
<button onclick=${onRemove}>X</button> | ||
<button onclick=${onToggle}>Edit</button> | ||
</li> | ||
` | ||
} | ||
) | ||
} | ||
export default Todo |
import html from 'evolui' | ||
import Todo from './Todo' | ||
import { | ||
UPDATE_TODO, | ||
TOGGLE_EDIT_TODO, | ||
STOP_EDIT_TODO, | ||
REMOVE_TODO, | ||
TOGGLE_TODO | ||
} from './actions' | ||
const TodoList = ({ todos, store }) => html` | ||
<ul> | ||
${todos.map(todo => Todo({ todo, store }))} | ||
</ul> | ||
` | ||
const TodoList = props$ => | ||
props$.map(({ store }) => { | ||
return html` | ||
<ul> | ||
${store.state | ||
.pluck('todos') | ||
.distinctUntilChanged() | ||
.map(todos => | ||
todos.map( | ||
todo => | ||
html`<${Todo} ${{ | ||
key: todo.text, | ||
todo, | ||
onToggleComplete: () => | ||
store.dispatch({ type: TOGGLE_TODO, id: todo.id }), | ||
onStopEdit: () => | ||
store.dispatch({ type: STOP_EDIT_TODO, id: todo.id }), | ||
onToggle: () => | ||
store.dispatch({ type: TOGGLE_EDIT_TODO, id: todo.id }), | ||
onInput: e => | ||
store.dispatch({ | ||
type: UPDATE_TODO, | ||
id: todo.id, | ||
text: e.target.value | ||
}), | ||
onRemove: () => | ||
store.dispatch({ type: REMOVE_TODO, id: todo.id }) | ||
}} />` | ||
) | ||
)} | ||
</ul> | ||
` | ||
}) | ||
export default TodoList |
@@ -1,3 +0,2 @@ | ||
import html, { render } from 'evolui' | ||
import { createState } from './utils' | ||
import html, { render, createState } from 'evolui' | ||
import Select from './components/Select' | ||
@@ -10,2 +9,3 @@ | ||
import Chat from './components/Chat' | ||
import Spreadsheet from './components/Spreadsheet' | ||
import SimpleAnimation from './components/animations/SimpleAnimation' | ||
@@ -16,6 +16,9 @@ import ComplexeAnimation from './components/animations/ComplexeAnimation' | ||
import './index.css' | ||
const examples = [ | ||
{ title: 'ComplexeAnimation', value: 'ComplexeAnimation' }, | ||
{ title: 'Spreadsheet', value: 'Spreadsheet' }, | ||
{ title: 'TodoList', value: 'TodoList' }, | ||
{ title: 'SimpleAnimation', value: 'SimpleAnimation' }, | ||
{ title: 'ComplexeAnimation', value: 'ComplexeAnimation' }, | ||
{ title: 'SvgAnimation', value: 'SvgAnimation' }, | ||
@@ -30,2 +33,3 @@ { title: 'PinterestLikeGrid', value: 'PinterestLikeGrid' }, | ||
const components = { | ||
Spreadsheet, | ||
TodoList, | ||
@@ -43,12 +47,20 @@ SimpleAnimation, | ||
const App = () => { | ||
const selectedExample = createState('TodoList') | ||
const state = createState({ selectedExample: 'ComplexeAnimation' }) | ||
const component$ = state.selectedExample.map(name => components[name]) | ||
return html` | ||
<div> | ||
${Select({ | ||
value$: selectedExample.stream, | ||
onChange: selectedExample.set, | ||
options: examples | ||
})} | ||
<h3>A few examples of what you can do with evolui 🚀</h3> | ||
${selectedExample.stream.map(name => components[name]())} | ||
<p> | ||
Choose an example 👉 | ||
<${Select} | ||
value=${state.selectedExample} | ||
onChange=${state.selectedExample.set} | ||
options=${examples} | ||
/> | ||
</p> | ||
${component$.map(Component => html`<${Component} />`)} | ||
</div> | ||
@@ -55,0 +67,0 @@ ` |
@@ -18,12 +18,1 @@ import { Observable, Subject } from 'rxjs' | ||
} | ||
export const createState = (initialValue) => { | ||
const stream = new Subject() | ||
return { | ||
set: x => stream.next(x), | ||
stream: stream.startWith(initialValue).shareReplay(1) | ||
} | ||
} | ||
export const all = obs => | ||
obs.length ? Observable.combineLatest(...obs, (...xs) => xs) : Observable.of([]) |
@@ -1,1 +0,1 @@ | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var hyperscriptAttributeToProperty=attributeToProperty,transform={class:"className",for:"htmlFor","http-equiv":"httpEquiv"};function attributeToProperty(r){return function(e,t,n){for(var o in t)o in transform&&(t[transform[o]]=t[o],delete t[o]);return r(e,t,n)}}var VAR=0,TEXT=1,OPEN=2,CLOSE=3,ATTR=4,ATTR_KEY=5,ATTR_KEY_W=6,ATTR_VALUE_W=7,ATTR_VALUE=8,ATTR_VALUE_SQ=9,ATTR_VALUE_DQ=10,ATTR_EQ=11,ATTR_BREAK=12,COMMENT=13,hyperx=function(r,e){e||(e={});var t=e.concat||function(r,e){return String(r)+String(e)};return!1!==e.attrToProp&&(r=hyperscriptAttributeToProperty(r)),function(o){for(var i=TEXT,s="",c=arguments.length,u=[],a=0;a<o.length;a++)if(a<c-1){var l=arguments[a+1],f=E(o[a]),p=i;p===ATTR_VALUE_DQ&&(p=ATTR_VALUE),p===ATTR_VALUE_SQ&&(p=ATTR_VALUE),p===ATTR_VALUE_W&&(p=ATTR_VALUE),p===ATTR&&(p=ATTR_KEY),f.push([VAR,p,l]),u.push.apply(u,f)}else u.push.apply(u,E(o[a]));var b=[null,{},[]],h=[[b,-1]];for(a=0;a<u.length;a++){var y=h[h.length-1][0],_=(f=u[a])[0];if(_===OPEN&&/^\//.test(f[1])){var T=h[h.length-1][1];h.length>1&&(h.pop(),h[h.length-1][0][2][T]=r(y[0],y[1],y[2].length?y[2]:void 0))}else if(_===OPEN){var v=[f[1],{},[]];y[2].push(v),h.push([v,y[2].length-1])}else if(_===ATTR_KEY||_===VAR&&f[1]===ATTR_KEY){for(var d,m="";a<u.length;a++)if(u[a][0]===ATTR_KEY)m=t(m,u[a][1]);else{if(u[a][0]!==VAR||u[a][1]!==ATTR_KEY)break;if("object"!=typeof u[a][2]||m)m=t(m,u[a][2]);else for(d in u[a][2])u[a][2].hasOwnProperty(d)&&!y[1][d]&&(y[1][d]=u[a][2][d])}u[a][0]===ATTR_EQ&&a++;for(var A=a;a<u.length;a++)if(u[a][0]===ATTR_VALUE||u[a][0]===ATTR_KEY)y[1][m]?""===u[a][1]||(y[1][m]=t(y[1][m],u[a][1])):y[1][m]=n(u[a][1]);else{if(u[a][0]!==VAR||u[a][1]!==ATTR_VALUE&&u[a][1]!==ATTR_KEY){!m.length||y[1][m]||a!==A||u[a][0]!==CLOSE&&u[a][0]!==ATTR_BREAK||(y[1][m]=m.toLowerCase()),u[a][0]===CLOSE&&a--;break}y[1][m]?""===u[a][2]||(y[1][m]=t(y[1][m],u[a][2])):y[1][m]=n(u[a][2])}}else if(_===ATTR_KEY)y[1][f[1]]=!0;else if(_===VAR&&f[1]===ATTR_KEY)y[1][f[2]]=!0;else if(_===CLOSE){if(selfClosing(y[0])&&h.length){T=h[h.length-1][1];h.pop(),h[h.length-1][0][2][T]=r(y[0],y[1],y[2].length?y[2]:void 0)}}else if(_===VAR&&f[1]===TEXT)void 0===f[2]||null===f[2]?f[2]="":f[2]||(f[2]=t("",f[2])),Array.isArray(f[2][0])?y[2].push.apply(y[2],f[2]):y[2].push(f[2]);else if(_===TEXT)y[2].push(f[1]);else if(_!==ATTR_EQ&&_!==ATTR_BREAK)throw new Error("unhandled: "+_)}if(b[2].length>1&&/^\s*$/.test(b[2][0])&&b[2].shift(),b[2].length>2||2===b[2].length&&/\S/.test(b[2][1]))throw new Error("multiple root elements must be wrapped in an enclosing tag");return Array.isArray(b[2][0])&&"string"==typeof b[2][0][0]&&Array.isArray(b[2][0][2])&&(b[2][0]=r(b[2][0][0],b[2][0][1],b[2][0][2])),b[2][0];function E(r){var t=[];i===ATTR_VALUE_W&&(i=ATTR);for(var n=0;n<r.length;n++){var o=r.charAt(n);i===TEXT&&"<"===o?(s.length&&t.push([TEXT,s]),s="",i=OPEN):">"!==o||quot(i)||i===COMMENT?i===COMMENT&&/-$/.test(s)&&"-"===o?(e.comments&&t.push([ATTR_VALUE,s.substr(0,s.length-1)],[CLOSE]),s="",i=TEXT):i===OPEN&&/^!--$/.test(s)?(e.comments&&t.push([OPEN,s],[ATTR_KEY,"comment"],[ATTR_EQ]),s=o,i=COMMENT):i===TEXT||i===COMMENT?s+=o:i===OPEN&&"/"===o&&s.length||(i===OPEN&&/\s/.test(o)?(t.push([OPEN,s]),s="",i=ATTR):i===OPEN?s+=o:i===ATTR&&/[^\s"'=/]/.test(o)?(i=ATTR_KEY,s=o):i===ATTR&&/\s/.test(o)?(s.length&&t.push([ATTR_KEY,s]),t.push([ATTR_BREAK])):i===ATTR_KEY&&/\s/.test(o)?(t.push([ATTR_KEY,s]),s="",i=ATTR_KEY_W):i===ATTR_KEY&&"="===o?(t.push([ATTR_KEY,s],[ATTR_EQ]),s="",i=ATTR_VALUE_W):i===ATTR_KEY?s+=o:i!==ATTR_KEY_W&&i!==ATTR||"="!==o?i!==ATTR_KEY_W&&i!==ATTR||/\s/.test(o)?i===ATTR_VALUE_W&&'"'===o?i=ATTR_VALUE_DQ:i===ATTR_VALUE_W&&"'"===o?i=ATTR_VALUE_SQ:i===ATTR_VALUE_DQ&&'"'===o?(t.push([ATTR_VALUE,s],[ATTR_BREAK]),s="",i=ATTR):i===ATTR_VALUE_SQ&&"'"===o?(t.push([ATTR_VALUE,s],[ATTR_BREAK]),s="",i=ATTR):i!==ATTR_VALUE_W||/\s/.test(o)?i===ATTR_VALUE&&/\s/.test(o)?(t.push([ATTR_VALUE,s],[ATTR_BREAK]),s="",i=ATTR):i!==ATTR_VALUE&&i!==ATTR_VALUE_SQ&&i!==ATTR_VALUE_DQ||(s+=o):(i=ATTR_VALUE,n--):(t.push([ATTR_BREAK]),/[\w-]/.test(o)?(s+=o,i=ATTR_KEY):i=ATTR):(t.push([ATTR_EQ]),i=ATTR_VALUE_W)):(i===OPEN?t.push([OPEN,s]):i===ATTR_KEY?t.push([ATTR_KEY,s]):i===ATTR_VALUE&&s.length&&t.push([ATTR_VALUE,s]),t.push([CLOSE]),s="",i=TEXT)}return i===TEXT&&s.length?(t.push([TEXT,s]),s=""):i===ATTR_VALUE&&s.length?(t.push([ATTR_VALUE,s]),s=""):i===ATTR_VALUE_DQ&&s.length?(t.push([ATTR_VALUE,s]),s=""):i===ATTR_VALUE_SQ&&s.length?(t.push([ATTR_VALUE,s]),s=""):i===ATTR_KEY&&(t.push([ATTR_KEY,s]),s=""),t}};function n(r){return"function"==typeof r?r:"string"==typeof r?r:r&&"object"==typeof r?r:t("",r)}};function quot(r){return r===ATTR_VALUE_SQ||r===ATTR_VALUE_DQ}var closeRE=RegExp("^("+["area","base","basefont","bgsound","br","col","command","embed","frame","hr","img","input","isindex","keygen","link","meta","param","source","track","wbr","!--","animate","animateTransform","circle","cursor","desc","ellipse","feBlend","feColorMatrix","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feDistantLight","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussianBlur","feImage","feMergeNode","feMorphology","feOffset","fePointLight","feSpecularLighting","feSpotLight","feTile","feTurbulence","font-face-format","font-face-name","font-face-uri","glyph","glyphRef","hkern","image","line","missing-glyph","mpath","path","polygon","polyline","rect","set","stop","tref","use","view","vkern"].join("|")+")(?:[.#][a-zA-Z0-9-_:-]+)*$");function selfClosing(r){return closeRE.test(r)}var _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(r){return typeof r}:function(r){return r&&"function"==typeof Symbol&&r.constructor===Symbol&&r!==Symbol.prototype?"symbol":typeof r},classCallCheck=function(r,e){if(!(r instanceof e))throw new TypeError("Cannot call a class as a function")},_extends=Object.assign||function(r){for(var e=1;e<arguments.length;e++){var t=arguments[e];for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(r[n]=t[n])}return r},slicedToArray=function(){return function(r,e){if(Array.isArray(r))return r;if(Symbol.iterator in Object(r))return function(r,e){var t=[],n=!0,o=!1,i=void 0;try{for(var s,c=r[Symbol.iterator]();!(n=(s=c.next()).done)&&(t.push(s.value),!e||t.length!==e);n=!0);}catch(r){o=!0,i=r}finally{try{!n&&c.return&&c.return()}finally{if(o)throw i}}return t}(r,e);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),toArray=function(r){return Array.isArray(r)?r:Array.from(r)},toConsumableArray=function(r){if(Array.isArray(r)){for(var e=0,t=Array(r.length);e<r.length;e++)t[e]=r[e];return t}return Array.from(r)},Nothing="Nothing",compose=function(){for(var r=arguments.length,e=Array(r),t=0;t<r;t++)e[t]=arguments[t];return function(r){return e.reduceRight(function(r,e){return e(r)},r)}},pipe=function(){for(var r=arguments.length,e=Array(r),t=0;t<r;t++)e[t]=arguments[t];return e.reduce(function(r,e){return function(t){return e(r(t))}},function(r){return r})},curry=function r(e){return function(){for(var t=arguments.length,n=Array(t),o=0;o<t;o++)n[o]=arguments[o];return n.length>=e.length?e.apply(void 0,n):function(){for(var t=arguments.length,o=Array(t),i=0;i<t;i++)o[i]=arguments[i];return r(e).apply(void 0,n.concat(o))}}},init=function(r){return r.slice(0,r.length-1)},last=function(r){return r[r.length-1]},flatMap=curry(function(r,e){return e.reduce(function(e,t){return e.concat(r(t))},[])}),isEmpty=function(r){return 0!==r&&(!r||"string"==typeof r&&!r.trim())},isPromise=function(r){return r&&"function"==typeof r.then},isObservable=function(r){return r&&"function"==typeof r.subscribe},createOperators=function(r){var e=function(){for(var e=arguments.length,t=Array(e),n=0;n<e;n++)t[n]=arguments[n];return new r(function(r){var e=!0,n=!1,o=void 0;try{for(var i,s=t[Symbol.iterator]();!(e=(i=s.next()).done);e=!0){var c=i.value;r.next(c)}}catch(r){n=!0,o=r}finally{try{!e&&s.return&&s.return()}finally{if(n)throw o}}return r.complete(),{unsubscribe:function(){}}})},t=curry(function(e,t){return new r(function(r){return r.next(e),t.subscribe(r)})}),n=function(){for(var e=arguments.length,t=Array(e),n=0;n<e;n++)t[n]=arguments[n];var o=init(t),i=last(t);return new r(function(r){var e=o.map(function(){return Nothing}),t=o.map(function(){return!0}),n=o.map(function(n,o){return n.subscribe({error:function(e){console.error(e),t[o]=!1,t.every(function(r){return!1===r})&&r.complete()},complete:function(){t[o]=!1,t.every(function(r){return!1===r})&&r.complete()},next:function(t){if(e[o]=t,e.every(function(r){return r!==Nothing})){var n=void 0;try{n=i.apply(void 0,toConsumableArray(e))}catch(r){console.error(r)}r.next(n)}}})});return{unsubscribe:function(){n.forEach(function(r){return r.unsubscribe()})}}})},o=curry(function(e,t){return new r(function(r){return t.subscribe({error:function(e){return r.error(e)},next:function(t){return r.next(e(t))},complete:function(){return r.complete()}})})}),i=curry(function(e,t){var n=void 0;return new r(function(r){return t.subscribe({next:function(t){n&&n.unsubscribe(),n=e(t).subscribe({error:function(e){return r.error(e)},next:function(e){return r.next(e)},complete:function(){}})},error:function(e){return r.error(e)},complete:function(){}})})}),s=curry(function(e,t){var n=Symbol("None");return new r(function(r){var o=n,i=t.subscribe({next:function(r){o=r},complete:function(){},error:function(e){return r.error(e)}}),s=e.subscribe({next:function(){o!==n&&(r.next(o),o=n)},complete:function(){return r.complete()},error:function(e){return r.error(e)}});return{unsubscribe:function(){i.unsubscribe(),s.unsubscribe()}}})});return{point:e,sample:s,map:o,switchMap:i,all:function(r){return r.length?n.apply(void 0,toConsumableArray(r).concat([function(){for(var r=arguments.length,e=Array(r),t=0;t<r;t++)e[t]=arguments[t];return e}])):e([])},combineLatest:n,startWith:t,scan:function(e,t,n){var o=t;return new r(function(r){return n.subscribe({error:function(e){return r.error(e)},next:function(t){return r.next(function(r){return o=e(o,r)}(t))},complete:function(){return r.complete()}})})},throttle:function(e){return function(t){return new r(function(r){return t.subscribe({complete:e(function(){return r.complete()}),error:function(e){return r.error(e)},next:e(function(e){return r.next(e)})})})}},toObservable:function(r){return isObservable(r)?r:e(r)},fromPromise:function(e){return new r(function(r){e.then(function(e){return r.next(e)}).catch(function(){return r.complete()})})},share:function(e){var t=[],n=void 0;return new r(function(r){return t.push(r),1===t.length&&(n=e.subscribe({complete:function(){return t.forEach(function(r){return r.complete()})},error:function(r){return t.forEach(function(e){return e.error(r)})},next:function(r){return t.forEach(function(e){return e.next(r)})}})),{unsubscribe:function(){t=t.filter(function(e){return e!==r}),0===r.length&&n.unsubscribe()}}})}}},createRaf=function(r){return new r(function(r){var e=!0;return window.requestAnimationFrame(function t(){e&&(r.next(),window.requestAnimationFrame(t))}),{unsubscribe:function(){e=!1}}})};function _objectEntries(r){for(var e=[],t=Object.keys(r),n=0;n<t.length;++n)e.push([t[n],r[t[n]]]);return e}var VNode=function r(e){var t=e.name,n=e.attrs,o=e.lifecycle,i=e.events,s=e.children;classCallCheck(this,r),this.name=t,this.attrs=n,this.lifecycle=o,this.events=i,this.children=s},VText=function r(e){var t=e.text;classCallCheck(this,r),this.text=t},isLifecycle=function(r){return["mount","update","unmount"].includes(r)},isEvent=function(r){return!!r.match(/^on/)},toEventName=function(r){return r.replace(/^on/,"").toLowerCase()},styleToObject=function(r){return r.split(";").reduce(function(r,e){var t=e.split(/:/),n=toArray(t),o=n[0],i=n.slice(1);return o.trim()&&(r[o.trim()]=i.join(":")),r},{})},formatChildren=flatMap(function(r){return Array.isArray(r)?r:r instanceof VNode||r instanceof VText?[r]:isEmpty(r)?[]:[new VText({text:""+r})]});function h(r){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},t=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[],n=_objectEntries(e).reduce(function(r,e){var t=slicedToArray(e,2),n=t[0],o=t[1];return isLifecycle(n)&&"function"==typeof o?r.lifecycle[n]=o:isEvent(n)&&"function"==typeof o?r.events[toEventName(n)]=o:r.attrs[n]="style"===n?"object"===(void 0===o?"undefined":_typeof(o))?o:styleToObject(o):o,r},{lifecycle:{},events:{},attrs:{}}),o=n.lifecycle,i=n.events,s=n.attrs;return new VNode({name:r,attrs:s,lifecycle:o,events:i,children:formatChildren(t)})}function _objectEntries$2(r){for(var e=[],t=Object.keys(r),n=0;n<t.length;++n)e.push([t[n],r[t[n]]]);return e}var vTreeKey=Symbol("vTree");function updateEvents(r,e,t){var n=!0,o=!1,i=void 0;try{for(var s,c=_objectEntries$2(t)[Symbol.iterator]();!(n=(s=c.next()).done);n=!0){var u=s.value,a=slicedToArray(u,2),l=a[0],f=a[1];e[l]?f!==e[l]&&(r.removeEventListener(l,e[l]),r.addEventListener(l,f)):r.addEventListener(l,f)}}catch(r){o=!0,i=r}finally{try{!n&&c.return&&c.return()}finally{if(o)throw i}}var p=_objectEntries$2(e).filter(function(r){var e=slicedToArray(r,1)[0];return!t[e]}),b=!0,h=!1,y=void 0;try{for(var _,T=p[Symbol.iterator]();!(b=(_=T.next()).done);b=!0){var v=_.value,d=slicedToArray(v,2),m=d[0],A=d[1];r.removeEventListener(m,A)}}catch(r){h=!0,y=r}finally{try{!b&&T.return&&T.return()}finally{if(h)throw y}}}function updateStyle(r){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},t=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};for(var n in _extends({},e,t)){var o=t&&t[n]?t[n]:"";t[n]===e[n]||("-"===n[0]?r.style.setProperty(n,o):r.style[n]=o)}}function updateAttrs(r,e,t){for(var n in _extends({},e,t)){var o=t[n];o===e[n]||(isEmpty(o)?"value"===n&&"INPUT"===r.tagName?r.value="":r.removeAttribute(n):"style"===n?updateStyle(r,e.style,t.style):"value"===n&&"INPUT"===r.tagName?r.value=o:r.setAttribute(n,o))}}function updateChildren(r,e,t){for(var n in e){var o=e[n],i=r.childNodes[n];isEmpty(o)||(i?o instanceof VNode&&o.lifecycle.render?o.lifecycle.render(i,o):updateElement(i,o,t):r.appendChild(createElement(o,t)))}var s=!0,c=!1,u=void 0;try{for(var a,l=[].slice.call(r.childNodes,e.length)[Symbol.iterator]();!(s=(a=l.next()).done);s=!0){removeElement(a.value)}}catch(r){c=!0,u=r}finally{try{!s&&l.return&&l.return()}finally{if(c)throw u}}}function createElement(r,e){if(r instanceof VText){var t=document.createTextNode(r.text);return t[vTreeKey]=r,t}var n=(e=e||"svg"===r.name)?document.createElementNS("http://www.w3.org/2000/svg",r.name):document.createElement(r.name);return updateEvents(n,{},r.events),updateAttrs(n,{},r.attrs),updateChildren(n,r.children,e),r.lifecycle.mount&&r.lifecycle.mount(n),n[vTreeKey]=r,n}function updateElement(r,e,t){var n=r[vTreeKey];return e instanceof VText?(n.text!==e.text&&(r.textContent=e.text),r[vTreeKey]=e):n.name!==e.name?(n.lifecycle.unmount&&n.lifecycle.unmount(r),r.parentNode.replaceChild(createElement(e),r)):(updateEvents(r,n.events,e.events),updateAttrs(r,n.attrs,e.attrs),updateChildren(r,e.children,t),e.lifecycle.update&&e.lifecycle.update(r),r[vTreeKey]=e),r}function removeElement(r){r[vTreeKey]instanceof VNode&&r[vTreeKey].lifecycle.unmount&&r[vTreeKey].lifecycle.unmount(r),r.remove()}function createVTree(r){return new VNode({name:r.nodeName.toLowerCase(),lifecycle:{},events:{},attrs:{},children:Array.prototype.map.call(r.childNodes,function(r){return 3===r.nodeType?new VText({text:r.nodeValue}):createVTree(r)})})}function patch(r,e){return r[vTreeKey]||(r[vTreeKey]=createVTree(r)),updateElement(r,e)}var commonjsGlobal="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function createCommonjsModule(r,e){return r(e={exports:{}},e.exports),e.exports}var __window="undefined"!=typeof window&&window,__self="undefined"!=typeof self&&"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope&&self,__global=void 0!==commonjsGlobal&&commonjsGlobal,_root=__window||__global||__self,root_1=_root;!function(){if(!_root)throw new Error("RxJS could not find any global context (window, self, global)")}();var root={root:root_1};function isFunction(r){return"function"==typeof r}var isFunction_2=isFunction,isFunction_1={isFunction:isFunction_2},isArray_1=Array.isArray||function(r){return r&&"number"==typeof r.length},isArray={isArray:isArray_1};function isObject(r){return null!=r&&"object"==typeof r}var tryCatchTarget,isObject_2=isObject,isObject_1={isObject:isObject_2},errorObject_1={e:{}},errorObject={errorObject:errorObject_1};function tryCatcher(){try{return tryCatchTarget.apply(this,arguments)}catch(r){return errorObject.errorObject.e=r,errorObject.errorObject}}function tryCatch(r){return tryCatchTarget=r,tryCatcher}var tryCatch_2=tryCatch,tryCatch_1={tryCatch:tryCatch_2},__extends$1=commonjsGlobal&&commonjsGlobal.__extends||function(r,e){for(var t in e)e.hasOwnProperty(t)&&(r[t]=e[t]);function n(){this.constructor=r}r.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},UnsubscriptionError=function(r){function e(e){r.call(this),this.errors=e;var t=Error.call(this,e?e.length+" errors occurred during unsubscription:\n "+e.map(function(r,e){return e+1+") "+r.toString()}).join("\n "):"");this.name=t.name="UnsubscriptionError",this.stack=t.stack,this.message=t.message}return __extends$1(e,r),e}(Error),UnsubscriptionError_2=UnsubscriptionError,UnsubscriptionError_1={UnsubscriptionError:UnsubscriptionError_2},Subscription=function(){function r(r){this.closed=!1,this._parent=null,this._parents=null,this._subscriptions=null,r&&(this._unsubscribe=r)}var e;return r.prototype.unsubscribe=function(){var r,e=!1;if(!this.closed){var t=this._parent,n=this._parents,o=this._unsubscribe,i=this._subscriptions;this.closed=!0,this._parent=null,this._parents=null,this._subscriptions=null;for(var s=-1,c=n?n.length:0;t;)t.remove(this),t=++s<c&&n[s]||null;if(isFunction_1.isFunction(o))tryCatch_1.tryCatch(o).call(this)===errorObject.errorObject&&(e=!0,r=r||(errorObject.errorObject.e instanceof UnsubscriptionError_1.UnsubscriptionError?flattenUnsubscriptionErrors(errorObject.errorObject.e.errors):[errorObject.errorObject.e]));if(isArray.isArray(i))for(s=-1,c=i.length;++s<c;){var u=i[s];if(isObject_1.isObject(u))if(tryCatch_1.tryCatch(u.unsubscribe).call(u)===errorObject.errorObject){e=!0,r=r||[];var a=errorObject.errorObject.e;a instanceof UnsubscriptionError_1.UnsubscriptionError?r=r.concat(flattenUnsubscriptionErrors(a.errors)):r.push(a)}}if(e)throw new UnsubscriptionError_1.UnsubscriptionError(r)}},r.prototype.add=function(e){if(!e||e===r.EMPTY)return r.EMPTY;if(e===this)return this;var t=e;switch(typeof e){case"function":t=new r(e);case"object":if(t.closed||"function"!=typeof t.unsubscribe)return t;if(this.closed)return t.unsubscribe(),t;if("function"!=typeof t._addParent){var n=t;(t=new r)._subscriptions=[n]}break;default:throw new Error("unrecognized teardown "+e+" added to Subscription.")}return(this._subscriptions||(this._subscriptions=[])).push(t),t._addParent(this),t},r.prototype.remove=function(r){var e=this._subscriptions;if(e){var t=e.indexOf(r);-1!==t&&e.splice(t,1)}},r.prototype._addParent=function(r){var e=this._parent,t=this._parents;e&&e!==r?t?-1===t.indexOf(r)&&t.push(r):this._parents=[r]:this._parent=r},r.EMPTY=((e=new r).closed=!0,e),r}(),Subscription_2=Subscription;function flattenUnsubscriptionErrors(r){return r.reduce(function(r,e){return r.concat(e instanceof UnsubscriptionError_1.UnsubscriptionError?e.errors:e)},[])}var Subscription_1={Subscription:Subscription_2},empty={closed:!0,next:function(r){},error:function(r){throw r},complete:function(){}},Observer={empty:empty},rxSubscriber=createCommonjsModule(function(r,e){var t=root.root.Symbol;e.rxSubscriber="function"==typeof t&&"function"==typeof t.for?t.for("rxSubscriber"):"@@rxSubscriber",e.$$rxSubscriber=e.rxSubscriber}),rxSubscriber_1=rxSubscriber.rxSubscriber,rxSubscriber_2=rxSubscriber.$$rxSubscriber,__extends=commonjsGlobal&&commonjsGlobal.__extends||function(r,e){for(var t in e)e.hasOwnProperty(t)&&(r[t]=e[t]);function n(){this.constructor=r}r.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},Subscriber=function(r){function e(t,n,o){switch(r.call(this),this.syncErrorValue=null,this.syncErrorThrown=!1,this.syncErrorThrowable=!1,this.isStopped=!1,arguments.length){case 0:this.destination=Observer.empty;break;case 1:if(!t){this.destination=Observer.empty;break}if("object"==typeof t){t instanceof e?(this.syncErrorThrowable=t.syncErrorThrowable,this.destination=t,this.destination.add(this)):(this.syncErrorThrowable=!0,this.destination=new SafeSubscriber(this,t));break}default:this.syncErrorThrowable=!0,this.destination=new SafeSubscriber(this,t,n,o)}}return __extends(e,r),e.prototype[rxSubscriber.rxSubscriber]=function(){return this},e.create=function(r,t,n){var o=new e(r,t,n);return o.syncErrorThrowable=!1,o},e.prototype.next=function(r){this.isStopped||this._next(r)},e.prototype.error=function(r){this.isStopped||(this.isStopped=!0,this._error(r))},e.prototype.complete=function(){this.isStopped||(this.isStopped=!0,this._complete())},e.prototype.unsubscribe=function(){this.closed||(this.isStopped=!0,r.prototype.unsubscribe.call(this))},e.prototype._next=function(r){this.destination.next(r)},e.prototype._error=function(r){this.destination.error(r),this.unsubscribe()},e.prototype._complete=function(){this.destination.complete(),this.unsubscribe()},e.prototype._unsubscribeAndRecycle=function(){var r=this._parent,e=this._parents;return this._parent=null,this._parents=null,this.unsubscribe(),this.closed=!1,this.isStopped=!1,this._parent=r,this._parents=e,this},e}(Subscription_1.Subscription),Subscriber_2=Subscriber,SafeSubscriber=function(r){function e(e,t,n,o){var i;r.call(this),this._parentSubscriber=e;var s=this;isFunction_1.isFunction(t)?i=t:t&&(i=t.next,n=t.error,o=t.complete,t!==Observer.empty&&(s=Object.create(t),isFunction_1.isFunction(s.unsubscribe)&&this.add(s.unsubscribe.bind(s)),s.unsubscribe=this.unsubscribe.bind(this))),this._context=s,this._next=i,this._error=n,this._complete=o}return __extends(e,r),e.prototype.next=function(r){if(!this.isStopped&&this._next){var e=this._parentSubscriber;e.syncErrorThrowable?this.__tryOrSetError(e,this._next,r)&&this.unsubscribe():this.__tryOrUnsub(this._next,r)}},e.prototype.error=function(r){if(!this.isStopped){var e=this._parentSubscriber;if(this._error)e.syncErrorThrowable?(this.__tryOrSetError(e,this._error,r),this.unsubscribe()):(this.__tryOrUnsub(this._error,r),this.unsubscribe());else{if(!e.syncErrorThrowable)throw this.unsubscribe(),r;e.syncErrorValue=r,e.syncErrorThrown=!0,this.unsubscribe()}}},e.prototype.complete=function(){var r=this;if(!this.isStopped){var e=this._parentSubscriber;if(this._complete){var t=function(){return r._complete.call(r._context)};e.syncErrorThrowable?(this.__tryOrSetError(e,t),this.unsubscribe()):(this.__tryOrUnsub(t),this.unsubscribe())}else this.unsubscribe()}},e.prototype.__tryOrUnsub=function(r,e){try{r.call(this._context,e)}catch(r){throw this.unsubscribe(),r}},e.prototype.__tryOrSetError=function(r,e,t){try{e.call(this._context,t)}catch(e){return r.syncErrorValue=e,r.syncErrorThrown=!0,!0}return!1},e.prototype._unsubscribe=function(){var r=this._parentSubscriber;this._context=null,this._parentSubscriber=null,r.unsubscribe()},e}(Subscriber),Subscriber_1={Subscriber:Subscriber_2};function toSubscriber(r,e,t){if(r){if(r instanceof Subscriber_1.Subscriber)return r;if(r[rxSubscriber.rxSubscriber])return r[rxSubscriber.rxSubscriber]()}return r||e||t?new Subscriber_1.Subscriber(r,e,t):new Subscriber_1.Subscriber(Observer.empty)}var toSubscriber_2=toSubscriber,toSubscriber_1={toSubscriber:toSubscriber_2},observable=createCommonjsModule(function(r,e){function t(r){var e,t=r.Symbol;return"function"==typeof t?t.observable?e=t.observable:(e=t("observable"),t.observable=e):e="@@observable",e}e.getSymbolObservable=t,e.observable=t(root.root),e.$$observable=e.observable}),observable_1=observable.getSymbolObservable,observable_2=observable.observable,observable_3=observable.$$observable;function noop(){}var noop_2=noop,noop_1={noop:noop_2};function pipe$1(){for(var r=[],e=0;e<arguments.length;e++)r[e-0]=arguments[e];return pipeFromArray(r)}var pipe_2=pipe$1;function pipeFromArray(r){return r?1===r.length?r[0]:function(e){return r.reduce(function(r,e){return e(r)},e)}:noop_1.noop}var pipeFromArray_1=pipeFromArray,pipe_1={pipe:pipe_2,pipeFromArray:pipeFromArray_1},Observable$1=function(){function r(r){this._isScalar=!1,r&&(this._subscribe=r)}return r.prototype.lift=function(e){var t=new r;return t.source=this,t.operator=e,t},r.prototype.subscribe=function(r,e,t){var n=this.operator,o=toSubscriber_1.toSubscriber(r,e,t);if(n?n.call(o,this.source):o.add(this.source||!o.syncErrorThrowable?this._subscribe(o):this._trySubscribe(o)),o.syncErrorThrowable&&(o.syncErrorThrowable=!1,o.syncErrorThrown))throw o.syncErrorValue;return o},r.prototype._trySubscribe=function(r){try{return this._subscribe(r)}catch(e){r.syncErrorThrown=!0,r.syncErrorValue=e,r.error(e)}},r.prototype.forEach=function(r,e){var t=this;if(e||(root.root.Rx&&root.root.Rx.config&&root.root.Rx.config.Promise?e=root.root.Rx.config.Promise:root.root.Promise&&(e=root.root.Promise)),!e)throw new Error("no Promise impl found");return new e(function(e,n){var o;o=t.subscribe(function(e){if(o)try{r(e)}catch(r){n(r),o.unsubscribe()}else r(e)},n,e)})},r.prototype._subscribe=function(r){return this.source.subscribe(r)},r.prototype[observable.observable]=function(){return this},r.prototype.pipe=function(){for(var r=[],e=0;e<arguments.length;e++)r[e-0]=arguments[e];return 0===r.length?this:pipe_1.pipeFromArray(r)(this)},r.prototype.toPromise=function(r){var e=this;if(r||(root.root.Rx&&root.root.Rx.config&&root.root.Rx.config.Promise?r=root.root.Rx.config.Promise:root.root.Promise&&(r=root.root.Promise)),!r)throw new Error("no Promise impl found");return new r(function(r,t){var n;e.subscribe(function(r){return n=r},function(r){return t(r)},function(){return r(n)})})},r.create=function(e){return new r(e)},r}(),Observable_2=Observable$1,_createOperators=createOperators(Observable_2),map=_createOperators.map,startWith=_createOperators.startWith,fromPromise=_createOperators.fromPromise,toObservable=_createOperators.toObservable,all=_createOperators.all,switchMap=_createOperators.switchMap,sample=_createOperators.sample,share=_createOperators.share,raf=share(createRaf(Observable_2)),toAStream=function r(e){return Array.isArray(e)?all(e.map(r).map(startWith(""))):isObservable(e)?switchMap(r)(e):isPromise(e)?compose(switchMap(r),fromPromise)(e):toObservable(e)},createReactiveTag=function(r){return function(e){for(var t=arguments.length,n=Array(t>1?t-1:0),o=1;o<t;o++)n[o-1]=arguments[o];return pipe(toAStream,startWith([]),sample(raf),map(function(t){return r.apply(void 0,[e].concat(toConsumableArray(t)))}))(n)}},hx=hyperx(h,{attrToProp:!1}),htmlTag=hx,render=function(r,e){var t=void 0;return r.forEach(function(r){t?patch(t,r):(t=createElement(r),e.appendChild(t))})},createRenderProcess=function(r){return new Observable_2(function(e){var t=void 0,n=void 0;return r.subscribe({complete:function(){return e.complete()},error:function(r){return e.error(r)},next:function(r){if(!(r instanceof VNode))return e.next(r);n=r;var o=r.lifecycle.mount;n.lifecycle.mount=function(r){t=r,o&&o(r)},n.lifecycle.render=function(r){patch(t=r,n)},t?patch(t,n):e.next(n)}})})},toComponent=function(r){return function(e){for(var t=arguments.length,n=Array(t>1?t-1:0),o=1;o<t;o++)n[o-1]=arguments[o];return createRenderProcess(r.apply(void 0,[e].concat(n)))}},html$1=toComponent(createReactiveTag(htmlTag)),textTag=function(r){for(var e=arguments.length,t=Array(e>1?e-1:0),n=1;n<e;n++)t[n-1]=arguments[n];return r.reduce(function(r,e,n){return r+e+(void 0!==t[n]?t[n]:"")},"")},text=createReactiveTag(textTag),defaultSecondPerFrame=.016,reusedTuple=[0,0];function stepper(r,e,t){var n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:170,o=arguments.length>4&&void 0!==arguments[4]?arguments[4]:20,i=arguments.length>5&&void 0!==arguments[5]?arguments[5]:defaultSecondPerFrame,s=arguments.length>6&&void 0!==arguments[6]?arguments[6]:.1,c=e+(-n*(r-t)+-o*e)*i,u=r+c*i;return Math.abs(c)<s&&Math.abs(u-t)<s?(reusedTuple[0]=t,reusedTuple[1]=0,reusedTuple):(reusedTuple[0]=u,reusedTuple[1]=c,reusedTuple)}var rafThrottle=function(r){var e=!0,t=[];return function(){for(var n=arguments.length,o=Array(n),i=0;i<n;i++)o[i]=arguments[i];t=o,e&&(e=!1,window.requestAnimationFrame(function(){e=!0,r.apply(void 0,toConsumableArray(t))}))}},ease=function(r,e){var t=void 0,n=0,o=void 0;return function(i){return o=i,void 0===t&&(t=i),new Observable_2(function(i){var s=!0,c=rafThrottle(function(){var u=stepper(t,n,o,r,e),a=slicedToArray(u,2);t=a[0],n=a[1],i.next(t),0!==n&&s&&c()});return c(),{unsubscribe:function(){s=!1}}})}},cache=new Map,getEase=function(r,e,t){return void 0===t?ease(r,e):(cache.has(t)||cache.set(t,ease(r,e)),cache.get(t))};exports.default=html$1,exports.ease=getEase,exports.text=text,exports.render=render; | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var commonjsGlobal="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function unwrapExports(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function createCommonjsModule(e,t){return e(t={exports:{}},t.exports),t.exports}var lib=createCommonjsModule(function(e,t){Object.defineProperty(t,"__esModule",{value:!0});var r=function(e){return 0!==e&&(!e||"string"==typeof e&&!e.trim())},n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},o=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e},i=function(){return function(e,t){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return function(e,t){var r=[],n=!0,o=!1,i=void 0;try{for(var s,u=e[Symbol.iterator]();!(n=(s=u.next()).done)&&(r.push(s.value),!t||r.length!==t);n=!0);}catch(e){o=!0,i=e}finally{try{!n&&u.return&&u.return()}finally{if(o)throw i}}return r}(e,t);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),s=function(e){if(Array.isArray(e)){for(var t=0,r=Array(e.length);t<e.length;t++)r[t]=e[t];return r}return Array.from(e)};var u,c=(u=0,function(e){return e.reduce(function(e,t){return o({},e,(i=u++,(n=t)in(r={})?Object.defineProperty(r,n,{value:i,enumerable:!0,configurable:!0,writable:!0}):r[n]=i,r));var r,n,i},{})}),a=c(["Text","Tag","ClosingTag","Attr","AttrKey","AttrValue","AttrValueSingleQuote","AttrValueDoubleQuote"]),l=c(["Text","OpenTag","AttributeName","AttributeValue","CloseTag","SelfCloseTag","ClosingTag","VTree"]),b=c(["Node","VTree","Text"]);function p(e){for(var t=[],n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:a.Text,o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"",i=0;i<e.length;i++){var s=e[i];switch(n){case a.Text:"<"===s?(r(o)||t.push({type:l.Text,value:o}),o="",n=a.Tag):o+=s;continue;case a.Tag:/\s/.test(s)?(t.push({type:l.OpenTag,value:o}),o="",n=a.Attr):">"===s?(t.push({type:l.OpenTag,value:o}),t.push({type:l.CloseTag}),o="",n=a.Text):"/"===s&&""===o?n=a.ClosingTag:o+=s;continue;case a.ClosingTag:">"===s?(t.push({type:l.ClosingTag,value:o}),o="",n=a.Text):o+=s;continue;case a.Attr:">"===s?("/"===o?t.push({type:l.SelfCloseTag}):t.push({type:l.CloseTag}),o="",n=a.Text):/\s/.test(s)||("/"===s?o+=s:(o+=s,n=a.AttrKey));continue;case a.AttrKey:"="===s?(""!==o&&t.push({type:l.AttributeName,value:o}),o="",n=a.AttrValue):/\s/.test(s)?(""!==o&&t.push({type:l.AttributeName,value:o}),o="",n=a.Attr):o+=s;continue;case a.AttrValue:/\s/.test(s)?(t.push({type:l.AttributeValue,value:o}),o="",n=a.Attr):">"===s?(t.push({type:l.AttributeValue,value:o}),t.push({type:l.CloseTag}),o="",n=a.Text):""===o&&"'"===s?n=a.AttrValueSingleQuote:""===o&&'"'===s?n=a.AttrValueDoubleQuote:o+=s;continue;case a.AttrValueSingleQuote:"'"===s?(t.push({type:l.AttributeValue,value:o}),o="",n=a.Attr):o+=s;continue;case a.AttrValueDoubleQuote:'"'===s?(t.push({type:l.AttributeValue,value:o}),o="",n=a.Attr):o+=s;continue}}return[t,n,o]}var f=function(e){return[(t=function(e){var t=i(e,2),r=t[0],n=t[1];return r.trim()?[{type:l.AttributeName,value:r},{type:l.AttributeValue,value:n}]:[]},r=function(e){for(var t=[],r=Object.keys(e),n=0;n<r.length;++n)t.push([r[n],e[r[n]]]);return t}(e),r.reduce(function(e,r){return e.concat(t(r))},[])),a.Attr];var t,r},h=function(e){return e.split(/\s+/).filter(function(e){return e.trim()}).reduce(function(e,t){var r=i(e,1)[0],n=t.split("="),o=i(n,2),s=o[0],u=o[1];return u?[r.concat([{type:l.AttributeName,value:s},{type:l.AttributeValue,value:u}]),a.Attr]:[r.concat([{type:l.AttributeName,value:s}]),a.AttrKey]},[[],a.Attr])};function y(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:l.Text,o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"";if(void 0===e)return[[],t,o];var s=[],u=t,c=o;switch(u){case a.Text:"object"===(void 0===e?"undefined":n(e))?(r(c)||s.push({type:l.Text,value:c}),s.push({type:l.VTree,value:e}),c=""):(r(c)||s.push({type:l.Text,value:c}),r(e)||s.push({type:l.Text,value:e.toString()}),c="");break;case a.Tag:case a.ClosingTag:""!==c?c+=e:c=e;break;case a.Attr:if("object"===(void 0===e?"undefined":n(e))){var b=f(e),p=i(b,2);s=p[0],u=p[1]}else{if("string"!=typeof e)throw new Error("Variable "+e+" of type '"+(void 0===e?"undefined":n(e))+"' is not supported in the State.Attr context");var y=h(e),v=i(y,2);s=v[0],u=v[1]}break;case a.AttrKey:throw new Error("Variable "+e+" of type '"+(void 0===e?"undefined":n(e))+"' is not supported in the State.AttrKey context");case a.AttrValue:case a.AttrValueSingleQuote:case a.AttrValueDoubleQuote:""!==c?c+=e:c=e}return[s,u,c]}var v=function(e){for(var t=arguments.length,r=Array(t>1?t-1:0),n=1;n<t;n++)r[n-1]=arguments[n];for(var o=[],s=a.Text,u="",c=0;c<e.length;c++){var l=e[c],b=r[c],f=p(l,s,u),h=i(f,3),v=h[0],d=y(b,h[1],h[2]),m=i(d,3),_=m[0],S=m[1],x=m[2];o=o.concat(v).concat(_),s=S,u=x}return o},d=1,m=2,_=function e(t,r){return r.map(function(r){switch(r.type){case b.Node:return t(r.value[0],r.value[d],e(t,r.value[m]));case b.VTree:case b.Text:return r.value}})};function S(e){for(var t=[],r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;r<e.length;){var n=e[r],o=t[t.length-1],u=o&&o.type===b.Node?o.value:null;switch(n.type){case l.OpenTag:t.push({type:b.Node,value:[n.value,{},[]]}),r++;break;case l.Text:t.push({type:b.Text,value:n.value}),r++;break;case l.VTree:t.push.apply(t,s(Array.isArray(n.value)?n.value.map(function(e){return{type:b.VTree,value:e}}):[{type:b.VTree,value:n.value}])),r++;break;case l.AttributeName:u?e[r+1]&&e[r+1].type===l.AttributeValue?(u[d][n.value]=e[r+1].value,r+=2):(u[d][n.value]=!0,r++):r++;break;case l.AttributeValue:break;case l.CloseTag:if(u){var c=S(e,r+1),a=i(c,2),p=a[0],f=a[1];u[m]=p,r=f}else r++;break;case l.SelfCloseTag:r++;break;case l.ClosingTag:return[t,r+1]}}return[t,r]}var x=function(e){return 1===e.length?e[0]:e};t.State=a,t.Token=l,t.Tree=b,t.tokenizer=p,t.variableTokenizer=y,t.tokenizerTag=v,t.buildTree=S,t.default=function(e){return function(){var t=S(v.apply(void 0,arguments)),r=i(t,1)[0];return x(_(e,r))}}}),createTag=unwrapExports(lib),lib_1=lib.State,lib_2=lib.Token,lib_3=lib.Tree,lib_4=lib.tokenizer,lib_5=lib.variableTokenizer,lib_6=lib.tokenizerTag,lib_7=lib.buildTree,__window="undefined"!=typeof window&&window,__self="undefined"!=typeof self&&"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope&&self,__global=void 0!==commonjsGlobal&&commonjsGlobal,_root=__window||__global||__self,root_1=_root;!function(){if(!_root)throw new Error("RxJS could not find any global context (window, self, global)")}();var root={root:root_1};function isFunction(e){return"function"==typeof e}var isFunction_2=isFunction,isFunction_1={isFunction:isFunction_2},isArray_1=Array.isArray||function(e){return e&&"number"==typeof e.length},isArray={isArray:isArray_1};function isObject(e){return null!=e&&"object"==typeof e}var tryCatchTarget,isObject_2=isObject,isObject_1={isObject:isObject_2},errorObject_1={e:{}},errorObject={errorObject:errorObject_1};function tryCatcher(){try{return tryCatchTarget.apply(this,arguments)}catch(e){return errorObject.errorObject.e=e,errorObject.errorObject}}function tryCatch(e){return tryCatchTarget=e,tryCatcher}var tryCatch_2=tryCatch,tryCatch_1={tryCatch:tryCatch_2},__extends$1=commonjsGlobal&&commonjsGlobal.__extends||function(e,t){for(var r in t)t.hasOwnProperty(r)&&(e[r]=t[r]);function n(){this.constructor=e}e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)},UnsubscriptionError=function(e){function t(t){e.call(this),this.errors=t;var r=Error.call(this,t?t.length+" errors occurred during unsubscription:\n "+t.map(function(e,t){return t+1+") "+e.toString()}).join("\n "):"");this.name=r.name="UnsubscriptionError",this.stack=r.stack,this.message=r.message}return __extends$1(t,e),t}(Error),UnsubscriptionError_2=UnsubscriptionError,UnsubscriptionError_1={UnsubscriptionError:UnsubscriptionError_2},Subscription=function(){function e(e){this.closed=!1,this._parent=null,this._parents=null,this._subscriptions=null,e&&(this._unsubscribe=e)}var t;return e.prototype.unsubscribe=function(){var e,t=!1;if(!this.closed){var r=this._parent,n=this._parents,o=this._unsubscribe,i=this._subscriptions;this.closed=!0,this._parent=null,this._parents=null,this._subscriptions=null;for(var s=-1,u=n?n.length:0;r;)r.remove(this),r=++s<u&&n[s]||null;if(isFunction_1.isFunction(o))tryCatch_1.tryCatch(o).call(this)===errorObject.errorObject&&(t=!0,e=e||(errorObject.errorObject.e instanceof UnsubscriptionError_1.UnsubscriptionError?flattenUnsubscriptionErrors(errorObject.errorObject.e.errors):[errorObject.errorObject.e]));if(isArray.isArray(i))for(s=-1,u=i.length;++s<u;){var c=i[s];if(isObject_1.isObject(c))if(tryCatch_1.tryCatch(c.unsubscribe).call(c)===errorObject.errorObject){t=!0,e=e||[];var a=errorObject.errorObject.e;a instanceof UnsubscriptionError_1.UnsubscriptionError?e=e.concat(flattenUnsubscriptionErrors(a.errors)):e.push(a)}}if(t)throw new UnsubscriptionError_1.UnsubscriptionError(e)}},e.prototype.add=function(t){if(!t||t===e.EMPTY)return e.EMPTY;if(t===this)return this;var r=t;switch(typeof t){case"function":r=new e(t);case"object":if(r.closed||"function"!=typeof r.unsubscribe)return r;if(this.closed)return r.unsubscribe(),r;if("function"!=typeof r._addParent){var n=r;(r=new e)._subscriptions=[n]}break;default:throw new Error("unrecognized teardown "+t+" added to Subscription.")}return(this._subscriptions||(this._subscriptions=[])).push(r),r._addParent(this),r},e.prototype.remove=function(e){var t=this._subscriptions;if(t){var r=t.indexOf(e);-1!==r&&t.splice(r,1)}},e.prototype._addParent=function(e){var t=this._parent,r=this._parents;t&&t!==e?r?-1===r.indexOf(e)&&r.push(e):this._parents=[e]:this._parent=e},e.EMPTY=((t=new e).closed=!0,t),e}(),Subscription_2=Subscription;function flattenUnsubscriptionErrors(e){return e.reduce(function(e,t){return e.concat(t instanceof UnsubscriptionError_1.UnsubscriptionError?t.errors:t)},[])}var Subscription_1={Subscription:Subscription_2},empty={closed:!0,next:function(e){},error:function(e){throw e},complete:function(){}},Observer={empty:empty},rxSubscriber=createCommonjsModule(function(e,t){var r=root.root.Symbol;t.rxSubscriber="function"==typeof r&&"function"==typeof r.for?r.for("rxSubscriber"):"@@rxSubscriber",t.$$rxSubscriber=t.rxSubscriber}),rxSubscriber_1=rxSubscriber.rxSubscriber,rxSubscriber_2=rxSubscriber.$$rxSubscriber,__extends=commonjsGlobal&&commonjsGlobal.__extends||function(e,t){for(var r in t)t.hasOwnProperty(r)&&(e[r]=t[r]);function n(){this.constructor=e}e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)},Subscriber=function(e){function t(r,n,o){switch(e.call(this),this.syncErrorValue=null,this.syncErrorThrown=!1,this.syncErrorThrowable=!1,this.isStopped=!1,arguments.length){case 0:this.destination=Observer.empty;break;case 1:if(!r){this.destination=Observer.empty;break}if("object"==typeof r){r instanceof t?(this.syncErrorThrowable=r.syncErrorThrowable,this.destination=r,this.destination.add(this)):(this.syncErrorThrowable=!0,this.destination=new SafeSubscriber(this,r));break}default:this.syncErrorThrowable=!0,this.destination=new SafeSubscriber(this,r,n,o)}}return __extends(t,e),t.prototype[rxSubscriber.rxSubscriber]=function(){return this},t.create=function(e,r,n){var o=new t(e,r,n);return o.syncErrorThrowable=!1,o},t.prototype.next=function(e){this.isStopped||this._next(e)},t.prototype.error=function(e){this.isStopped||(this.isStopped=!0,this._error(e))},t.prototype.complete=function(){this.isStopped||(this.isStopped=!0,this._complete())},t.prototype.unsubscribe=function(){this.closed||(this.isStopped=!0,e.prototype.unsubscribe.call(this))},t.prototype._next=function(e){this.destination.next(e)},t.prototype._error=function(e){this.destination.error(e),this.unsubscribe()},t.prototype._complete=function(){this.destination.complete(),this.unsubscribe()},t.prototype._unsubscribeAndRecycle=function(){var e=this._parent,t=this._parents;return this._parent=null,this._parents=null,this.unsubscribe(),this.closed=!1,this.isStopped=!1,this._parent=e,this._parents=t,this},t}(Subscription_1.Subscription),Subscriber_2=Subscriber,SafeSubscriber=function(e){function t(t,r,n,o){var i;e.call(this),this._parentSubscriber=t;var s=this;isFunction_1.isFunction(r)?i=r:r&&(i=r.next,n=r.error,o=r.complete,r!==Observer.empty&&(s=Object.create(r),isFunction_1.isFunction(s.unsubscribe)&&this.add(s.unsubscribe.bind(s)),s.unsubscribe=this.unsubscribe.bind(this))),this._context=s,this._next=i,this._error=n,this._complete=o}return __extends(t,e),t.prototype.next=function(e){if(!this.isStopped&&this._next){var t=this._parentSubscriber;t.syncErrorThrowable?this.__tryOrSetError(t,this._next,e)&&this.unsubscribe():this.__tryOrUnsub(this._next,e)}},t.prototype.error=function(e){if(!this.isStopped){var t=this._parentSubscriber;if(this._error)t.syncErrorThrowable?(this.__tryOrSetError(t,this._error,e),this.unsubscribe()):(this.__tryOrUnsub(this._error,e),this.unsubscribe());else{if(!t.syncErrorThrowable)throw this.unsubscribe(),e;t.syncErrorValue=e,t.syncErrorThrown=!0,this.unsubscribe()}}},t.prototype.complete=function(){var e=this;if(!this.isStopped){var t=this._parentSubscriber;if(this._complete){var r=function(){return e._complete.call(e._context)};t.syncErrorThrowable?(this.__tryOrSetError(t,r),this.unsubscribe()):(this.__tryOrUnsub(r),this.unsubscribe())}else this.unsubscribe()}},t.prototype.__tryOrUnsub=function(e,t){try{e.call(this._context,t)}catch(e){throw this.unsubscribe(),e}},t.prototype.__tryOrSetError=function(e,t,r){try{t.call(this._context,r)}catch(t){return e.syncErrorValue=t,e.syncErrorThrown=!0,!0}return!1},t.prototype._unsubscribe=function(){var e=this._parentSubscriber;this._context=null,this._parentSubscriber=null,e.unsubscribe()},t}(Subscriber),Subscriber_1={Subscriber:Subscriber_2};function toSubscriber(e,t,r){if(e){if(e instanceof Subscriber_1.Subscriber)return e;if(e[rxSubscriber.rxSubscriber])return e[rxSubscriber.rxSubscriber]()}return e||t||r?new Subscriber_1.Subscriber(e,t,r):new Subscriber_1.Subscriber(Observer.empty)}var toSubscriber_2=toSubscriber,toSubscriber_1={toSubscriber:toSubscriber_2},observable=createCommonjsModule(function(e,t){function r(e){var t,r=e.Symbol;return"function"==typeof r?r.observable?t=r.observable:(t=r("observable"),r.observable=t):t="@@observable",t}t.getSymbolObservable=r,t.observable=r(root.root),t.$$observable=t.observable}),observable_1=observable.getSymbolObservable,observable_2=observable.observable,observable_3=observable.$$observable;function noop(){}var noop_2=noop,noop_1={noop:noop_2};function pipe(){for(var e=[],t=0;t<arguments.length;t++)e[t-0]=arguments[t];return pipeFromArray(e)}var pipe_2=pipe;function pipeFromArray(e){return e?1===e.length?e[0]:function(t){return e.reduce(function(e,t){return t(e)},t)}:noop_1.noop}var pipeFromArray_1=pipeFromArray,pipe_1={pipe:pipe_2,pipeFromArray:pipeFromArray_1},Observable=function(){function e(e){this._isScalar=!1,e&&(this._subscribe=e)}return e.prototype.lift=function(t){var r=new e;return r.source=this,r.operator=t,r},e.prototype.subscribe=function(e,t,r){var n=this.operator,o=toSubscriber_1.toSubscriber(e,t,r);if(n?n.call(o,this.source):o.add(this.source||!o.syncErrorThrowable?this._subscribe(o):this._trySubscribe(o)),o.syncErrorThrowable&&(o.syncErrorThrowable=!1,o.syncErrorThrown))throw o.syncErrorValue;return o},e.prototype._trySubscribe=function(e){try{return this._subscribe(e)}catch(t){e.syncErrorThrown=!0,e.syncErrorValue=t,e.error(t)}},e.prototype.forEach=function(e,t){var r=this;if(t||(root.root.Rx&&root.root.Rx.config&&root.root.Rx.config.Promise?t=root.root.Rx.config.Promise:root.root.Promise&&(t=root.root.Promise)),!t)throw new Error("no Promise impl found");return new t(function(t,n){var o;o=r.subscribe(function(t){if(o)try{e(t)}catch(e){n(e),o.unsubscribe()}else e(t)},n,t)})},e.prototype._subscribe=function(e){return this.source.subscribe(e)},e.prototype[observable.observable]=function(){return this},e.prototype.pipe=function(){for(var e=[],t=0;t<arguments.length;t++)e[t-0]=arguments[t];return 0===e.length?this:pipe_1.pipeFromArray(e)(this)},e.prototype.toPromise=function(e){var t=this;if(e||(root.root.Rx&&root.root.Rx.config&&root.root.Rx.config.Promise?e=root.root.Rx.config.Promise:root.root.Promise&&(e=root.root.Promise)),!e)throw new Error("no Promise impl found");return new e(function(e,r){var n;t.subscribe(function(e){return n=e},function(e){return r(e)},function(){return e(n)})})},e.create=function(t){return new e(t)},e}(),Observable_2=Observable,Observable_1={Observable:Observable_2},__extends$3=commonjsGlobal&&commonjsGlobal.__extends||function(e,t){for(var r in t)t.hasOwnProperty(r)&&(e[r]=t[r]);function n(){this.constructor=e}e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)},ObjectUnsubscribedError=function(e){function t(){var t=e.call(this,"object unsubscribed");this.name=t.name="ObjectUnsubscribedError",this.stack=t.stack,this.message=t.message}return __extends$3(t,e),t}(Error),ObjectUnsubscribedError_2=ObjectUnsubscribedError,ObjectUnsubscribedError_1={ObjectUnsubscribedError:ObjectUnsubscribedError_2},__extends$4=commonjsGlobal&&commonjsGlobal.__extends||function(e,t){for(var r in t)t.hasOwnProperty(r)&&(e[r]=t[r]);function n(){this.constructor=e}e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)},SubjectSubscription=function(e){function t(t,r){e.call(this),this.subject=t,this.subscriber=r,this.closed=!1}return __extends$4(t,e),t.prototype.unsubscribe=function(){if(!this.closed){this.closed=!0;var e=this.subject,t=e.observers;if(this.subject=null,t&&0!==t.length&&!e.isStopped&&!e.closed){var r=t.indexOf(this.subscriber);-1!==r&&t.splice(r,1)}}},t}(Subscription_1.Subscription),SubjectSubscription_2=SubjectSubscription,SubjectSubscription_1={SubjectSubscription:SubjectSubscription_2},__extends$2=commonjsGlobal&&commonjsGlobal.__extends||function(e,t){for(var r in t)t.hasOwnProperty(r)&&(e[r]=t[r]);function n(){this.constructor=e}e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)},SubjectSubscriber=function(e){function t(t){e.call(this,t),this.destination=t}return __extends$2(t,e),t}(Subscriber_1.Subscriber),Subject=function(e){function t(){e.call(this),this.observers=[],this.closed=!1,this.isStopped=!1,this.hasError=!1,this.thrownError=null}return __extends$2(t,e),t.prototype[rxSubscriber.rxSubscriber]=function(){return new SubjectSubscriber(this)},t.prototype.lift=function(e){var t=new AnonymousSubject(this,this);return t.operator=e,t},t.prototype.next=function(e){if(this.closed)throw new ObjectUnsubscribedError_1.ObjectUnsubscribedError;if(!this.isStopped)for(var t=this.observers,r=t.length,n=t.slice(),o=0;o<r;o++)n[o].next(e)},t.prototype.error=function(e){if(this.closed)throw new ObjectUnsubscribedError_1.ObjectUnsubscribedError;this.hasError=!0,this.thrownError=e,this.isStopped=!0;for(var t=this.observers,r=t.length,n=t.slice(),o=0;o<r;o++)n[o].error(e);this.observers.length=0},t.prototype.complete=function(){if(this.closed)throw new ObjectUnsubscribedError_1.ObjectUnsubscribedError;this.isStopped=!0;for(var e=this.observers,t=e.length,r=e.slice(),n=0;n<t;n++)r[n].complete();this.observers.length=0},t.prototype.unsubscribe=function(){this.isStopped=!0,this.closed=!0,this.observers=null},t.prototype._trySubscribe=function(t){if(this.closed)throw new ObjectUnsubscribedError_1.ObjectUnsubscribedError;return e.prototype._trySubscribe.call(this,t)},t.prototype._subscribe=function(e){if(this.closed)throw new ObjectUnsubscribedError_1.ObjectUnsubscribedError;return this.hasError?(e.error(this.thrownError),Subscription_1.Subscription.EMPTY):this.isStopped?(e.complete(),Subscription_1.Subscription.EMPTY):(this.observers.push(e),new SubjectSubscription_1.SubjectSubscription(this,e))},t.prototype.asObservable=function(){var e=new Observable_1.Observable;return e.source=this,e},t.create=function(e,t){return new AnonymousSubject(e,t)},t}(Observable_1.Observable),Subject_2=Subject,AnonymousSubject=function(e){function t(t,r){e.call(this),this.destination=t,this.source=r}return __extends$2(t,e),t.prototype.next=function(e){var t=this.destination;t&&t.next&&t.next(e)},t.prototype.error=function(e){var t=this.destination;t&&t.error&&this.destination.error(e)},t.prototype.complete=function(){var e=this.destination;e&&e.complete&&this.destination.complete()},t.prototype._subscribe=function(e){return this.source?this.source.subscribe(e):Subscription_1.Subscription.EMPTY},t}(Subject),_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},classCallCheck=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},createClass=function(){function e(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}return function(t,r,n){return r&&e(t.prototype,r),n&&e(t,n),t}}(),defineProperty=function(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e},_extends=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e},slicedToArray=function(){return function(e,t){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return function(e,t){var r=[],n=!0,o=!1,i=void 0;try{for(var s,u=e[Symbol.iterator]();!(n=(s=u.next()).done)&&(r.push(s.value),!t||r.length!==t);n=!0);}catch(e){o=!0,i=e}finally{try{!n&&u.return&&u.return()}finally{if(o)throw i}}return r}(e,t);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),toArray=function(e){return Array.isArray(e)?e:Array.from(e)},toConsumableArray=function(e){if(Array.isArray(e)){for(var t=0,r=Array(e.length);t<e.length;t++)r[t]=e[t];return r}return Array.from(e)},compose=function(){for(var e=arguments.length,t=Array(e),r=0;r<e;r++)t[r]=arguments[r];return function(e){return t.reduceRight(function(e,t){return t(e)},e)}},pipe$1=function(){for(var e=arguments.length,t=Array(e),r=0;r<e;r++)t[r]=arguments[r];return t.reduce(function(e,t){return function(r){return t(e(r))}},function(e){return e})},curry=function e(t){return function(){for(var r=arguments.length,n=Array(r),o=0;o<r;o++)n[o]=arguments[o];return n.length>=t.length?t.apply(void 0,n):function(){for(var r=arguments.length,o=Array(r),i=0;i<r;i++)o[i]=arguments[i];return e(t).apply(void 0,n.concat(o))}}},rafThrottle=function(e){var t=!0,r=[];return function(){for(var n=arguments.length,o=Array(n),i=0;i<n;i++)o[i]=arguments[i];r=o,t&&(t=!1,window.requestAnimationFrame(function(){t=!0,e.apply(void 0,toConsumableArray(r))}))}},init=function(e){return e.slice(0,e.length-1)},last=function(e){return e[e.length-1]},flatMap=curry(function(e,t){return t.reduce(function(t,r){return t.concat(e(r))},[])}),isPromise=function(e){return e&&"function"==typeof e.then},isObservable=function(e){return e&&"function"==typeof e.subscribe},point=function(){for(var e=arguments.length,t=Array(e),r=0;r<e;r++)t[r]=arguments[r];return new Observable_2(function(e){var r=!0,n=!1,o=void 0;try{for(var i,s=t[Symbol.iterator]();!(r=(i=s.next()).done);r=!0){var u=i.value;e.next(u)}}catch(e){n=!0,o=e}finally{try{!r&&s.return&&s.return()}finally{if(n)throw o}}return e.complete(),{unsubscribe:function(){}}})},fromPromise=function(e){return new Observable_2(function(t){return e.then(function(e){return t.next(e)}).then(function(){return t.complete()}).catch(function(e){return t.error(e)}),{unsubscribe:function(){}}})},toObservable=function(e){return isObservable(e)?e:point(e)},startWith=curry(function(e,t){return new Observable_2(function(r){return r.next(e),t.subscribe(r)})}),Nothing="Nothing",combineLatest=function(){for(var e=arguments.length,t=Array(e),r=0;r<e;r++)t[r]=arguments[r];var n=init(t),o=last(t);return new Observable_2(function(e){var t=n.map(function(){return Nothing}),r=n.map(function(){return!0}),i=n.map(function(n,i){return n.subscribe({error:function(t){console.error(t),r[i]=!1,r.every(function(e){return!1===e})&&e.complete()},complete:function(){r[i]=!1,r.every(function(e){return!1===e})&&e.complete()},next:function(r){if(t[i]=r,t.every(function(e){return e!==Nothing})){var n=void 0;try{n=o.apply(void 0,toConsumableArray(t))}catch(e){console.error(e)}e.next(n)}}})});return{unsubscribe:function(){i.forEach(function(e){return e.unsubscribe()})}}})},map=curry(function(e,t){return new Observable_2(function(r){return t.subscribe({error:function(e){return r.error(e)},next:function(t){return r.next(e(t))},complete:function(){return r.complete()}})})}),filter=curry(function(e,t){return new Observable_2(function(r){return t.subscribe({error:function(e){return r.error(e)},next:function(t){e(t)&&r.next(t)},complete:function(){return r.complete()}})})}),switchMap=curry(function(e,t){var r=void 0;return new Observable_2(function(n){var o=t.subscribe({next:function(t){r&&r.unsubscribe(),r=e(t).subscribe({error:function(e){return n.error(e)},next:function(e){return n.next(e)},complete:function(){}})},error:function(e){return n.error(e)},complete:function(){}});return{unsubscribe:function(){r&&r.unsubscribe(),o.unsubscribe()}}})}),sample=curry(function(e,t){var r=Symbol("None");return new Observable_2(function(n){var o=r,i=t.subscribe({next:function(e){o=e},complete:function(){},error:function(e){return n.error(e)}}),s=e.subscribe({next:function(){o!==r&&(n.next(o),o=r)},complete:function(){return n.complete()},error:function(e){return n.error(e)}});return{unsubscribe:function(){i.unsubscribe(),s.unsubscribe()}}})}),all=function(e){return e.length?combineLatest.apply(void 0,toConsumableArray(e).concat([function(){for(var e=arguments.length,t=Array(e),r=0;r<e;r++)t[r]=arguments[r];return t}])):point([])},scan=curry(function(e,t,r){var n=t;return new Observable_2(function(t){return r.subscribe({error:function(e){return t.error(e)},next:function(r){return t.next(function(t){return n=e(n,t)}(r))},complete:function(){return t.complete()}})})}),shareReplay=curry(function(e,t){var r=[],n=void 0,o=[];return new Observable_2(function(i){return r.push(i),1===r.length&&(n=t.subscribe({complete:function(){return r.forEach(function(e){return e.complete()})},error:function(e){return r.forEach(function(t){return t.error(e)})},next:function(t){r.forEach(function(e){return e.next(t)}),o=o.concat(t).slice(Math.max(0,o.length-e+1))}})),o.map(function(e){return i.next(e)}),{unsubscribe:function(){r=r.filter(function(e){return e!==i}),0===i.length&&(n.unsubscribe(),o=[])}}})}),share=shareReplay(0),raf=new Observable_2(function(e){var t=!0;return window.requestAnimationFrame(function r(){t&&(e.next(),window.requestAnimationFrame(r))}),{unsubscribe:function(){t=!1}}}),addOperator=function(e,t,r){e.prototype[t]=r};[{name:"pipe",f:pipe$1},{name:"map",f:map},{name:"filter",f:filter},{name:"scan",f:scan},{name:"startWith",f:startWith},{name:"share",f:share},{name:"shareReplay",f:shareReplay},{name:"sample",f:sample},{name:"switchMap",f:switchMap}].forEach(function(e){var t=e.name,r=e.f;addOperator(Observable_2,t,function(){return r.apply(void 0,arguments)(this)}),addOperator(Subject_2,t,function(){return r.apply(void 0,arguments)(this)})});var noOp=function(){},createDefaultLifecycle=function(){return{mount:noOp,update:noOp,unmount:noOp}},isEmpty=function(e){return 0!==e&&(!e||"string"==typeof e&&!e.trim())},hasContent=function(e){return!e.length||!e.every(isEmpty)},flatten=function e(t){return Array.isArray(t)?all(t.map(compose(startWith(""),e))).pipe(filter(hasContent)):isObservable(t)?switchMap(e)(t):isPromise(t)?switchMap(e,fromPromise(t)):toObservable(t)},sharedRaf=share(raf),createReactiveTag=function(e){return function(t){for(var r=arguments.length,n=Array(r>1?r-1:0),o=1;o<r;o++)n[o-1]=arguments[o];return flatten(n).pipe(startWith([]),sample(sharedRaf),map(function(r){return e.apply(void 0,[t].concat(toConsumableArray(r)))}))}};function _objectEntries(e){for(var t=[],r=Object.keys(e),n=0;n<r.length;++n)t.push([r[n],e[r[n]]]);return t}function _objectEntries(e){for(var t=[],r=Object.keys(e),n=0;n<r.length;++n)t.push([r[n],e[r[n]]]);return t}function updateStyle(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};for(var n in _extends({},t,r)){var o=r&&r[n]?r[n]:"";r[n]===t[n]||("-"===n[0]?e.style.setProperty(n,o):e.style[n]=o)}}var VNode=function(){function e(t){var r=t.name,n=t.attrs,o=void 0===n?{}:n,i=t.lifecycle,s=void 0===i?{}:i,u=t.events,c=void 0===u?{}:u,a=t.children,l=void 0===a?{}:a,b=t.key,p=void 0===b?"":b;classCallCheck(this,e),this.name=r,this.attrs=o,this.lifecycle=s,this.events=c,this.children=l,this.key=p}return createClass(e,[{key:"createElement",value:function(e,t){var r=(e=e||"svg"===this.name)?document.createElementNS("http://www.w3.org/2000/svg",this.name):document.createElement(this.name);return this.updateEvents(r,{}),this.updateAttrs(r,{}),this.updateChildren(r,[],e,t),r}},{key:"updateElement",value:function(e,t,r,n){if(t.name!==this.name)return t.removeElement(e),this.createElement(r,n);this.updateEvents(e,t.events),this.updateAttrs(e,t.attrs),this.updateChildren(e,t.children,r,n),this.lifecycle.update(e)}},{key:"removeElement",value:function(e){this.children.map(function(t,r){return t.removeElement(e.childNodes[r])}),this.lifecycle.unmount(e)}},{key:"mount",value:function(e){this.children.map(function(e){return e.mount()}),this.lifecycle.mount(e)}},{key:"updateEvents",value:function(e,t){var r=this,n=!0,o=!1,i=void 0;try{for(var s,u=_objectEntries(this.events)[Symbol.iterator]();!(n=(s=u.next()).done);n=!0){var c=s.value,a=slicedToArray(c,2),l=a[0],b=a[1];t[l]?b!==t[l]&&(e.removeEventListener(l,t[l]),e.addEventListener(l,b)):e.addEventListener(l,b)}}catch(e){o=!0,i=e}finally{try{!n&&u.return&&u.return()}finally{if(o)throw i}}var p=_objectEntries(t).filter(function(e){var t=slicedToArray(e,1)[0];return!r.events[t]}),f=!0,h=!1,y=void 0;try{for(var v,d=p[Symbol.iterator]();!(f=(v=d.next()).done);f=!0){var m=v.value,_=slicedToArray(m,2),S=_[0],x=_[1];e.removeEventListener(S,x)}}catch(e){h=!0,y=e}finally{try{!f&&d.return&&d.return()}finally{if(h)throw y}}}},{key:"updateAttrs",value:function(e,t){for(var r in _extends({},t,this.attrs)){var n=this.attrs[r];n===t[r]||(isEmpty(n)?"value"===r&&"INPUT"===e.tagName?e.value="":e.removeAttribute(r):"style"===r?updateStyle(e,t.style,this.attrs.style):"value"===r&&"INPUT"===e.tagName?e.value=n:e.setAttribute(r,n))}}},{key:"updateChildren",value:function(e,t,r,n){for(var o in this.children){var i=this.children[o],s=t[o],u=e.childNodes[o];if(u)n(u,s,i,r);else{var c=i.createElement(r,n);e.appendChild(c),i.mount(c)}}for(var a in[].slice.call(e.childNodes,this.children.length)){var l=parseInt(a)+this.children.length,b=t[l],p=e.childNodes[l];p&&(b.removeElement(p),p.remove())}}}]),e}(),VText=function(){function e(t){var r=t.text;classCallCheck(this,e),this.text=r}return createClass(e,[{key:"createElement",value:function(){return document.createTextNode(this.text)}},{key:"updateElement",value:function(e,t){t.text!==this.text&&(e.textContent=this.text)}},{key:"removeElement",value:function(){}},{key:"mount",value:function(){}}]),e}();function createVTree(e){return new VNode({name:e.nodeName.toLowerCase(),lifecycle:createDefaultLifecycle(),events:{},attrs:{},untouchedAttributes:{},children:Array.prototype.map.call(e.childNodes,function(e){return 3===e.nodeType?new VText({text:e.nodeValue}):createVTree(e)})})}function patch(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:createVTree(e),r=arguments[2],n=arguments[3];if(r.constructor!==t.constructor||r.key!==t.key){t.removeElement(e);var o=r.createElement(n,patch);return e.parentNode.replaceChild(o,e),r.mount(o),o}var i=r.updateElement(e,t,n,patch);return i?(e.parentNode.replaceChild(i,e),r.mount(i),i):e}function createPropsStream(e){var t=new Subject_2;return{next:function(e){return t.next(e)},stream:t.startWith(e).shareReplay(1)}}var Component=function(){function e(t){var r=t.name,n=t.untouchedAttributes,o=t.key,i=void 0===o?"":o;classCallCheck(this,e),this.name=r,this.untouchedAttributes=n,this.key=i}return createClass(e,[{key:"createElement",value:function(e,t){var r=this,n=e?document.createElementNS("g"):document.createElement("div");this.state={},this.state.props=createPropsStream(this.untouchedAttributes),this.state.childTree=void 0;var o=this.name(this.state.props.stream);if(!o)throw new Error("Component "+this.name.name+" must return a stream!");return this.state.subscription=o.pipe(flatten,sample(sharedRaf)).subscribe({next:function(o){n=t(n,r.state.childTree,o,e),r.state.childTree=o},error:function(e){return console.error(e)}}),n}},{key:"updateElement",value:function(e,t,r,n){if(t.name!==this.name)return t.removeElement(e),this.createElement(r,n);this.state=t.state,this.state.props.next(this.untouchedAttributes)}},{key:"removeElement",value:function(e){this.state.subscription.unsubscribe(),this.state.childTree&&this.state.childTree.removeElement(e)}},{key:"mount",value:function(){}}]),e}();function _objectEntries$1(e){for(var t=[],r=Object.keys(e),n=0;n<r.length;++n)t.push([r[n],e[r[n]]]);return t}function _objectEntries$1(e){for(var t=[],r=Object.keys(e),n=0;n<r.length;++n)t.push([r[n],e[r[n]]]);return t}var isLifecycle=function(e){return["mount","update","unmount"].includes(e)},isEvent=function(e){return!!e.match(/^on/)},toEventName=function(e){return e.replace(/^on/,"").toLowerCase()},styleToObject=function(e){return e.split(";").reduce(function(e,t){var r=t.split(/:/),n=toArray(r),o=n[0],i=n.slice(1);return o.trim()&&(e[o.trim()]=i.join(":")),e},{})},formatChildren=flatMap(function(e){return Array.isArray(e)?formatChildren(e):[VNode,VText,Component].some(function(t){return e instanceof t})?[e]:isEmpty(e)?[]:[new VText({text:""+e})]});function h(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[];if("function"==typeof e)return new Component({name:e,untouchedAttributes:_extends({},t,{children:r})});var n=_objectEntries$1(t).reduce(function(e,t){var r=slicedToArray(t,2),n=r[0],o=r[1];return"key"===n?e.key=o:isLifecycle(n)&&"function"==typeof o?e.lifecycle[n]=o:isEvent(n)&&"function"==typeof o?e.events[toEventName(n)]=o:e.attrs[n]="style"===n?"object"===(void 0===o?"undefined":_typeof(o))?o:styleToObject(o):o,e},{lifecycle:createDefaultLifecycle(),events:{},attrs:{}}),o=n.key,i=n.lifecycle,s=n.events,u=n.attrs;return new VNode({name:e,attrs:u,lifecycle:i,events:s,children:formatChildren(r),key:o})}var render=function(e,t){var r=void 0,n=void 0;return e.subscribe({next:function(e){r?(patch(r,n,e),n=e):(r=e.createElement(!1,patch),t.appendChild(r))}})},html$1=createReactiveTag(createTag(h)),textTag=function(e){for(var t=arguments.length,r=Array(t>1?t-1:0),n=1;n<t;n++)r[n-1]=arguments[n];return e.reduce(function(e,t,n){return e+t+(void 0!==r[n]?r[n]:"")},"")},text=createReactiveTag(textTag),defaultSecondPerFrame=.016,reusedTuple=[0,0];function stepper(e,t,r){var n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:170,o=arguments.length>4&&void 0!==arguments[4]?arguments[4]:20,i=arguments.length>5&&void 0!==arguments[5]?arguments[5]:defaultSecondPerFrame,s=arguments.length>6&&void 0!==arguments[6]?arguments[6]:.1,u=t+(-n*(e-r)+-o*t)*i,c=e+u*i;return Math.abs(u)<s&&Math.abs(c-r)<s?(reusedTuple[0]=r,reusedTuple[1]=0,reusedTuple):(reusedTuple[0]=c,reusedTuple[1]=u,reusedTuple)}var ease=function(e,t){var r=void 0,n=0,o=void 0;return function(i){return o=i,void 0===r&&(r=i),new Observable_2(function(i){var s=!0,u=rafThrottle(function(){var c=stepper(r,n,o,e,t),a=slicedToArray(c,2);r=a[0],n=a[1],i.next(r),0!==n&&s&&u()});return u(),{unsubscribe:function(){s=!1}}})}},cache=new Map,getEase=function(e,t,r){return void 0===r?ease(e,t):(cache.has(r)||cache.set(r,ease(e,t)),cache.get(r))},mapValues=curry(function(e,t){return Object.keys(t).reduce(function(r,n){return _extends({},r,defineProperty({},n,e(t[n],n)))},{})}),createMutable=function(e){var t=new Subject_2,r=t.pipe(scan(function(e,t){return t(e)},e),startWith(e),shareReplay(1));return r.set=function(e){return t.next("function"==typeof e?e:function(){return e})},r};function createState(e){return mapValues(createMutable,e)}exports.default=html$1,exports.text=text,exports.render=render,exports.ease=getEase,exports.createState=createState,exports.all=all; |
{ | ||
"name": "evolui", | ||
"version": "1.3.0", | ||
"version": "1.4.0", | ||
"description": "", | ||
@@ -8,3 +8,4 @@ "main": "lib/evolui.js", | ||
"clean": "rimraf lib", | ||
"build": "npm run clean && rollup --config rollup.config.js", | ||
"build": | ||
"npm run clean && BABEL_ENV=production rollup --config rollup.config.js", | ||
"prepare": "npm run clean && npm run build", | ||
@@ -26,4 +27,4 @@ "test": "jest" | ||
"eslint-plugin-prettier": "^2.6.0", | ||
"hyperx": "^2.3.3", | ||
"jest": "^22.4.2", | ||
"prettier": "^1.12.1", | ||
"rimraf": "^2.6.2", | ||
@@ -35,4 +36,5 @@ "rollup": "^0.51.7", | ||
"rollup-plugin-uglify": "^3.0.0", | ||
"rxjs": "^5.5.7" | ||
"rxjs": "^5.5.7", | ||
"vdom-tag": "^0.1.1" | ||
} | ||
} |
162
README.md
# evolui | ||
A `8kb` template library that magically understands Promises and Observables. | ||
A `8kb` reactive user interface library. | ||
Evolui takes care of refreshing your UI when promises and observables emit new values. | ||
Evolui magically understands Observable and Promises and takes care of refreshing your UI when they emit new values. | ||
You can only care about where the data should be displayed. | ||
⚠️ this is experimental! ⚠️ | ||
## Get it | ||
``` | ||
npm install --save evolui | ||
npm install evolui | ||
``` | ||
## Promises | ||
### Promises | ||
@@ -34,3 +32,3 @@ ```js | ||
## Observables | ||
### Observables | ||
@@ -59,5 +57,10 @@ ```js | ||
Observables are a great way to represent values that change over time. The hard part though is combining them and managing subscriptions. This is where evolui comes in handy. Evolui understand **any** combination of `Array`s, `Promise`s and `Observable`s, so you never have to worry on the way you should combine them before putting them inside your template. | ||
Observables are a great way to represent values that change over time. The hard part though is combining them. This is where evolui comes in handy. It understands **any** combination of `Array`s, `Promise`s and `Observable`s, so you never have to worry about the way you should combine them before putting them inside your template. | ||
```js | ||
const getCharacterName = id => | ||
fetch(`https://swapi.co/api/people/${id}`) | ||
.then(res => res.json()) | ||
.then(character => character.name) | ||
html` | ||
@@ -69,7 +72,5 @@ <div> | ||
id => html` | ||
<h1>${Observable.fromPromise( | ||
fetch(`https://swapi.co/api/people/${id}`) | ||
.then(res => res.json()) | ||
.then(character => character.name) | ||
).startWith('Loading...')}</h1> | ||
<h1>${Observable.fromPromise(getCharacterName(id)).startWith( | ||
'Loading...' | ||
)}</h1> | ||
` | ||
@@ -83,2 +84,43 @@ )} | ||
## Components | ||
Evolui lets you organize your code in components. | ||
Components are defined as a simple function of `Observable Props -> Observable VirtualDOM`: | ||
```js | ||
import html, { createState, render } from 'evolui' | ||
const Button = props$ => | ||
props$.map( | ||
({ text, onClick }) => html` | ||
<button class="Button" onClick=${onClick}> | ||
${text} | ||
</button> | ||
` | ||
) | ||
const App = () => { | ||
const state = createState({ count: 0 }) | ||
return html` | ||
<div> | ||
<${Button} | ||
text="-" | ||
onClick=${() => state.count.set(c => c - 1)} | ||
/> | ||
count: ${state.count} | ||
<${Button} | ||
text="+" | ||
onClick=${() => state.count.set(c => c + 1)} | ||
/> | ||
</div> | ||
` | ||
} | ||
render(App(), document.body) | ||
``` | ||
## Animations | ||
@@ -122,4 +164,96 @@ | ||
## API | ||
#### text :: TemplateLiteral -> Observable String | ||
```js | ||
import { text } from 'evolui' | ||
const style$ = text` | ||
position: absolute; | ||
transform: translate(${x$}px, ${y$}px); | ||
` | ||
``` | ||
#### html :: TemplateLiteral -> Observable VirtualDOM | ||
```js | ||
import html from 'evolui' | ||
const App = () => html` | ||
<div style="${style$};" /> | ||
` | ||
``` | ||
#### render :: Observable VirtualDOM -> DOMNode -> () | ||
```js | ||
import { render } from 'evolui' | ||
render(App(), document.body) | ||
``` | ||
### ease :: (Number, Number) -> Observable Number -> Observable Number | ||
```js | ||
import { ease } from 'evolui' | ||
import { Observable } from 'rxjs' | ||
Observable.interval(1000) | ||
.switchMap(ease(120, 20)) | ||
.forEach(x => console.log(x)) // every values will be interpolated | ||
``` | ||
### createState :: Object -> State | ||
```js | ||
import html, { createState, render } from 'evolui' | ||
const App = () => { | ||
const state = createState({ count: 0 }) | ||
return html` | ||
<button onClick=${() => state.count.set(c => c + 1)}> | ||
you clicked ${state.count} times! | ||
</button> | ||
` | ||
} | ||
render(App(), document.body) | ||
``` | ||
Each key on your initial state will be transformed into a stream, with a special `set` method on it. | ||
`set` can take either a value or a mapper function. | ||
```js | ||
const state = createState({ count: 0 }) | ||
const reset = () => state.count.set(0) | ||
const add1 = () => state.count.set(c => c + 1) | ||
``` | ||
### all :: [Observable a] -> Observable [a] | ||
```js | ||
import { all } from 'evolui' | ||
const z$ = all([x$, y$]).map(([x, y]) => x + y) | ||
``` | ||
### Lifecycle | ||
* **mount** — after the element as been rendered | ||
* **update** — after the dom element as been update | ||
* **unmount** — before the dom element is removed from the dom | ||
```js | ||
html` | ||
<div | ||
mount="${el => console.log('mounted!', el)}" | ||
update="${el => console.log('updated', el)}" | ||
unmount="${el => console.log('will unmount!', el)}" /> | ||
` | ||
``` | ||
## More examples | ||
* All examples [Demo](https://7yv1494p9x.codesandbox.io/) — [see code](https://codesandbox.io/s/github/gvergnaud/evolui/tree/master/example) | ||
* Simple Animation [Demo](https://72wkn61x21.codesandbox.io/) — [see code](https://codesandbox.io/s/72wkn61x21) | ||
@@ -129,3 +263,3 @@ * Complexe Animation [Demo](https://31z431n4m.codesandbox.io/) — [see code](https://codesandbox.io/s/31z431n4m) | ||
**To see more example, visite the [`example`](https://github.com/gvergnaud/evolui/tree/master/example) folder.** | ||
**To jump to the code, visite the [`example`](https://github.com/gvergnaud/evolui/tree/master/example) folder.** | ||
@@ -132,0 +266,0 @@ ## Contributing |
@@ -1,12 +0,5 @@ | ||
import Observable from './Observable' | ||
import { | ||
createOperators, | ||
isObservable, | ||
isPromise, | ||
pipe, | ||
compose, | ||
createRaf | ||
} from './utils' | ||
const { | ||
map, | ||
raf, | ||
startWith, | ||
@@ -16,9 +9,14 @@ fromPromise, | ||
all, | ||
map, | ||
filter, | ||
switchMap, | ||
sample, | ||
share | ||
} = createOperators(Observable) | ||
} from './utils/observables' | ||
const raf = share(createRaf(Observable)) | ||
import { isEmpty } from './utils/misc' | ||
import { compose } from './utils/functions' | ||
const hasContent = xs => !xs.length || !xs.every(isEmpty) | ||
// data Variable a | ||
@@ -30,12 +28,16 @@ // = a | ||
// toAStream :: Variable a -> Observable a | ||
const toAStream = variable => | ||
// flatten :: Variable a -> Observable a | ||
export const flatten = variable => | ||
Array.isArray(variable) | ||
? all(variable.map(toAStream).map(startWith(''))) | ||
? all(variable.map(compose(startWith(''), flatten))).pipe( | ||
filter(hasContent) | ||
) | ||
: isObservable(variable) | ||
? switchMap(toAStream)(variable) | ||
? switchMap(flatten)(variable) | ||
: isPromise(variable) | ||
? compose(switchMap(toAStream), fromPromise)(variable) | ||
? switchMap(flatten, fromPromise(variable)) | ||
: toObservable(variable) | ||
export const sharedRaf = share(raf) | ||
// createReactiveTag | ||
@@ -47,7 +49,6 @@ // :: ([String] -> ...[Variable a] -> b) | ||
export const createReactiveTag = tagFunction => (strings, ...variables) => | ||
pipe( | ||
toAStream, | ||
flatten(variables).pipe( | ||
startWith([]), | ||
sample(raf), | ||
sample(sharedRaf), | ||
map(variables => tagFunction(strings, ...variables)) | ||
)(variables) | ||
) |
@@ -1,2 +0,3 @@ | ||
import Observable from './Observable' | ||
import { Observable } from './utils/observables' | ||
import { rafThrottle } from './utils/functions' | ||
@@ -47,17 +48,2 @@ const defaultSecondPerFrame = 0.016 | ||
const rafThrottle = f => { | ||
var shouldExecute = true | ||
let args = [] | ||
return (..._args) => { | ||
args = _args | ||
if (!shouldExecute) return | ||
shouldExecute = false | ||
window.requestAnimationFrame(() => { | ||
shouldExecute = true | ||
f(...args) | ||
}) | ||
} | ||
} | ||
const ease = (stiffness, damping) => { | ||
@@ -64,0 +50,0 @@ let value |
@@ -1,19 +0,8 @@ | ||
import { flatMap, isEmpty } from '../utils' | ||
import VNode from './VNode' | ||
import VText from './VText' | ||
import Component from './Component' | ||
export class VNode { | ||
constructor({ name, attrs, lifecycle, events, children }) { | ||
this.name = name | ||
this.attrs = attrs | ||
this.lifecycle = lifecycle | ||
this.events = events | ||
this.children = children | ||
} | ||
} | ||
import { flatMap } from '../utils/arrays' | ||
import { isEmpty, createDefaultLifecycle } from '../utils/misc' | ||
export class VText { | ||
constructor({ text }) { | ||
this.text = text | ||
} | ||
} | ||
const isLifecycle = key => ['mount', 'update', 'unmount'].includes(key) | ||
@@ -33,12 +22,23 @@ const isEvent = key => !!key.match(/^on/) | ||
Array.isArray(c) | ||
? c | ||
: c instanceof VNode || c instanceof VText | ||
? formatChildren(c) | ||
: [VNode, VText, Component].some(C => c instanceof C) | ||
? [c] | ||
: isEmpty(c) ? [] : [new VText({ text: `${c}` })] | ||
: isEmpty(c) | ||
? [] | ||
: [new VText({ text: `${c}` })] | ||
) | ||
export default function h(name, attributes = {}, children = []) { | ||
const { lifecycle, events, attrs } = Object.entries(attributes).reduce( | ||
if (typeof name === 'function') { | ||
return new Component({ | ||
name, | ||
untouchedAttributes: { ...attributes, children } | ||
}) | ||
} | ||
const { key, lifecycle, events, attrs } = Object.entries(attributes).reduce( | ||
(acc, [key, value]) => { | ||
if (isLifecycle(key) && typeof value === 'function') { | ||
if (key === 'key') { | ||
acc.key = value | ||
} else if (isLifecycle(key) && typeof value === 'function') { | ||
acc.lifecycle[key] = value | ||
@@ -55,3 +55,3 @@ } else if (isEvent(key) && typeof value === 'function') { | ||
}, | ||
{ lifecycle: {}, events: {}, attrs: {} } | ||
{ lifecycle: createDefaultLifecycle(), events: {}, attrs: {} } | ||
) | ||
@@ -64,4 +64,5 @@ | ||
events, | ||
children: formatChildren(children) | ||
children: formatChildren(children), | ||
key | ||
}) | ||
} |
@@ -1,24 +0,20 @@ | ||
import hyperx from 'hyperx' | ||
import h, { VNode } from './h' | ||
import patch, { createElement } from './patch' | ||
import Observable from '../Observable' | ||
import createTag from 'vdom-tag' | ||
import { createReactiveTag } from '../core' | ||
import patch from './patch' | ||
import h from './h' | ||
const hx = hyperx(h, { attrToProp: false }) | ||
// type Tag a b = [String] -> ...[a] -> b | ||
// htmlTag :: Tag a VirtualDOM | ||
const htmlTag = hx | ||
// render :: Observable VirtualDOM -> DOMElement -> Promise Error () | ||
const render = (component, element) => { | ||
let rootNode | ||
let previousTree | ||
return component.forEach(newTree => { | ||
if (!rootNode) { | ||
rootNode = createElement(newTree) | ||
element.appendChild(rootNode) | ||
} else { | ||
patch(rootNode, newTree) | ||
return component.subscribe({ | ||
next: vTree => { | ||
if (!rootNode) { | ||
rootNode = vTree.createElement(false, patch) | ||
element.appendChild(rootNode) | ||
} else { | ||
patch(rootNode, previousTree, vTree) | ||
previousTree = vTree | ||
} | ||
} | ||
@@ -28,39 +24,5 @@ }) | ||
const createRenderProcess = vdom$ => | ||
new Observable(observer => { | ||
let domNode | ||
let tree | ||
return vdom$.subscribe({ | ||
complete: () => observer.complete(), | ||
error: e => observer.error(e), | ||
next: newTree => { | ||
if (!(newTree instanceof VNode)) return observer.next(newTree) | ||
tree = newTree | ||
const onMount = newTree.lifecycle.mount | ||
tree.lifecycle.mount = node => { | ||
domNode = node | ||
if (onMount) onMount(node) | ||
} | ||
tree.lifecycle.render = node => { | ||
domNode = node | ||
patch(domNode, tree) | ||
} | ||
if (!domNode) observer.next(tree) | ||
else patch(domNode, tree) | ||
} | ||
}) | ||
}) | ||
// toComponent :: Tag a (Observable VirtalDOM) -> Tag a Component | ||
const toComponent = tag => (strings, ...variables) => | ||
createRenderProcess(tag(strings, ...variables)) | ||
// html :: [String] -> ...[Variable a] -> Observable VirtualDOM | ||
const html = toComponent(createReactiveTag(htmlTag)) | ||
const html = createReactiveTag(createTag(h)) | ||
export { html, render } |
@@ -1,143 +0,13 @@ | ||
import { isEmpty } from '../utils' | ||
import { VNode, VText } from './h' | ||
import { createDefaultLifecycle } from '../utils/misc' | ||
const vTreeKey = Symbol('vTree') | ||
import VNode from './VNode' | ||
import VText from './VText' | ||
function updateEvents(node, previousEvents, nextEvents) { | ||
for (const [eventName, handler] of Object.entries(nextEvents)) { | ||
if (!previousEvents[eventName]) { | ||
node.addEventListener(eventName, handler) | ||
} else if (handler !== previousEvents[eventName]) { | ||
node.removeEventListener(eventName, previousEvents[eventName]) | ||
node.addEventListener(eventName, handler) | ||
} | ||
} | ||
const removedEventsEntries = Object.entries(previousEvents).filter( | ||
([key]) => !nextEvents[key] | ||
) | ||
for (const [eventName, handler] of removedEventsEntries) { | ||
node.removeEventListener(eventName, handler) | ||
} | ||
} | ||
function updateStyle(node, previousStyle = {}, nextStyle = {}) { | ||
for (const key in { ...previousStyle, ...nextStyle }) { | ||
const style = !nextStyle || !nextStyle[key] ? '' : nextStyle[key] | ||
if (nextStyle[key] === previousStyle[key]) { | ||
// no update needed | ||
} else if (key[0] === '-') { | ||
node.style.setProperty(key, style) | ||
} else { | ||
node.style[key] = style | ||
} | ||
} | ||
} | ||
function updateAttrs(node, previousAttrs, nextAttrs) { | ||
for (const attrName in { ...previousAttrs, ...nextAttrs }) { | ||
const attrValue = nextAttrs[attrName] | ||
if (attrValue === previousAttrs[attrName]) { | ||
// no update needed | ||
} else if (!isEmpty(attrValue)) { | ||
if (attrName === 'style') { | ||
updateStyle(node, previousAttrs.style, nextAttrs.style) | ||
} else if (attrName === 'value' && node.tagName === 'INPUT') { | ||
node.value = attrValue | ||
} else { | ||
node.setAttribute(attrName, attrValue) | ||
} | ||
} else { | ||
if (attrName === 'value' && node.tagName === 'INPUT') { | ||
node.value = '' | ||
} else { | ||
node.removeAttribute(attrName) | ||
} | ||
} | ||
} | ||
} | ||
function updateChildren(node, nextChildren, isSvg) { | ||
for (const index in nextChildren) { | ||
const childTree = nextChildren[index] | ||
const previousChildNode = node.childNodes[index] | ||
if (isEmpty(childTree)) { | ||
} else if (!previousChildNode) { | ||
node.appendChild(createElement(childTree, isSvg)) | ||
} else { | ||
if (childTree instanceof VNode && childTree.lifecycle.render) { | ||
childTree.lifecycle.render(previousChildNode, childTree) | ||
} else { | ||
updateElement(previousChildNode, childTree, isSvg) | ||
} | ||
} | ||
} | ||
for (const childNode of [].slice.call(node.childNodes, nextChildren.length)) { | ||
removeElement(childNode) | ||
} | ||
} | ||
export function createElement(vTree, isSvg) { | ||
if (vTree instanceof VText) { | ||
const node = document.createTextNode(vTree.text) | ||
node[vTreeKey] = vTree | ||
return node | ||
} else { | ||
const node = (isSvg = isSvg || vTree.name === 'svg') | ||
? document.createElementNS('http://www.w3.org/2000/svg', vTree.name) | ||
: document.createElement(vTree.name) | ||
updateEvents(node, {}, vTree.events) | ||
updateAttrs(node, {}, vTree.attrs) | ||
updateChildren(node, vTree.children, isSvg) | ||
if (vTree.lifecycle.mount) vTree.lifecycle.mount(node) | ||
node[vTreeKey] = vTree | ||
return node | ||
} | ||
} | ||
export function updateElement(node, vTree, isSvg) { | ||
const previousTree = node[vTreeKey] | ||
if (vTree instanceof VText) { | ||
if (previousTree.text !== vTree.text) node.textContent = vTree.text | ||
node[vTreeKey] = vTree | ||
} else { | ||
if (previousTree.name !== vTree.name) { | ||
if (previousTree.lifecycle.unmount) previousTree.lifecycle.unmount(node) | ||
node.parentNode.replaceChild(createElement(vTree), node) | ||
} else { | ||
updateEvents(node, previousTree.events, vTree.events) | ||
updateAttrs(node, previousTree.attrs, vTree.attrs) | ||
updateChildren(node, vTree.children, isSvg) | ||
if (vTree.lifecycle.update) vTree.lifecycle.update(node) | ||
node[vTreeKey] = vTree | ||
} | ||
} | ||
return node | ||
} | ||
function removeElement(node) { | ||
if (node[vTreeKey] instanceof VNode && node[vTreeKey].lifecycle.unmount) { | ||
node[vTreeKey].lifecycle.unmount(node) | ||
} | ||
node.remove() | ||
} | ||
function createVTree(node) { | ||
return new VNode({ | ||
name: node.nodeName.toLowerCase(), | ||
lifecycle: {}, | ||
lifecycle: createDefaultLifecycle(), | ||
events: {}, | ||
attrs: {}, | ||
untouchedAttributes: {}, | ||
children: Array.prototype.map.call( | ||
@@ -153,8 +23,27 @@ node.childNodes, | ||
export default function patch(node, vTree) { | ||
if (!node[vTreeKey]) { | ||
node[vTreeKey] = createVTree(node) | ||
export default function patch( | ||
node, | ||
previousTree = createVTree(node), | ||
vTree, | ||
isSvg | ||
) { | ||
if ( | ||
vTree.constructor !== previousTree.constructor || | ||
vTree.key !== previousTree.key | ||
) { | ||
previousTree.removeElement(node) | ||
const newNode = vTree.createElement(isSvg, patch) | ||
node.parentNode.replaceChild(newNode, node) | ||
vTree.mount(newNode) | ||
return newNode | ||
} else { | ||
const newNode = vTree.updateElement(node, previousTree, isSvg, patch) | ||
if (newNode) { | ||
node.parentNode.replaceChild(newNode, node) | ||
vTree.mount(newNode) | ||
return newNode | ||
} else { | ||
return node | ||
} | ||
} | ||
return updateElement(node, vTree) | ||
} |
import { html, render } from './html' | ||
import { text } from './text' | ||
import ease from './ease' | ||
import createState from './createState' | ||
import { all } from './utils/observables' | ||
export default html | ||
export { ease, text, render } | ||
export { text, render, ease, createState, all } |
@@ -1,5 +0,8 @@ | ||
import h, { VNode, VText } from '../../src/html/h' | ||
import hyperx from 'hyperx' | ||
import h from '../../src/html/h' | ||
import VNode from '../../src/html/VNode' | ||
import VText from '../../src/html/VText' | ||
import createTag from 'vdom-tag' | ||
import { createDefaultLifecycle } from '../../src/utils/misc' | ||
const html = hyperx(h) | ||
const html = createTag(h) | ||
@@ -12,3 +15,3 @@ describe('h', () => { | ||
attrs: {}, | ||
lifecycle: {}, | ||
lifecycle: createDefaultLifecycle(), | ||
events: {}, | ||
@@ -30,16 +33,16 @@ children: [] | ||
new VNode({ | ||
attrs: { className: 'User' }, | ||
attrs: { class: 'User' }, | ||
children: [ | ||
new VNode({ | ||
attrs: { className: 'User-image', src: '/path/to/img.jpg' }, | ||
attrs: { class: 'User-image', src: '/path/to/img.jpg' }, | ||
children: [], | ||
events: {}, | ||
lifecycle: {}, | ||
lifecycle: createDefaultLifecycle(), | ||
name: 'img' | ||
}), | ||
new VNode({ | ||
attrs: { className: 'User-name' }, | ||
attrs: { class: 'User-name' }, | ||
children: [new VText({ text: 'Toto' })], | ||
events: {}, | ||
lifecycle: {}, | ||
lifecycle: createDefaultLifecycle(), | ||
name: 'h1' | ||
@@ -49,3 +52,3 @@ }) | ||
events: {}, | ||
lifecycle: {}, | ||
lifecycle: createDefaultLifecycle(), | ||
name: 'div' | ||
@@ -66,3 +69,3 @@ }) | ||
new VNode({ | ||
attrs: { className: 'User' }, | ||
attrs: { class: 'User' }, | ||
children: [], | ||
@@ -73,3 +76,3 @@ events: { | ||
}, | ||
lifecycle: {}, | ||
lifecycle: createDefaultLifecycle(), | ||
name: 'div' | ||
@@ -96,3 +99,3 @@ }) | ||
new VNode({ | ||
attrs: { className: 'User' }, | ||
attrs: { class: 'User' }, | ||
children: [], | ||
@@ -99,0 +102,0 @@ events: {}, |
import h from '../../src/html/h' | ||
import patch, { createElement } from '../../src/html/patch' | ||
import hyperx from 'hyperx' | ||
import patch from '../../src/html/patch' | ||
import createTag from 'vdom-tag' | ||
const html = hyperx(h) | ||
const html = createTag(h) | ||
const createElement = vTree => vTree.createElement(false, patch) | ||
@@ -42,9 +43,9 @@ const getHtml = str => { | ||
patch( | ||
el, | ||
html` | ||
<div class="something" /> | ||
` | ||
) | ||
let vTree | ||
let newVTree = html` | ||
<div class="something" /> | ||
` | ||
patch(el, vTree, newVTree) | ||
expect(el).toEqual( | ||
@@ -56,9 +57,9 @@ getHtml(` | ||
patch( | ||
el, | ||
html` | ||
<div class="something" cool="yes" /> | ||
` | ||
) | ||
vTree = newVTree | ||
newVTree = html` | ||
<div class="something" cool="yes" /> | ||
` | ||
patch(el, vTree, newVTree) | ||
expect(el).toEqual( | ||
@@ -70,9 +71,9 @@ getHtml(` | ||
patch( | ||
el, | ||
html` | ||
<div hello="good" /> | ||
` | ||
) | ||
vTree = newVTree | ||
newVTree = html` | ||
<div hello="good" /> | ||
` | ||
patch(el, vTree, newVTree) | ||
expect(el).toEqual( | ||
@@ -91,2 +92,3 @@ getHtml(` | ||
el, | ||
undefined, | ||
html` | ||
@@ -117,2 +119,3 @@ <div> | ||
el, | ||
undefined, | ||
html` | ||
@@ -133,2 +136,3 @@ <div> | ||
el, | ||
undefined, | ||
html` | ||
@@ -158,32 +162,32 @@ <div> | ||
patch( | ||
el, | ||
html` | ||
<div> | ||
<div | ||
class="User" | ||
unmount="${el => { | ||
expect(el).toEqual( | ||
getHtml(` | ||
<div class="User"></div> | ||
`) | ||
) | ||
unmountWasCalled = true | ||
}}" /> | ||
</div> | ||
` | ||
) | ||
let vTree | ||
let newVTree = html` | ||
<div> | ||
<div | ||
class="User" | ||
unmount="${el => { | ||
expect(el).toEqual( | ||
getHtml(` | ||
<div class="User"></div> | ||
`) | ||
) | ||
unmountWasCalled = true | ||
}}" /> | ||
</div> | ||
` | ||
patch(el, vTree, newVTree) | ||
expect(unmountWasCalled).toBe(false) | ||
patch( | ||
el, | ||
html` | ||
<div> | ||
</div> | ||
` | ||
) | ||
vTree = newVTree | ||
newVTree = html` | ||
<div> | ||
</div> | ||
` | ||
patch(el, vTree, newVTree) | ||
expect(unmountWasCalled).toBe(true) | ||
}) | ||
}) |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
200649
60
4953
263
20
3