redux-saga

An alternative side effect model for Redux apps

MIT License

Downloads
25.8M
Stars
22.5K
Committers
363

Bot releases are visible (Hide)

redux-saga -

Published by yelouafi over 8 years ago

This patch fixes #118. The implementation of argument passing to forked tasks in takeEvery/takeLatest didn't match the specs in docs and examples

redux-saga -

Published by yelouafi over 8 years ago

And yet another patch release

  • Added missed utils top level export for utils. So now we can do import redux-saga/utils
redux-saga -

Published by yelouafi over 8 years ago

Features

The release adds 2 helper functions takeEvery and takeLatest to handle the common case concurrency scenarios

For the reasons behind this addition see https://github.com/yelouafi/redux-saga/issues/70#issuecomment-182401477

You can find the docs of the functions here

http://yelouafi.github.io/redux-saga/docs/basics/UsingSagaHelpers.html

http://yelouafi.github.io/redux-saga/docs/advanced/Concurrency.html

http://yelouafi.github.io/redux-saga/docs/api/index.html#saga-helpers

There is a breaking change in this release

The path import for Effects has changed from redux-saga to redux-saga/effects

Before

import {  take, put, call, ... } from 'redux-saga'

After

import {  take, put, call, ... } from 'redux-saga/effects'

Other changes

added a helper function isCancelError to simplify test of Cancellation Exception

Instead of

import { isCancelError } from 'redux-saga'

function* saga() {
  try {
     ...
  } catch(error) {
     if(isCance(error) 
        // error is an instance of SagaCancellationException
  }
}
redux-saga -

Published by yelouafi over 8 years ago

Features

This release adds new support to dynamically running Sagas after the applyMiddleware phase.

In previous releases, the library provided the runSaga method to start Sagas dynamically. However, there were some issues due to how runSaga was implemented (related issues #48, #76)

In this release, the library provides a new method (thanks to @gaearon) to attach Sagas dynamically to the Store.

Migration

(see API docs for detailed infos)

Before

In previous releases, you had to create a storeIO and passes it to runSaga

configureStore.js

import createSagaMiddleware from 'redux-saga'
import reducer from './path/to/reducer'
import startupSagas from './path/to/sagas'

export default function configureStore(initialState) {
  // Note: passing middleware as the last argument to createStore requires redux@>=3.1.0
  return createStore(
    reducer,
    initialState,
    applyMiddleware(/* other middleware, */createSagaMiddleware(...startupSagas ))
  )
}

someModule.js

import {runSaga, storeIO} from 'redux-saga'
import configureStore from './configureStore '

import dynamicSaga from './path/to/dynamicSaga'

const store = configureStore()
const task = runSaga(
  dynamicSaga(store.getState),
  storeIO(store)
)

After

Starting from this release, you export the saga middleware itself and uses its run method

configureStore.js

import createSagaMiddleware from 'redux-saga'
import reducer from './path/to/reducer'
import startupSagas from './path/to/sagas'

// export the middleware
export const sagaMiddleware = createSagaMiddleware(...startupSagas)

export default function configureStore(initialState) {
  // Note: passing middleware as the last argument to createStore requires redux@>=3.1.0
  return createStore(
    reducer,
    initialState,
    applyMiddleware(/* other middleware, */ sagaMiddleware)
  )
}

someModule.js

import { sagaMiddleware } from './configureStore'
import dynamicSaga from './path/to/dynamicSaga'

sagaMiddleware.run(dynamicSaga)

Other changes

  • Task descriptor enhanced with a new cancel method
  • Throw an Error if the Saga was provided an undefined action
  • The documentation is now using GitBook thanks to @cef62
redux-saga -

Published by yelouafi over 8 years ago

Include fix #71 'yield [] should return immediately an empty array instead of blocking forever' (thanks to @slorber )

redux-saga -

Published by yelouafi over 8 years ago

This release include a new generator driver core that doesnt rely on promises. This should get rid of annoying issues related to Saga missing events.

The new implementation uses only callback notification to handle synchronous actions. It means now even when you dispatch multiple actions concecutively in a synchrnous way, Sagas waiting for those action wont miss anyone. It means also that Saga starts immediately and do not miss actions fired at startup (no more requestAnimationFrame tricks are required).

For more background see the explanation on this issue. This release should fixe #50 and #55

Other Changes

  • Uncaught SagaCancellationExceptions are no longer bubbled to parents. This was necessary to make yield cancel(...) have true non blocking semantics. Once we cancel a task, we move immediately to the next step. If the cancelled task omits to catch its cancellation error, a warning message will be printed on the console (only in dev mode).
  • Fixed 'Infinite loop when using take('*')' (#61)
  • Uncaught cancellation exception are logged into the console only in dev mode (process.env.NODE_ENV set to 'development')
  • Monitor actions are also dispatched only in dev mode
  • new function createMockTask to mock results of fork effects. With this function, it is now possible to test generators using fork like this
import test from 'tape';
import { take, fork, cancel } from 'redux-saga'
import { createMockTask } from 'redux-saga/lib/testUtils'

const types = { GET_DATA: 'GET_DATA'}

function callApi() { ... }

export function* getData () {
  let task
  while (true) {
    let { data } = yield take(types.GET_DATA)
    task && task.isRunning() ? yield cancel(task) : null
    task = yield fork(callApi, data)
  }
}

test('getData', assert => {

  const it = getData()

  assert.deepEqual( it.next().value, take(types.GET_DATA) )

  const mockData = {data: 'xyz'}
  const mockAction = {type: types.GET_DATA, data: mockData }

  // resume the generator with mockAction
  // since task is null, we expect yield null
  assert.deepEqual( it.next(mockAction).value, fork(callApi, mockData ) )

  // mock fork result
  const mockTask = createMockTask()

  // resume the generator with mock task
  assert.deepEqual( it.next(mockTask).value, take(types.GET_DATA) )

  // simulate a task ending
  mockTask.setRunning(false)

  // now expect a cancel
  assert.deepEqual( it.next(mockAction).value, cancel(mockTask) )

  assert.end()
})
redux-saga -

Published by yelouafi over 8 years ago

Features

  • call, cps and fork both support providing 'this' context for invoking instance methods

Fixes

  • take will now throw an error if provided with an argument and that argument is undefined. (see #35. thanks @tgriesser)

Also migrated examples to webpack. All build infrastructure use webpack

redux-saga -

Published by yelouafi almost 9 years ago

  • Fixed issue: apply not exported from the main module
redux-saga -

Published by yelouafi almost 9 years ago

Features

  • Task cancellation support. Thanks to @aikoven for this one. (issue #14).
  • Saga monitoring support (The sagaMonitor in the examples folder implements a simple logger. You can print a trace of the sagas control flow in the console by dispatching a LOG_EFFECT action. You can play with the repo examples by typing store.dispatch({type: 'LOG_EFFECT'}) in the console.

Below a screenshot from the counter example.

counter-log

redux-saga -

Published by yelouafi almost 9 years ago

redux-saga -

Published by yelouafi almost 9 years ago

redux-saga -

Published by yelouafi almost 9 years ago

Package Rankings
Top 0.34% on Npmjs.org
Top 14.45% on Repo1.maven.org
Top 3.46% on Proxy.golang.org
Badges
Extracted from project README
npm version CDNJS npm Discord Shield OpenCollective OpenCollective