Skip to content

Instantly share code, notes, and snippets.

@samoshkin
Created July 27, 2016 14:31
Show Gist options
  • Save samoshkin/60c242528826acd0cabc78afe050c3cf to your computer and use it in GitHub Desktop.
Save samoshkin/60c242528826acd0cabc78afe050c3cf to your computer and use it in GitHub Desktop.
Naive implementation of Redux pattern in RxJS
import { OpaqueToken } from '@angular/core';
import { Subject } from 'rxjs/Subject';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/scan';
import 'rxjs/add/operator/observeOn';
import { queue } from 'rxjs/scheduler/queue';
import { ReplaySubject } from 'rxjs/ReplaySubject';
export interface Action {
type: string;
payload?: any;
meta?: {
[key: string]: any
};
}
export interface ActionReducer<T> {
(state: T, action: Action): T;
}
function stateFactory<T>(
dispatcher$: Subject<Action>,
reducer: ActionReducer<T>,
initialState?: T) {
const state = reducer(initialState, { type: '@@INIT' });
const state$ = new ReplaySubject(1);
dispatcher$
.observeOn(queue)
.scan(reducer, state)
.startWith(state)
.subscribe(state$);
return state$;
}
export const state = new OpaqueToken('state');
export const dispatcher = new OpaqueToken('dispatcher');
export function provideStore<TState>(reducer, initialState?: TState) {
return [
{
provide: state,
useFactory: d => stateFactory(d, reducer, initialState),
deps: [dispatcher]
},
{
provide: dispatcher,
useValue: new Subject<Action>()
}
];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment