A single pipeline of sources to sinks.
const reactions = {
updateFormField: (state) => ({event, form, field}) => {
return mergeDeepRight(state)({
ephemeral: {
forms: {
[form]: {
field: event.target.value
}
}
}
})
},
receiveResults: (state) => ({results}) => {
return mergeDeepRight(state)({
resources: {
results,
}
})
}
}
const intents = {
onChangeSearch: intentOn("change")(["updateFormField", "fetchSearchResult"]),
}
const presentation = (state) => {
const searchWith = onChangeSearch({
form: "search",
field: "query"
})
return main({
children: [
h1({children: "Google"}),
searchWith(input({children: state.ephemeral.forms.search.query})),
p({children: "See below for the results"}),
ul({
children: mapValues((result) => li({children: result.title}))(state.resources.results)
})
]
})
}
const application = (sources) => {
return channel([
viewEventSignals(sources.view),
networkResponseSignals(sources.network),
storageReadSignals(sources.storage),
])({
state: stateFrom(reactions)(initialState),
network: (signals) => ???,
storage: (signals) => ???,
})({
view: ({state}) => presentation(presentation),
network: ({network}) => request(network),
storage: ({storage}) => write(storage)
})
}
const drivers = {
view: makeDOMDriver("body"),
network: makeHTTPDriver(),
storage: makeStorageDriver()
}
run(application, drivers)
Test