An alternative side effect model for Redux apps
MIT License
Bot releases are hidden (Show)
Published by Andarist about 5 years ago
Fixes resolving TS types for redux-saga/effects
Published by Andarist about 5 years ago
This release is bringing improved TS typings - allowed by [email protected]. Thanks, @gilbsgilbs for working on this 👍
For more on this please read https://github.com/redux-saga/redux-saga/pull/1892#issue-297396449
Published by Andarist over 5 years ago
Breaking changes:
channel
and actionChannel
have default buffer of buffers.expanding()
put
execution are no longer caught and swallowed, you need to catch them manuallytakeEvery
, takeLatest
, throttle
from the redux-saga
entry point (they are and were importable from redux-saga/effects
), takem
, put.sync
and executing array of effects, there is explicit API for this for already some time - all
effectrunSaga
- it no longer accepts subscribe
option, you should create a channel (preferably stdChannel
), pass it as channel
argument to the runSaga
API and communicate with through it with take
and put
methods{ [IO]: true, type, payload }
asEffect
, effect types are public, effect shapes are stable, so if for whatever reason you want to do some effect inspection you can just check them without us providing additional helpers for itlogError
, use only onError
option (it's signature is onError(error, { sagaStack })
)END
will now finish the race
effectstask.done
getter was changed to be task.toPromise
methodchannel
s private getters (__takers__
and __closed__
) got removeddelay
became an effectredux-saga/utils
got removed, exports available exclusively there got moved to separate packages - @redux-saga/deferred
, @redux-saga/delay-p
, @redux-saga/is
, @redux-saga/symbols
& @redux-saga/testing-utils
eventChannel
does no longer accept matcher
argument - it was a hacky way to support previous implementation of stdChannel
{effects, utils}
can't imported from 'redux-saga' anymoredetach
helper returns a new effect instead of mutating the input onefork
, this shouldn't affect any real-life code, affected patterns look like this fork(() => effectCreator())
and fork(takeEvery, 'type', fn)
TS@>3.1
nowNew:
babel-plugin-redux-saga
- can be used to enhance stack traces of thrown errorsmulticastChannel
- no buffering, notify all pending takers, multicastChannel#take(cb, matcher = matchers.wildard)
yield take(multicastChannel, pattern)
stdChannel
got reworked to be a singleton object (it is wrapped multicastChannel
's instance'), also it is an exported API to support new runSaga
's signature - this should also result in being a small perf boosteffectMiddlewares
- useful especially for testing, you can intercept/hijack any effect and resolve it on your own - passing it very redux-style to the next middleware (last being redux-saga
itself). How it might be used can be checked here.takeLeading
effect - it takes "leading" action and ignores all incoming ones of the same type while the "leading" is still handled (useful for things debouncing)retry
effect with the signature of retry(maxTries, delayLength, worker, ...args)
debounce
effect with the signature of debounce(delayLength, pattern, worker, ...args)
rootSagaStarted
hook for saga monitorObject.defineProperty
on actions dispatched with put
effect, so we have to be able to mutate the action objectredux-saga
process.env.NODE_ENV
is read only once and based on that value the appropriate bundle (development or production) is loaded conditionally with require
. process.env
is slow in node.js so this should improve performance a little bit.isRoot
property on Task (you probably won't ever need to use it, it's internal)Fixes:
stdChannel
in the internals allowed to fix 2 bugs with missed actions (see #707 and #1146)onError
should get called now even if you throw non-Errors in your code.actionChannel
sPublished by Andarist almost 6 years ago
This is first (and very likely last 😉) release candidate version 🎉. We expect no more breaking changes before releasing stable v1 (truth to be told there were not many breaking changes during whole beta
process - the API is mostly the same).
Added:
isRoot
property on Task (you probably won't ever need to use it, it's internal)delay
effect incorrectlyChanged:
sagaStack
was refactored - onError
call signature is now onError(error, { sagaStack })
Removed:
logError
, use only onError
optionredux-saga/utils
entirely, move of those are moved to separate packagesFixed:
Improved:
Many thanks once more to @restrry and @shinima who made it possible with their contributions.
Published by Andarist about 6 years ago
This is rather a smaller release, but some things have changed or got improved.
Added:
rootSagaStarted
hook for saga monitorChanged:
detach
helper returns a new effect instead of mutating the input oneRemoved:
asEffect
, it shouldn't be used, effect types are public, effect shapes are stable, so if for whatever reason you want to do some effect inspection you can just check them without us providing additional helpers for itFixed:
fork
, this shouldn't affect any real-life code, affected patterns look like this fork(() => effectCreator())
and fork(takeEvery, 'type', fn)
actionChannel
sPolished:
Object.defineProperty
on actions dispatched with put
effect, so we have to be able to mutate the action objectredux-saga
@babel/runtime
helpers, this has helped us to remove some bytes from our bundlesprocess.env.NODE_ENV
is read only once and based on that value the appropriate bundle (development or production) is loaded conditionally with require
. process.env
is slow in node.js so this should improve performance a little bit.Published by Andarist about 6 years ago
This release is highly motivated by our 2 new core members @restrry & @shinima. They have put a lot of work into creating PRs & helping others with their issues.
We've recently extracted some modular packages, you can see @redux-saga/deferred
, @redux-saga/delay-p
, @redux-saga/is
& @redux-saga/symbols
. At the same time we've managed to shave off some bytes from the core build - according to some tests of our we've managed remove over 1kb, but your YMMV ofc.
Added:
retry
effect with the signature of retry(maxTries, delayLength, worker, ...args)
debounce
effect with the signature of debounce(delayLength, pattern, worker, ...args)
Changed:
{effects, utils}
aren't imported from 'redux-saga' anymore. import them from redux-saga/effects
, redux-saga/utils
is
helper should be imported from @redux-saga/is
.delay
function (not effect!) should be imported from @redux-saga/delay-p
{ [IO]: true, type, payload }
, their structure should be treated as opaque anyway, so we hope this doesn't break anyoneEND
will now finish the race
effectsPublished by Andarist over 6 years ago
Error handling
Let's face it. Errors coming from redux-saga
were unreadable and made finding a root cause of the problem really difficult. We really want to improve this situation and with this release (thanks to @restrry's amazing contribution) we start to log "saga stacks" along with original errors. This works similar to what React already does with its "component stacks". Just look at this one:
You can even enhance those stacks with file names and line numbers by using in development our new babel-plugin-redux-saga (also thanks to @restrry). Let us know if there are any issues with this or if we can make them even more useful!
Also onError
should get called now even if you throw non-Errors in your code.
Beside that few things have changed, you can read more about them below.
Added:
takeLeading
effect - it takes "leading" action and ignores all incoming ones of the same type while the "leading" is still handled (useful for things debouncing)node_modules
, keep in mind though that we only depend on compose
from that package)Changed:
delay
became an effect, you still can import delay
util from redux-saga/utils
thoughPublished by Andarist almost 7 years ago
I must say that this release probably wouldn't be possible without community sponsors - both organizations and individual backers.
I'm not saying that money given by the community has helped, but it is a nice incentive to work and a token of appreciation. Somehow the fact alone that people are sending money towards us got me lately back on track, going, writing some code, pushing things forward towards v1 release.
Note that the money is not what you have most valuable to offer for OSS projects - your time is way more valuable. If you want some feature to get implemented, bug to be fixed or just want to help - please reach out to a project's maintainer, maybe ask for pointers about code internals so you can start working easier. OSS is done by regular people like you and most projects' code is not magic, everything can be figured out and you can get comfortable with it.
Maintaining a popular project (over 10k ⭐️⭐️⭐️!) is not an easy task to do. Truth to be told you do not even have to write code to get exhausted. Answering issues, replying to people's demands etc is time and energy consuming.
I'd want to think that at least in those areas I've maintained the package well - nearly every question gets answered and it gets answered within days. I've helped people fix their broken code, I've suggested how their apps can be structured, how to solve particular problems.
However GitHub is not really a place where (most of such) questions should be asked. Whenever you consider asking a question on any project's GitHub, please consider if it is the right place to ask. There are many places you can get help from the community, such as obviously StackOverflow. In terms of redux-saga additionally you can reach out to the community on our gitter channel and redux-saga reactiflux's channel.
New:
multicastChannel
- no buffering, notify all pending takers, multicastChannel#take(cb, matcher = matchers.wildard)
yield take(multicastChannel, pattern)
stdChannel
got reworked to be a singleton object (it is wrapped multicastChannel
's instance'), also it is an exported API to support new runSaga
's signature - this should also result in being a small perf boosteffectMiddlewares
- useful especially for testing, you can intercept/hijack any effect and resolve it on your own - passing it very redux-style to the next middleware (last being redux-saga
itself). How it might be used can be checked here. Many thanks to @eloytoro for this featureBreaking changes:
channel
and actionChannel
have default buffer of buffers.expanding()
put
execution are no longer caught and swallowed, you need to catch them manuallyeventChannel
does no longer accept matcher
argument - it was a hacky way to support previous implementation of stdChannel
arrayOfDeffered
got renamed to the correct arrayOfDeferred
sym
tries to use Symbol
if it's available, this mainly breaks effects' "shape" - types no longer are simple strings, although no code should make any assumptions about effects' shape anywaytakeEvery
, takeLatest
, throttle
from the redux-saga
entry point (they are and were importable from redux-saga/effects
), takem
, put.sync
and executing array of effects, there is explicit API for this for already some time - all
effectrunSaga
- it no longer accepts subscribe
option, you should create a channel (preferably stdChannel
), pass it as channel
argument to the runSaga
API and communicate with through it with take
and put
methodstask.done
getter was changed to be task.toPromise
methodchannel
s private getters (__takers__
and __closed__
) got removedBug fixes:
stdChannel
in the internals allowed to fix 2 bugs with missed actions (see #707 and #1146), cc @gajusInternals:
Published by Andarist about 7 years ago
detach
helper - this is used internally now by spawn
to mark fork
effect as detached, got exported and might be used in userland, it's useful for creating i.e. detached takeEvery
import { detach } from 'redux-saga'
import { takeEvery } from 'redux-saga/effects'
// ...
yield detach(takeEvery(ACTION_A, mightThrowSaga))
detach
got added thanks to @aikoven#__PURE__
annotations from the source code, adding them automatically with annotate-pure-calls babel's plugin
sagaStack
property non-enumerable (this is attached sometimes by redux-saga
to the thrown Errors)Published by Andarist about 7 years ago
TS Typings
take
and put
effects redeclarable (thanks to @Rokt33r)put.sync
as deprecatedPublished by Andarist about 7 years ago
TS Typings
CpsCallback
(thanks to @dannsam)cloneableGenerator
function (thanks to @zyml)Published by Andarist over 7 years ago
context
not being passed to the root sagas (thanks @VictorQueiroz)Published by Andarist over 7 years ago
Symbol
s for some internal properties - this caused 2 redux-saga version to be incompatible, effects from one couldnt be interpreted by the other onePublished by Andarist over 7 years ago
const two = yield 2
), however yielding falsy values prevented yielding saga to continuePublished by Andarist over 7 years ago
Things published already under recent patch versions, but without public release noted:
redux-saga/effects
and redux-saga/utils
working properly for webpack2
and rollup
users (or any other bundle which recognizes jsnext:main
/module
entry). Thanks to @Ephys. How was it achieved can be seen here. Neat trick which I think is not publicly known and it was an issue for quite some time and also allowed me to help fixing this in some other libraries.join(...tasks)
implementation, its not accepting an array of tasks, but rather a variadic number of tasks as argumentscancel(...tasks)
in similar manneryield cancel()
inside a task and handle both cancel(task)
+ self cancellation via cancel()
within the same finally
blockgetContext
and setContext
effects (thanks for the idea to @aikoven). It's not properly documented yet, but its a feature which allows sharing context properties across tasks without need to import them in each file or passing them explicitly through arguments. The feature is implemented as dynamic scoping which should sounds familiar for JS devs. In general you cannot share a context property from a child task to the parent, its only passed 'down'. You can read more in related issue and PR till its not documented.createSagaMiddleware({ onerror })
which got into library because of a typo and we have supported it for some time, please use onError
insteadNew in this release:
runSaga
API, runSaga(iterator, storeInterface)
got depreacted in favor of runSaga(storeInterface, saga, ...args)
. It allowed us to leverage the change internally so now sagaMiddleware.run
became partially applied runSaga
, they wont now go out of sync (in the past changes and bug fixes had to implemented in both of them).cloneableGenerator
utils, which can ease ur unit testing when logic branching is needed, thanks to @nihauxcall([obj, 'method'])
- now you can pass a string as method's name which should be called on the passed contextall
effect - explicit effect for parallel effects, which is exactly what we had been supporting by accepting yielded arrays, so the latter is become deprecated now in favor of this explicitness which nicely maps to the Promise.all
API. Please use this from now onBug fixes:
eventChannel
s not closing automatically upon emitting END
, thanks to @baldwmicIn the meantime we have also:
rollup
ed UMD build, which is way smaller than the one which was produced by a webpack, thanks to the so called 'flat-bundling'Published by Andarist over 7 years ago
take
effect supporting Symbol
types again - thanks to @iMosesPublished by Andarist almost 8 years ago
This small update allows you to integrate better with some other redux libraries, like redux-actions and redux-act.
For the users of those it is now possible to omit maintaining action constants only for the sake's of redux-saga
and they can use created actions as patterns for the take
effect like this:
import { createAction } from 'redux-actions'
const increment = createAction('INCREMENT', amount => amount) // typeof increment === 'function'
// ...
yield take(increment)
It means that you can pass an action creator function with custom .toString()
method on it and it can be checked by redux-saga against dispatched actions' types.
Special thanks for this goes to @thezanke
Also - finally the build for rollup
should be fixed (public export of CHANNEL_END
got fixed).
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 action
s.
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.
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])
redux-saga/effects
, that means takeEvery
, takeLatest
, throttle
(thanks to @mcrawshaw)