diff --git a/redux-saga/redux-saga-tests.ts b/redux-saga/redux-saga-tests.ts
new file mode 100644
index 000000000..933a397b1
--- /dev/null
+++ b/redux-saga/redux-saga-tests.ts
@@ -0,0 +1,172 @@
+///
+
+
+import sagaMiddleware, {
+ take,
+ put,
+ race,
+ call,
+ fork,
+ cancel,
+ storeIO,
+ runSaga,
+ Saga,
+ SagaCancellationException
+} from 'redux-saga'
+import {applyMiddleware, createStore} from 'redux';
+
+declare const delay: (ms: number) => Promise;
+declare const fetchApi: (url: string) => Promise;
+
+namespace GettingStarted {
+
+ const incrementAsync:Saga = function* incrementAsync() {
+
+ while(true) {
+
+ // wait for each INCREMENT_ASYNC action
+ const nextAction = yield take('INCREMENT_ASYNC')
+
+ // delay is a sample function
+ // return a Promise that resolves after (ms) milliseconds
+ yield delay(1000)
+
+ // dispatch INCREMENT_COUNTER
+ yield put( {type: 'INCREMENT_COUNTER'} )
+ }
+
+ }
+
+ const createStoreWithSaga = applyMiddleware(
+ // ...,
+ sagaMiddleware(incrementAsync)
+ )(createStore)
+
+ export default function configureStore(initialState) {
+ return createStoreWithSaga((state: any) => state, initialState)
+ }
+}
+
+
+namespace EffectCombinators {
+ const fetchPostsWithTimeout:Saga = function* fetchPostsWithTimeout() {
+ while( yield take('FETCH_POSTS') ) {
+ // starts a race between 2 effects
+ const {posts, timeout} = yield race({
+ posts : call(fetchApi, '/posts'),
+ timeout : call(delay, 1000)
+ })
+
+ if(posts)
+ put( {type: 'RECEIVE_POSTS', posts} )
+ else
+ put( {type: 'TIMEOUT_ERROR'} )
+ }
+ }
+}
+
+
+namespace SequencingSagasViaYield {
+ function showScore(score) {
+ return {
+ type: 'SHOW_SCORE', score
+ }
+ }
+
+ function* playLevelOne(getState) { yield 1 }
+
+ function* playLevelTwo(getState) { yield 2 }
+
+ function* playLevelThree(getState) { yield 3 }
+
+ const game: Saga = function* game(getState) {
+
+ const score1 = yield* playLevelOne(getState)
+ yield put(showScore(score1))
+
+ const score2 = yield* playLevelTwo(getState)
+ yield put(showScore(score2))
+
+ const score3 = yield* playLevelThree(getState)
+ yield put(showScore(score3))
+
+ }
+}
+
+
+namespace ComposingSagas {
+ function* fetchProducts() {
+ yield put( {type: 'REQUEST_PRODUCTS'} )
+ const products = yield call(fetchApi, '/products')
+ yield put( {type: 'RECEIVE_PRODUCTS', products } )
+ }
+
+ function* watchFetch() {
+ while ( yield take('FETCH_PRODUCTS') ) {
+ yield call(fetchProducts) // waits for the fetchProducts task to
+ // terminate
+ }
+ }
+}
+
+
+namespace NonBlockingCallsWithForkJoin {
+ function* fetchPosts() {
+ yield put( {type: 'REQUEST_POSTS'} )
+ const posts = yield call(fetchApi, '/posts')
+ yield put( {type: 'RECEIVE_POSTS', posts} )
+ }
+
+ function* watchFetch() {
+ while ( yield take('FETCH_POSTS') ) {
+ yield fork(fetchPosts) // non blocking call
+ }
+ }
+}
+
+
+namespace TaskCancellation {
+ declare const someApi: () => any;
+
+ function* bgSync() {
+ try {
+ while(true) {
+ yield put({type: 'REQUEST_START'})
+ const result = yield call(someApi)
+ yield put({type: 'REQUEST_SUCCESS', result})
+ yield call(delay, 5000)
+ }
+ } catch(error) {
+ if(error instanceof SagaCancellationException)
+ yield put({type: 'REQUEST_FAILURE', message: 'Sync cancelled!'})
+ }
+ }
+
+ function* main() {
+ while( yield take('START_BACKGROUND_SYNC') ) {
+ // starts the task in the background
+ const bgSyncTask = yield fork(bgSync)
+
+ // wait for the user stop action
+ yield take('STOP_BACKGROUND_SYNC')
+ // user clicked stop. cancel the background task
+ // this will throw a SagaCancellationException into the forked bgSync
+ // task
+ yield cancel(bgSyncTask)
+ }
+ }
+}
+
+
+namespace DynamicallyStartingSagasWithRunSaga {
+ const store = createStore((state: any, action: any) => state);
+
+ function* serverSaga(getState) {
+ yield getState()
+ }
+
+ runSaga(
+ serverSaga(store.getState),
+ storeIO(store)
+ )
+}
diff --git a/redux-saga/redux-saga-tests.ts.tscparams b/redux-saga/redux-saga-tests.ts.tscparams
new file mode 100644
index 000000000..14fce22a5
--- /dev/null
+++ b/redux-saga/redux-saga-tests.ts.tscparams
@@ -0,0 +1 @@
+--target ES6
diff --git a/redux-saga/redux-saga.d.ts b/redux-saga/redux-saga.d.ts
new file mode 100644
index 000000000..6573f1245
--- /dev/null
+++ b/redux-saga/redux-saga.d.ts
@@ -0,0 +1,110 @@
+// Type definitions for redux-saga 0.6.0
+// Project: https://github.com/yelouafi/redux-saga
+// Definitions by: Daniel Lytkin
+// Definitions: https://github.com/borisyankov/DefinitelyTyped
+
+///
+
+declare module 'redux-saga' {
+ export class SagaCancellationException {
+ }
+
+ export type Effect = {};
+
+ export type Saga = (getState?: () => T) => Iterable;
+
+ type Predicate = (action: any) => boolean;
+
+ export function take(pattern?: string|string[]|Predicate): Effect;
+
+ export function put(action: any): Effect;
+
+ export function race(effects: {[key:string]: any}): Effect;
+
+ export function call(fn: (arg1?: T1, arg2?: T2, arg3?: T3, ...rest: any[]) => any,
+ arg1?: T1, arg2?: T2, arg3?: T3, ...rest: any[]): Effect;
+
+
+ export interface Task {
+ name:string;
+ isRunning():boolean;
+ result():T;
+ error():any;
+ }
+
+ export function fork(effect: Effect): Effect;
+ export function fork(fn: (arg1?: T1, arg2?: T2, arg3?: T3, ...rest: any[]) =>
+ Promise|Iterable,
+ arg1?: T1, arg2?: T2, arg3?: T3, ...rest: any[]): Effect;
+
+ export function join(task: Task): Effect;
+
+ export function cancel(task: Task): Effect;
+
+
+ import {Middleware} from 'redux';
+ export default function (...sagas: Saga[]): Middleware;
+
+ export {
+ CANCEL,
+ RACE_AUTO_CANCEL,
+ PARALLEL_AUTO_CANCEL,
+ MANUAL_CANCEL
+ } from 'redux-saga/lib/proc';
+
+ import * as monitorActions from 'redux-saga/lib/monitorActions';
+ export {monitorActions}
+
+ export {runSaga, storeIO} from 'redux-saga/lib/runSaga'
+
+}
+
+
+declare module 'redux-saga/lib/proc' {
+ import {Task} from 'redux-saga';
+
+ export const CANCEL: symbol;
+ export const NOT_ITERATOR_ERROR: string;
+ export const PARALLEL_AUTO_CANCEL: string;
+ export const RACE_AUTO_CANCEL: string;
+ export const MANUAL_CANCEL: string;
+
+ export default function proc(iterator: Iterable,
+ subscribe?: (cb: Function) => Function,
+ dispatch?: (action: any) => any,
+ monitor?: (action: any) => void,
+ parentEffectId?: any,
+ name?: string): Task;
+}
+
+
+declare module 'redux-saga/lib/runSaga' {
+ import {Store} from 'redux';
+ import {Task} from 'redux-saga';
+
+ interface IO {
+ dispatch: (action: any) => any;
+ subscribe: (cb: Function) => Function;
+ }
+
+ export function storeIO(store: Store): IO;
+
+ export function runSaga(iterator: Iterable,
+ io: IO,
+ monitor?: (action: any) => void): Task;
+}
+
+
+declare module 'redux-saga/lib/emitter' {
+ export default function emitter(): {
+ subscribe(cb: Function):Function;
+ emit(item: any):void;
+ }
+}
+
+declare module 'redux-saga/lib/monitorActions' {
+ export const MONITOR_ACTION: string;
+ export const EFFECT_TRIGGERED: string;
+ export const EFFECT_RESOLVED: string;
+ export const EFFECT_REJECTED: string;
+}
diff --git a/redux-saga/redux-saga.d.ts.tscparams b/redux-saga/redux-saga.d.ts.tscparams
new file mode 100644
index 000000000..14fce22a5
--- /dev/null
+++ b/redux-saga/redux-saga.d.ts.tscparams
@@ -0,0 +1 @@
+--target ES6