Skip to content

Instantly share code, notes, and snippets.

@theRemix
Last active September 28, 2017 01:53
Show Gist options
  • Save theRemix/6b78c763a8dc2acf24c11510355555b0 to your computer and use it in GitHub Desktop.
Save theRemix/6b78c763a8dc2acf24c11510355555b0 to your computer and use it in GitHub Desktop.
CycleJS xstream HTTP example
import xs, { Stream } from 'xstream';
import { VNode, DOMSource } from '@cycle/dom';
import { HTTPSource } from '@cycle/http';
import { StateSource } from 'cycle-onionify';
import { Sources, Sinks } from './interfaces';
export type AppSources = Sources & { onion: StateSource<AppState> };
export type AppSinks = Sinks & { onion: Stream<Reducer>, HTTP: Stream<any> };
export type Reducer = (prev: AppState) => AppState;
export type AppState = {
count: number;
items: Array<any>;
};
export function App(sources: AppSources): AppSinks {
const action$: Stream<Reducer> = intent(sources.DOM, sources.HTTP);
const vdom$: Stream<VNode> = view(sources.onion.state$);
const testxhr$: Stream<any> = sources.DOM.select('.getItems')
.events('click')
.map(ev => ({
url: '/api/items',
category: 'items'
}));
return {
DOM: vdom$,
HTTP: testxhr$,
onion: action$
};
}
function intent(DOM: DOMSource, HTTP: HTTPSource): Stream<Reducer> {
const init$: Stream<Reducer> = xs.of<Reducer>(() => ({ count: 0, items: [] }));
const add$: Stream<Reducer> = DOM.select('.add')
.events('click')
.mapTo<Reducer>(state => ({ ...state, count: state.count + 1 }));
const subtract$: Stream<Reducer> = DOM.select('.subtract')
.events('click')
.mapTo<Reducer>(state => ({ ...state, count: state.count - 1 }));
const response$: Stream<Reducer> = HTTP.select('items')
.flatten()
.map(res => res.body)
.startWith([])
.map<Reducer>(items => state => ({ ...state, items }));
return xs.merge(init$, add$, subtract$, response$);
}
function view(state$: Stream<AppState> ): Stream<VNode> {
return state$.map(state =>
<div>
<h2>My Awesome Cycle.js app</h2>
<span>
{'Counter: ' + state.count}
</span>
<button type="button" className="add">
Increase
</button>
<button type="button" className="subtract">
Decrease
</button>
<button type="button" className="getItems">
Get Items
</button>
<p>
<span>
{ 'Items: ' + state.items.join(', ') }
</span>
</p>
</div>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment