or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/npm-redux-saga

Saga middleware for Redux to handle side effects using ES6 generators

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/redux-saga@1.3.x

To install, run

npx @tessl/cli install tessl/npm-redux-saga@1.3.0

0

# Redux-Saga

1

2

Redux-Saga is a library that makes application side effects (asynchronous things like data fetching and impure things like accessing the browser cache) easier to manage, more efficient to execute, easy to test, and better at handling failures. It uses ES6 generator functions to make asynchronous flows easy to read, write and test, creating a mental model where sagas act as separate threads solely responsible for side effects.

3

4

## Package Information

5

6

- **Package Name**: redux-saga

7

- **Package Type**: npm

8

- **Language**: JavaScript/TypeScript

9

- **Installation**: `npm install redux-saga`

10

11

## Core Imports

12

13

```typescript

14

import createSagaMiddleware from "redux-saga";

15

import { take, put, call, fork, select } from "redux-saga/effects";

16

```

17

18

For CommonJS:

19

20

```javascript

21

const createSagaMiddleware = require("redux-saga").default;

22

const { take, put, call, fork, select } = require("redux-saga/effects");

23

```

24

25

## Basic Usage

26

27

```typescript

28

import { createStore, applyMiddleware } from "redux";

29

import createSagaMiddleware from "redux-saga";

30

import { take, put, call, fork } from "redux-saga/effects";

31

32

// Create saga middleware

33

const sagaMiddleware = createSagaMiddleware();

34

35

// Apply middleware to store

36

const store = createStore(

37

reducer,

38

applyMiddleware(sagaMiddleware)

39

);

40

41

// Example saga

42

function* fetchUserSaga(action) {

43

try {

44

const user = yield call(Api.fetchUser, action.payload.userId);

45

yield put({ type: 'USER_FETCH_SUCCEEDED', user });

46

} catch (e) {

47

yield put({ type: 'USER_FETCH_FAILED', message: e.message });

48

}

49

}

50

51

function* watchFetchUser() {

52

yield take('USER_FETCH_REQUESTED', fetchUserSaga);

53

}

54

55

// Start the saga

56

sagaMiddleware.run(watchFetchUser);

57

```

58

59

## Architecture

60

61

Redux-Saga is built around several key concepts:

62

63

- **Generator Functions**: ES6 generators that can be paused and resumed, making async code look synchronous

64

- **Effects**: Plain JavaScript objects that describe what the saga should do (declarative)

65

- **Middleware**: Redux middleware that connects sagas to the Redux store

66

- **Tasks**: Objects representing running generator functions that can be cancelled or joined

67

- **Channels**: Communication mechanism between sagas and external event sources

68

69

## Capabilities

70

71

### Middleware Creation

72

73

Core functionality for creating and configuring the Redux middleware that connects sagas to your Redux store.

74

75

```typescript { .api }

76

interface SagaMiddlewareOptions<C extends object = {}> {

77

context?: C;

78

sagaMonitor?: SagaMonitor;

79

onError?(error: Error, errorInfo: ErrorInfo): void;

80

effectMiddlewares?: EffectMiddleware[];

81

channel?: MulticastChannel<Action>;

82

}

83

84

interface SagaMiddleware<C extends object = {}> extends Middleware {

85

run<S extends Saga>(saga: S, ...args: Parameters<S>): Task;

86

setContext(props: Partial<C>): void;

87

}

88

89

function createSagaMiddleware<C extends object>(

90

options?: SagaMiddlewareOptions<C>

91

): SagaMiddleware<C>;

92

```

93

94

[Middleware](./middleware.md)

95

96

### Basic Effects

97

98

Core effects for the most common saga operations: waiting for actions, dispatching actions, calling functions, and managing context.

99

100

```typescript { .api }

101

function take<A extends Action>(pattern?: ActionPattern<A>): TakeEffect;

102

103

function put<A extends Action>(action: A): PutEffect<A>;

104

105

function call<Fn extends (...args: any[]) => any>(

106

fn: Fn,

107

...args: Parameters<Fn>

108

): CallEffect<SagaReturnType<Fn>>;

109

110

function select<Fn extends (state: any, ...args: any[]) => any>(

111

selector?: Fn,

112

...args: Tail<Parameters<Fn>>

113

): SelectEffect;

114

115

function getContext(prop: string): GetContextEffect;

116

117

function setContext(props: object): SetContextEffect;

118

```

119

120

[Basic Effects](./basic-effects.md)

121

122

### Concurrency Effects

123

124

Effects for managing concurrent execution, forking tasks, and coordinating multiple asynchronous operations.

125

126

```typescript { .api }

127

function fork<Fn extends (...args: any[]) => any>(

128

fn: Fn,

129

...args: Parameters<Fn>

130

): ForkEffect<SagaReturnType<Fn>>;

131

132

function spawn<Fn extends (...args: any[]) => any>(

133

fn: Fn,

134

...args: Parameters<Fn>

135

): ForkEffect<SagaReturnType<Fn>>;

136

137

function join(task: Task): JoinEffect;

138

139

function cancel(task: Task): CancelEffect;

140

141

function all<T>(effects: T[]): AllEffect<T>;

142

143

function race<T>(effects: { [key: string]: T }): RaceEffect<T>;

144

```

145

146

[Concurrency Effects](./concurrency-effects.md)

147

148

### Helper Effects

149

150

High-level helper effects built on top of basic effects for common patterns like handling every action, latest action, or throttling.

151

152

```typescript { .api }

153

function takeEvery<P extends ActionPattern>(

154

pattern: P,

155

worker: (action: ActionMatchingPattern<P>) => any

156

): ForkEffect<never>;

157

158

function takeLatest<P extends ActionPattern>(

159

pattern: P,

160

worker: (action: ActionMatchingPattern<P>) => any

161

): ForkEffect<never>;

162

163

function takeLeading<P extends ActionPattern>(

164

pattern: P,

165

worker: (action: ActionMatchingPattern<P>) => any

166

): ForkEffect<never>;

167

168

function throttle<P extends ActionPattern>(

169

ms: number,

170

pattern: P,

171

worker: (action: ActionMatchingPattern<P>) => any

172

): ForkEffect<never>;

173

174

function debounce<P extends ActionPattern>(

175

ms: number,

176

pattern: P,

177

worker: (action: ActionMatchingPattern<P>) => any

178

): ForkEffect<never>;

179

```

180

181

[Helper Effects](./helper-effects.md)

182

183

### Channels

184

185

Channel system for communication between sagas and external event sources, enabling integration with WebSockets, DOM events, and other async data sources.

186

187

```typescript { .api }

188

function channel<T extends NotUndefined>(buffer?: Buffer<T>): Channel<T>;

189

190

function eventChannel<T extends NotUndefined>(

191

subscribe: Subscribe<T>,

192

buffer?: Buffer<T>

193

): EventChannel<T>;

194

195

function multicastChannel<T extends NotUndefined>(): MulticastChannel<T>;

196

197

function actionChannel(

198

pattern: ActionPattern,

199

buffer?: Buffer<Action>

200

): ActionChannelEffect;

201

```

202

203

[Channels](./channels.md)

204

205

### Testing Utilities

206

207

Tools for testing sagas in isolation, including cloneable generators and mock tasks.

208

209

```typescript { .api }

210

function cloneableGenerator<S extends Saga>(

211

saga: S

212

): (...args: Parameters<S>) => SagaIteratorClone;

213

214

function createMockTask(): MockTask;

215

```

216

217

[Testing](./testing.md)

218

219

### Utility Functions

220

221

General utility functions for working with Redux-Saga effects and values.

222

223

```typescript { .api }

224

function detach<T>(forkEffect: ForkEffect<T>): ForkEffect<T>;

225

function isEnd(value: any): value is END;

226

```

227

228

### Utility Packages

229

230

Additional utility packages providing type checking, symbols, deferred promises, and monitoring capabilities.

231

232

```typescript { .api }

233

// Type checking utilities

234

import * as is from "@redux-saga/is";

235

236

// Symbol constants

237

import { CANCEL, SAGA_ACTION, TASK } from "@redux-saga/symbols";

238

239

// Deferred promises

240

import deferred from "@redux-saga/deferred";

241

242

// Promise-based delay

243

import delay from "@redux-saga/delay-p";

244

245

// Saga monitoring

246

import createSagaMonitor from "@redux-saga/simple-saga-monitor";

247

```

248

249

[Utilities](./utilities.md)

250

251

## Types

252

253

### Core Types

254

255

```typescript { .api }

256

interface Action<T extends string = string> {

257

type: T;

258

}

259

260

interface AnyAction extends Action {

261

[extraProps: string]: any;

262

}

263

264

interface Task {

265

isRunning(): boolean;

266

result<T = any>(): T | undefined;

267

error(): any | undefined;

268

toPromise<T = any>(): Promise<T>;

269

cancel(): void;

270

setContext(props: object): void;

271

}

272

273

type ActionPattern<A extends Action = Action> =

274

| string

275

| string[]

276

| ((action: A) => boolean)

277

| A['type'][];

278

279

type NotUndefined = {} | null;

280

281

interface Saga<Args extends any[] = any[], Return = any> {

282

(...args: Args): SagaIterator<Return>;

283

}

284

285

interface SagaIterator<T = any> extends Iterator<any, T, any> {

286

readonly name: string;

287

}

288

289

interface Buffer<T> {

290

isEmpty(): boolean;

291

put(message: T): void;

292

take(): T | undefined;

293

}

294

295

interface TakeableChannel<T> {

296

take(cb: (message: T | END) => void): void;

297

}

298

299

interface PuttableChannel<T> {

300

put(message: T | END): void;

301

}

302

303

interface FlushableChannel<T> {

304

flush(cb: (items: T[] | END) => void): void;

305

}

306

307

interface Channel<T> extends TakeableChannel<T>, PuttableChannel<T>, FlushableChannel<T> {

308

close(): void;

309

}

310

311

interface MulticastChannel<T> extends Channel<T> {

312

take(cb: (message: T | END) => void, matcher?: Predicate<T>): void;

313

}

314

315

type Predicate<T> = (value: T) => boolean;

316

type END = { type: 'END' };

317

type EndType = END;

318

```

319

320

### Effect Types

321

322

```typescript { .api }

323

type TakeEffect = SimpleEffect<'TAKE', TakeEffectDescriptor>;

324

type PutEffect<A extends Action = AnyAction> = SimpleEffect<'PUT', PutEffectDescriptor<A>>;

325

type CallEffect<RT = any> = SimpleEffect<'CALL', CallEffectDescriptor<RT>>;

326

type ForkEffect<RT = any> = SimpleEffect<'FORK', ForkEffectDescriptor<RT>>;

327

type SelectEffect = SimpleEffect<'SELECT', SelectEffectDescriptor>;

328

type GetContextEffect = SimpleEffect<'GET_CONTEXT', GetContextEffectDescriptor>;

329

type SetContextEffect = SimpleEffect<'SET_CONTEXT', SetContextEffectDescriptor>;

330

type AllEffect<T> = CombinatorEffect<'ALL', T>;

331

type RaceEffect<T> = CombinatorEffect<'RACE', T>;

332

333

interface SimpleEffect<T, P> {

334

type: T;

335

payload: P;

336

}

337

338

interface CombinatorEffect<T, P> {

339

type: T;

340

payload: P;

341

}

342

343

type ActionMatchingPattern<P> = P extends string

344

? Action<P>

345

: P extends (action: infer A) => boolean

346

? A extends Action ? A : Action

347

: Action;

348

349

type SagaReturnType<S extends Function> = S extends (...args: any[]) => SagaIterator<infer RT>

350

? RT

351

: S extends (...args: any[]) => Promise<infer RT>

352

? RT

353

: S extends (...args: any[]) => infer RT

354

? RT

355

: never;

356

357

type Tail<L extends any[]> = L extends [any, ...infer T] ? T : never;

358

```

359

360

### Constants

361

362

```typescript { .api }

363

/** Symbol used for cancellation */

364

const CANCEL: string;

365

366

/** Special action type that terminates sagas */

367

const END: EndType;

368

369

/** Effect type constants */

370

const effectTypes: {

371

TAKE: 'TAKE';

372

PUT: 'PUT';

373

ALL: 'ALL';

374

RACE: 'RACE';

375

CALL: 'CALL';

376

CPS: 'CPS';

377

FORK: 'FORK';

378

JOIN: 'JOIN';

379

CANCEL: 'CANCEL';

380

SELECT: 'SELECT';

381

ACTION_CHANNEL: 'ACTION_CHANNEL';

382

CANCELLED: 'CANCELLED';

383

FLUSH: 'FLUSH';

384

GET_CONTEXT: 'GET_CONTEXT';

385

SET_CONTEXT: 'SET_CONTEXT';

386

};

387

```