From ca26076c7ccc02dd9cccc7283c7a3e5d6c4485d8 Mon Sep 17 00:00:00 2001 From: Dimitri Rosenberg Date: Sat, 27 Feb 2016 17:25:40 +0300 Subject: [PATCH 1/2] fit redux-saga 0.9.1 --- redux-saga/redux-saga-tests.ts | 53 ++++++++++++++++++--- redux-saga/redux-saga.d.ts | 86 ++++++++++++++++++++-------------- 2 files changed, 99 insertions(+), 40 deletions(-) diff --git a/redux-saga/redux-saga-tests.ts b/redux-saga/redux-saga-tests.ts index 933a397b19..34f91310b7 100644 --- a/redux-saga/redux-saga-tests.ts +++ b/redux-saga/redux-saga-tests.ts @@ -2,17 +2,25 @@ import sagaMiddleware, { + storeIO, + runSaga, + Saga, + SagaCancellationException, + takeEvery, + takeLatest, + isCancelError +} from 'redux-saga' + +import { take, put, race, call, fork, + select, cancel, - storeIO, - runSaga, - Saga, - SagaCancellationException -} from 'redux-saga' +} from 'redux-saga/effects' + import {applyMiddleware, createStore} from 'redux'; declare const delay: (ms: number) => Promise; @@ -137,7 +145,7 @@ namespace TaskCancellation { yield call(delay, 5000) } } catch(error) { - if(error instanceof SagaCancellationException) + if(error instanceof SagaCancellationException && isCancelError(error)) yield put({type: 'REQUEST_FAILURE', message: 'Sync cancelled!'}) } } @@ -170,3 +178,36 @@ namespace DynamicallyStartingSagasWithRunSaga { storeIO(store) ) } + +namespace DynamicallyStartingSagasWithMiddleware { + function* startupSaga() { + } + + function* dynamicSaga() { + } + + sagaMiddleware(startupSaga).run(dynamicSaga) +} + +namespace TestHelpers { + function* watchAndLog(getState) { + yield* takeEvery('*', function* logger(action) { + console.log('action', action) + }) + } + + function* fetchUser(action) { + } + + function* watchLastFetchUser() { + yield* takeLatest('USER_REQUESTED', fetchUser) + } +} + +namespace AccessCurrentState { + export const getCart = state => state.cart; + + function* checkout() { + const cart = yield select(getCart) + } +} diff --git a/redux-saga/redux-saga.d.ts b/redux-saga/redux-saga.d.ts index 6573f12452..3df94243e0 100644 --- a/redux-saga/redux-saga.d.ts +++ b/redux-saga/redux-saga.d.ts @@ -1,6 +1,6 @@ -// Type definitions for redux-saga 0.6.0 +// Type definitions for redux-saga 0.9.1 // Project: https://github.com/yelouafi/redux-saga -// Definitions by: Daniel Lytkin +// Definitions by: Daniel Lytkin , Dimitri Rosenberg // Definitions: https://github.com/borisyankov/DefinitelyTyped /// @@ -9,41 +9,17 @@ 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; - + export type Predicate = (action: any) => boolean; + export type Pattern = string | string[] | Predicate; import {Middleware} from 'redux'; - export default function (...sagas: Saga[]): Middleware; + + interface SagaMiddleware extends Middleware { + run(saga: Saga, ...args: any[]): void; + } + + export default function (...sagas: Saga[]): SagaMiddleware; export { CANCEL, @@ -57,8 +33,50 @@ declare module 'redux-saga' { export {runSaga, storeIO} from 'redux-saga/lib/runSaga' + export interface Task { + name:string; + isRunning():boolean; + result():T; + error():any; + cancel(): void; + } + + export function takeEvery(pattern: Pattern, saga: Saga, ...args: any[]): { [Symbol.iterator](): IterableIterator }; + + export function takeLatest(pattern: Pattern, saga: Saga, ...args: any[]): { [Symbol.iterator](): IterableIterator }; + + export function isCancelError(e: any): boolean; } +declare module 'redux-saga/effects' { + import {Task} from 'redux-saga'; + import {Predicate} from 'redux-saga'; + import {Pattern} from 'redux-saga'; + + export type Effect = {}; + + + export function take(pattern?: Pattern): 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 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 select(selector?: (state: any, ...args: any[]) => any, ...args: any[]): Effect; + + export function cancel(task: Task): Effect; +} declare module 'redux-saga/lib/proc' { import {Task} from 'redux-saga'; From bd08832e14cd61edc737a5d7793ee10ec130a738 Mon Sep 17 00:00:00 2001 From: Dimitri Rosenberg Date: Sun, 28 Feb 2016 23:57:22 +0300 Subject: [PATCH 2/2] add apply effect creater --- redux-saga/redux-saga-tests.ts | 6 +++--- redux-saga/redux-saga.d.ts | 19 ++++++++++++++----- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/redux-saga/redux-saga-tests.ts b/redux-saga/redux-saga-tests.ts index 34f91310b7..ce05915490 100644 --- a/redux-saga/redux-saga-tests.ts +++ b/redux-saga/redux-saga-tests.ts @@ -16,6 +16,7 @@ import { put, race, call, + apply, fork, select, cancel, @@ -55,13 +56,12 @@ namespace GettingStarted { } } - 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'), + posts : call([this, fetchApi], '/posts'), timeout : call(delay, 1000) }) @@ -140,7 +140,7 @@ namespace TaskCancellation { try { while(true) { yield put({type: 'REQUEST_START'}) - const result = yield call(someApi) + const result = yield apply(this, someApi) yield put({type: 'REQUEST_SUCCESS', result}) yield call(delay, 5000) } diff --git a/redux-saga/redux-saga.d.ts b/redux-saga/redux-saga.d.ts index 3df94243e0..e68a2a2562 100644 --- a/redux-saga/redux-saga.d.ts +++ b/redux-saga/redux-saga.d.ts @@ -55,6 +55,12 @@ declare module 'redux-saga/effects' { export type Effect = {}; + type EffectFunction = (arg1?: T1, arg2?: T2, arg3?: T3, ...rest: any[]) => Promise | Iterable; + + interface EffectFunctionContext { + 0: any; + 1: EffectFunction; + } export function take(pattern?: Pattern): Effect; @@ -62,14 +68,17 @@ declare module 'redux-saga/effects' { 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 function call(fn: EffectFunction, arg1?: T1, arg2?: T2, arg3?: T3, ...rest: any[]): Effect; + export function call(fn: EffectFunctionContext, arg1?: T1, arg2?: T2, arg3?: T3, ...rest: any[]): Effect; + + export function apply(context: any, fn: EffectFunction, arg1?: T1, arg2?: T2, arg3?: T3, ...rest: any[]): Effect; 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 fork(fn: EffectFunction, arg1?: T1, arg2?: T2, arg3?: T3, ...rest: any[]): Effect; + + export function fork(fn: EffectFunctionContext, arg1?: T1, arg2?: T2, arg3?: T3, ...rest: any[]): Effect; export function join(task: Task): Effect;