Created
February 26, 2018 07:05
-
-
Save naddeoa/31c45bf049e35c526ada982362ff1c29 to your computer and use it in GitHub Desktop.
Hello world for cycle JS. I might be doing something wrong. At this rate, it will end up looking a lot like Elm, but with the complication of streams.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { div, DOMSource, h1, makeDOMDriver, VNode, input } from '@cycle/dom'; | |
import { run } from '@cycle/xstream-run'; | |
import xs, { Stream } from 'xstream'; | |
import SearchBox, { SearchBoxProps } from './SearchBox'; | |
export interface Sources { | |
DOM: DOMSource; | |
} | |
export interface Sinks { | |
DOM: Stream<VNode> | |
} | |
interface Model { | |
search: string | |
searchPending: { | |
[s: string]: boolean | |
} | |
} | |
interface SearchForUser { | |
type: 'SearchForUser' | |
} | |
interface SearchBoxUpdated { | |
type: 'SearchBoxUpdated', | |
value: string | |
} | |
type Actions = SearchForUser | SearchBoxUpdated; | |
function intent(domSource: DOMSource): Stream<Actions> { | |
return xs.merge( | |
domSource.select('.search-box') | |
.events('input') | |
.map((event: Event) => ({ | |
type: 'SearchBoxUpdated', | |
value: ((event.target as any).value as string) | |
} as SearchBoxUpdated)), | |
domSource.select('.search-box') | |
.events('keypress') | |
.map(event => event.keyCode === 13) | |
.filter(result => result === true) | |
.map(e => ({ type: 'SearchForUser' } as SearchForUser)) | |
) | |
} | |
function model(action$: Stream<Actions>): Stream<Model> { | |
const initialModel: Model = { | |
search: '', | |
searchPending: {} | |
}; | |
return action$.fold((model, action) => { | |
switch (action.type) { | |
case 'SearchForUser': | |
return model; | |
case 'SearchBoxUpdated': | |
return Object.assign({}, model, { search: action.value }) | |
} | |
}, initialModel) | |
} | |
function view(model$: Stream<Model>): Stream<VNode> { | |
return model$.map(model => { | |
return div([ | |
h1('Github user search'), | |
input('.search-box', { value: model.search }) | |
]) | |
}) | |
} | |
function main(sources: Sources): Sinks { | |
const action$ = intent(sources.DOM); | |
const state$ = model(action$); | |
return { | |
DOM: view(state$) | |
}; | |
} | |
run(main, { | |
DOM: makeDOMDriver('#main-container') | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment