CULLI teaser
import * as O from "most" | |
import {run} from "@cycle/most-run" | |
import DOM from "@culli/dom" | |
import Store, {Memory} from "@culli/store" | |
import HTTP from "@culli/http" | |
run(GithubSearch, { | |
DOM: DOM("#app"), | |
// create store using in-memory persintence | |
Store: Store(Memory({q: "", results: []})), | |
HTTP: HTTP("https://github.com/api/v3") | |
}) | |
function GithubSearch(sources) { | |
const {DOM: {h, dom}, Store, HTTP} = sources | |
const {props, dispatch} = model(Store) | |
const vdom = view(props) | |
const actions = intent(vdom) | |
return { | |
DOM: dom(vdom), | |
Store: dispatch(actions) | |
} | |
function model({actions}) { | |
// reduce supports also default (= "initial") value as a second parameter | |
const {state, dispatch} = actions.reduce((state, action) => { | |
switch (action.type) { | |
case "SET_QUERY": | |
return {...state, q: action.payload} | |
case "SET_RESULTS": | |
return {...state, results: action.payload} | |
default: | |
return state | |
} | |
}) | |
return { | |
dispatch, | |
props: { | |
q: state.select("q"), | |
results: state.select("results") | |
} | |
} | |
} | |
function view({q, results}) { | |
const children = results.mapChildren(result => Result({...sources, Store: result})) | |
return h("div", [ | |
h("input.q", {value: q.value, placeholder: "Search GitHub repos..."}), | |
h("hr"), | |
h("ul.results", children.DOM) | |
]) | |
} | |
function intent(vdom) { | |
const textInput = | |
vdom.select(".q") | |
.events("input") | |
.map(e => e.target.value) | |
const resultsFromServer = | |
textInput | |
.debounce(300) | |
.map(query => HTTP.get(makeGitHubSearchParams(query))) | |
.switch() | |
const setQueryActions = | |
textInput.map(query => ({ | |
type: "SET_QUERY", | |
payload: query | |
})) | |
const setResultsActions = | |
resultsFromServer.map(res => ({ | |
type: "SET_RESULTS", | |
// result == {id: <string>, text: <string>} | |
payload: extractResults(res.body) | |
})) | |
return O.merge(setQueryActions, setResultsActions) | |
} | |
} | |
function Result({DOM: {h, dom}, Store: result}) { | |
const vdom = h("li", [ | |
result.select("text").value | |
]) | |
return { | |
DOM: dom(vdom) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment