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 - v0.14.2

Published by Andarist almost 8 years ago

This small update allows you to integrate better with some other redux libraries, like redux-batched-actions.

From now on you can intercept what's being dispatched before it's emitted into the saga, which will allow for using take just like everybody else, instead of playing with the pattern argument.

The argument you need to pass to the middleware is a higher-order function which will first take out built-in emit function as the argument and return a 'middleware' function to process dispatched actions.

Example usage:

createSagaMiddleware({
 emitter: emit => action => {
   if (Array.isArray(action)) {
     action.forEach(emit);
     return
   }
   emit(action)
 }
});

More can be read in our docs

Great thanks to the @pbadenski for implementing the feature.

redux-saga - v0.14.1

Published by Andarist almost 8 years ago

Just a small patch version with:

  • join(...tasks) - this effect creator will accept array of tasks from now on, it's just a shorthand (more obvious one) for tasks.map(join)
  • take(array) - array can be now of mixed types - strings and predicate functions so this is possible now yield take(['ACTION_A', ac => ac.payload])
  • added TS typings for helpers' effect creators from the redux-saga/effects, that means takeEvery, takeLatest, throttle (thanks to @mcrawshaw)
redux-saga - v0.14.0

Published by Andarist almost 8 years ago

This release contains mostly deprecations, but only a mild ones. Mainly few things got better, more descriptive names to indicate their behaviour and helpers got their way into effects. Of course as those are deprecations only, we are still planning to support old APIs for a time being, but as those do not require much change in the code they old versions will get removed eventually.

New features:

  • permitting saga monitors to only hook the functions they want (thanks to @skellock)

Fixes:

  • refactored moment of actions emitting to saga internals, so not only standard middleware benefits from the recent (and possibly future) scheduling fixed, but also the runSaga API

Deprecations:

  • put.sync got renamed to put.resolve
  • takem got renamed to take.maybe
  • createSagaMiddleware({ onerror }) got fixed in the code (was documented as onError) and should be used from now on as docs suggested - createSagaMiddleware({ onError }) (thanks to @kuy)
  • all built-in helpers (takeEvery, takeLatest, throttle) got their respective counterparts in redux-saga/effects module, which should confuse people less and be more newcomers-friendly
import { takeEvery } from 'redux-saga/effects'
// ...
yield* takeEvery('ACTION', worker) // this WON'T work, as effect is just an object
const task = yield takeEvery('ACTION', worker) // this WILL work like charm

-----

import { takeEvery } from 'redux-saga'
// ...
yield* takeEvery('ACTION', worker) // this will continue to work for now
const task = yield takeEvery('ACTION', worker) // and so will this

Also few typings were fixed, thanks to @yenshih, @CarsonF and @aikoven for veryfing.

And last (but not least) great thanks and much appreciation to everyone who has contributed to improving the docs!

Happy Christmas.

redux-saga -

Published by yelouafi almost 8 years ago

This release includes an Improved saga monitor API (see #609).

  • notifies the monitor when root sagas are started by sagaMiddleware.run or runSaga.
  • added actionDispatched trigger to the monitor contract. We need this in order to figure out saga/take effects that reacted to a given action. Also added a silent flag SAGA_ACTION (non enumerable property) added to distinguish actions dispatched by sagas from others.

Other changes

  • New scheduler to handle synchronous & deeply nested forks/puts (see #622)
  • Browser build is now on cdnjs (thanks to @ian4hu & @pvnr0082t)
redux-saga - v0.12.1

Published by Andarist almost 8 years ago

  • fixed issue with uncaught errors in reducers/helpers/etc causing a saga to terminate if caused by a put effect (thanks to @michaelgilley)
  • fixed issue with races sometimes dropping buffered items in channels
  • added a possibility to attach cancel callback to cps effect (thanks to @alxandr)
  • fixed some TS typings (thanks to @jupl)
  • allowing sagaMonitor to be used in react-native (thanks to @benhughes)
redux-saga -

Published by yelouafi about 8 years ago

Changes

  • Added new effect flush (API docs). It can be used to clear buffered items in the channel and geting them back in a batch in the saga (thanks to @Andarist)

  • Added a new helper throttle (API docs)(thanks to @Andarist)

  • Added a new buffer type expanding (API docs) (thanks to @Andarist) . This new type also fixes the breaking change that was introduced by v0.11.1 with the new internal buffer implementation (see #511 [only if you need more details]).

    TL/DR: Use buffer.fixed(limit) when you need a bounded buffer (will throw an error when the untaked messages exceed the buffer limit). Use buffer.expanding(limit) when you need an auto expanding buffer.

  • createSagaMiddleware supports a new (optional) option: onError API docs to detect uncaught exceptions from Sagas (thanks to @secobarbital)

  • Saga helpers (takeEvery, takeLatest, throttle) are now non blocking (thanks to @Andarist).

Saga helpers return Iterator objects. In previous versions they were treated just like other Iterators and Promises in redux-saga, the Saga calling a helper (either via yield or yield*) will block until the Iterator returns. But since Saga helpers never return (because they are looping forever ) this will also cause the calling Saga to block forever. So in previous versions, if you wanted to call a helper in a non blocking way you had to use the fork effect

function* saga1() { ... }

function* saga2() { ... }

function* mainSaga() {
  yield fork(takeEvery, 'ACTION_1', saga1)
  yield fork(takeLatest, 'ACTION_2', saga2)
}

With this change, redux-saga handles the helpers like forks when used with yield which mean you can call them directly like this


function* mainSaga() {
  const task1 = yield takeEvery('ACTION_1', saga1)
  const task2 = yield takeLatest('ACTION_2', saga2)
}

Note this will not work when used with the delegation form yield*: eg yield* takeEvery(...) will block the Generator. This is due to how yield* works in Generators in JavaScript and can't be handled by redux-saga.

  • Add Chinese Traditional translation (thanks to @neighborhood999)
  • fixed bug log() not compatible with IE9 (thanks to @cyrilluce)
redux-saga -

Published by yelouafi about 8 years ago

A patch release including some fixes

  • fix V8 issue when yield*ing saga helpers
  • Fix issue with ES build (thanks @Andarist)
  • Fix issues with Error handling
redux-saga -

Published by yelouafi over 8 years ago

  • fix #360 : added option logger to customize logging (see API docs for createSagaMiddleware)
  • fix #398 : es build to properly use jsnext:main field (thanks to @mgmcdermott)

Breaking change in the signature of runSaga

The monitor argument is removed. Starting from this release, you must provide the monitor as a sagaMonitor key in the option argument. runSaga supports also the logger option

runSaga(iterator, {
  subscribe: ...,
  dispatch: ...,
  getState: ...,
+ sagaMonitor: monitor,
+ logger: ...
},
- monitor
)
redux-saga -

Published by yelouafi over 8 years ago

  • Fix Synchronous puts behaviors to be consistent with pre 0.10 releases

This restores the pre 0.10 behavior for handling puts whose result is a Promise (i.e. dispatch an action which will be handled by a middleware and returns a Promise). In pre 0.10 releases, the put doesn't wait for the returned promise to resolve;

Starting from this release

  1. put doesn't block waiting the returned promise to resolve
  2. In order to wait for the returned Promise, use the variant put.sync(...) which will wait until the Promise resolve (or rejects) before resuming

For background see #336

Other changes

  • fix Symbol handling in take's patterns and takeEvery/takeLatest (thanks to @jscinoz)
redux-saga -

Published by yelouafi over 8 years ago

Yep! Already another patch (got #314 merged just after releasing 0.10.3). Changes:

  • Make delay cancellable (#314 thanks to @aikoven, Also thanks @itinance for issuing #327).
redux-saga -

Published by yelouafi over 8 years ago

Changes

  • Enhanced sagaMonitor to work in Node environment (#317 thanks to @sompylasar)
  • fix #287 weird error stack trace and error printing
  • fix #316 Compare END action by string type, not by reference, to allow middleware-transformed actions
  • fix #298 Long error messages should be cut in production
redux-saga -

Published by yelouafi over 8 years ago

Fixed issue with the re-scheduling nested puts from forked childs (see #277 (comment))

redux-saga -

Published by yelouafi over 8 years ago

A patch release fixing some issues

  • fix Rejected Promise does not throw inside Generators if rejected with an undefined error #283
  • Only check eventChannel matcher if defined #273 (thanks @secobarbital)
  • Fixes issues of taking puts nested inside a fork call (forked child puts before fork Effect returns) #277
  • Updated docs, added a section on channels
  • Fixed cancellable-counter example
redux-saga -

Published by yelouafi over 8 years ago

This is a major release. Make sure to read the following notes because there are some breaking changes

Middleware API

It's no longer possible to start the Sagas in the applyMiddleware phase. Starting from this version Sagas must be started using the sagaMiddleware.run(saga, ...args) method. For a background see #235

Before this release, we used the following to start Sagas

import { createStore, applyMiddleware } from 'redux'
import createSagaMiddleware from 'redux-saga'

import reducer from './reducers'
import rootSaga from './sagas'


const store = createStore(
  reducer,
  applyMiddleware(createSagaMiddleware(rootSaga))
)

This is no longer valid. Instead you'll have to use the following

import { createStore, applyMiddleware } from 'redux'
import createSagaMiddleware from 'redux-saga'

import reducer from './reducers'
import rootSaga from './sagas'


const sagaMiddleware = createSagaMiddleware()
const store = createStore(
  reducer,
  applyMiddleware(sagaMiddleware)
)
sagaMiddleware.run(rootSaga)

Also see examples for an alternative way which enahnces the store with a runSaga method

Other changes

Removed deprecated getState argument passed to Sagas. You can use the select Effect to get the store state

New fork model

In prior release, all forked tasks were detached from their parents. The parent Saga terminates as soon as its own body of instructions is fully executed and errors from forked tasks do not propagate up to their parents which in some situations caused errors from forks to be swallowed. Also cancellation of a Parent task do not automatically propagate to child tasks, which means one have to maintain the list of running tasks manually and take care of cancelling them if the parent was cancelled

This new release includes a new fork model. By default, all forked tasks are attached to their parents. The whole parent + direct and indirect children form an execution tree (vs execution path in sequential programming). This implies new semantics from the prior releases

  • A parent task will terminate only if : 1- it terminates its own body and 2- all forked tasks are terminated (this can be handy for Server Side rendering scenarios, see real-world example in the repo)
  • Cancellation of a parent automatically propagates to child tasks, this means effectively the cancellation of the whole execution tree.
  • Errors can now also bubble from forked tasks: Any uncaught error from a fork will propagate up to the parent and aborts the whole execution tree. The benefit is that errors are no longer swallowed. Also errors are now logged with entire execution tree

error-rep

To create detached forks which follow the old model. You can use the new effect spawn.

Cancellation as a 'third State' (no longer throw on the Generator)

The release introduces a new model for Cancellation propagation. In prior releases, Cancellation of a task throws a SagaCancellationException inside the cancelled task. Starting from this release, Cancellations no longer throw inside cancelled tasks. This means that special cancellation handling no longer interfere with Error handling. In prior release, any try/catch block needed this chek

function* saga() {
  try {
     yield call(someApi)
     yield put(SuccessAction())
  } catch(err) {
    // ensure this is not a Cancellation error before handling the error
    // We do not want to dispatch an Error on cancellations
    if(!isCancel(err))
      yield put(ErrorAction())
  }
}

Starting with this release; the check is no longer necessary. If you want to react to cancellations, you can do it inside finally block. A new effect cancelled() is provided to check if the Saga has been cancelled

function* saga() {
  try {
     yield call(someApi)
     yield put(SuccessAction())
  } catch(err) {
     yield put(ErrorAction())
  } finally {
     if(yield cancelled()) {
       // logic proper to cancellation
    }
  }
}

So SagaCancellationException class and isCancelError function were removed.

Also Cancellation are now simply logged using console.info in dev mode instead of warnings

For background see #266

Support for Channels and Event channels

The redux-saga concurrency model introduces a new abstraction channel. You can now use take and put with other sources than the Store actions. Esp. eventChannel allows sagas to take from external event sources. You can find a simple example in the cancellable-counter repo example. For more info see API docs.

Introdcution of the special action END (support SSR and Universal Sagas)

This release introduces a special action END which can be used to notify that an event source has terminated. You can also dispatch an END to notify Sagas that no more Store actions will be fired. This can be handy in Server Side rendering to break the while(true) loop inside watchers.The real-world example in the repo shows a possible ways to implement universal Sagas and SSR.

END actions are automatically handled by the middleware and cause a Saga blocked on a take effect to automatically terminate (but it'll still wait for its forked tasks which provides support for SSR). To catch END values you can use the new Effect takem (aka takeMaybe). Using takem you get the explicit END so you can handle it manually. See #255 for more infos

Changes in the Monitoring API

Monitor actions are no longer fired by default in dev mode. To activate monitoring, you'll have to pass the {sagaMonitor} option explicitly to the middleware factory. Also monitor events are now dispatched to the Saga monitor via direct method calls instead of dispatching actions to the Store. See repo examples for usage examples.

Other changes

  • It's now possible to have parallel takes (yield [take(...), take(...)]
  • Added delay(ms, [val]) function
  • Fixed issue with interleaved synchronous dispatches (see #235)
  • runSaga: remove deprecated StoreIO
  • Task object gets a new property:isCancelled
  • Fixed Regenerator runtime in lib/dist #252
  • Fixed takeEvery doesn't work when action type is a Symbol #246
redux-saga -

Published by yelouafi over 8 years ago

A small patch with the following merges

  • Fixes 'yield* takeEvery causing 'not a function' error'. (issue #197)
  • Better error printing in non-browser environments (PR #194)
  • Added "jsnext:main" entry to package.json for ES2015 module import (PR #204)
  • Improved logging in sagaMonitor for takeEvery and takeLatest. Now if you do a yield takeEvery(...) (instead of yield* takeEvery(...)). You'll get a better logging (previously sagaMonitor logged 'anonymous')

yield-iter

redux-saga -

Published by yelouafi over 8 years ago

This patch fixes the createMockTask result to be conform to the API of Task object (see #182)

redux-saga -

Published by yelouafi over 8 years ago

This patch fixes synchronous errors handling (see #152 and #165)

redux-saga -

Published by yelouafi over 8 years ago

This patch removes all Symbol references from the source code. Some reported issues were related to buggy/incomplete/absent Symbol support which caused subtle and hard to track bugs on the source code.

The lib uses now simple namespaced strings to identify internal constants

redux-saga -

Published by yelouafi over 8 years ago

Well, perhaps this is the fastest patch in the release history.

So following the advice of @gaearon. I decided to drop the getState effect and only keep select. To get the entire Store's state, simply use yield select() without arguments

Before (in the previous v0.9.0) to get the entire state we used

import { getState } from 'redux-saga/effects'

function* saga() {
  // No longer valid with 0.9.1
  yield getState()
} 

Now (with 0.9.1) to get the entire state we use

import { select } from 'redux-saga/effects'

function* saga() {
  // get the entire state
  yield select()
} 

Other changes

  • Using the getState() param passed to the root Sagas is now deprecated (this is the getState argument passed to the root Sagas started by the middleware, not to confound with the dropped getState effect above)
  • Fixed SagaMonitor example code to support logging select effects
redux-saga -

Published by yelouafi over 8 years ago

This release add support for 2 new Effects (thanks to @gaearon and @slorber)

  • yield select(selector, ...args) allows a Saga to query some state slice using the provided selector function (Api docs)
  • yield getState() same as select but retrieves the entire state (Api docs)
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