npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

redux-saga-engine-network

v1.3.0

Published

a network adapter for redux-saga to seemingly integrate socket and api interraction in redux-saga way

Downloads

7

Readme

redux-saga-engine-network

a network adapter for redux-saga-engine-react to seemingly integrate socket and api interraction in redux-saga way

Why ?

as redux-saga provides a convenient effect approach to interact with the redux store, fetching data from remote remains a task on the hands of developers. integrating WebSocket technologies into your application futher complicates the integration into redux-saga reactive coding approach. This is where redux-saga-engine-network intend to give a helping hand.

How ?

redux-saga-engine-network allows you to register endpoints, both api and socket, wich can be later interracted with redux-saga like effects. this provide you with the benefits of clear declaration of your remote endpoints, and flawless integration of your calls into your sagas. futhermore, events are tracked and can be listened from multiple points into your scripts, opening the door of distributed reaction.

Usage

installation

npm install redux-saga-engine-network

testing

You can clone the repository and run the npm test command

endpoint declaration

redux-saga-engine-network needs to access the redux-saga middleware and a socket factory class in order to function, in your initialization script, you should import the connect helper function, and pass it the arguments (futher exemples uses socket.io-client library as implementation for the socket engine).

//src/initialize.ts

import { connect } from 'redux-saga-engine-network/helpers';
import { SocketClient as ISocketClient } from 'redux-saga-engine-network/clients';
import from '../network/declarations/endpoints';
import createSagaMiddleware from 'redux-saga';
import { ManagerOptions, Manager } from 'socket.io-client';

...

const sagaMiddleware = createSagaMiddleware({...});
class SocketClient extends ISocketClient {
  createManager<T = ManagerOptions>(uri: string, options: Partial<T>): Manager {
    return new Manager(uri, options);
  }
}
connect(sagaMiddleware, new SocketClient());

...

you can now start declaring your endpoints, make sure to import them before the call to connect helper.

api endpoint

// src/network/declarations/endpoints/api.ts

import { registerApiEndpoint } from "redux-saga-engine-network/helpers";

registerApiEndpoint("getTodoList", api.getTodoList);
// api.getTodoList should wrap a call with axios or other http client and return the expected data

socket endpoint

import {
  registerSocket,
  registerSocketEndpoint,
  registerSocketManager,
} from "redux-saga-engine-network/helpers";

registerSocketManager(
  "todoManager",
  {
    url: "http://localhost",
    port: 8080,
    options: {
      // socket.io-client manager options
    },
  },
  connectionErrorSaga,
  reconnectSuccessSaga,
  reconnectErrorSaga,
  maxReconnectErrorSaga
);

registerSocket(
  "todoManager",
  "todoSocket",
  "/todo",
  {
    auth: {
      //socket.io-client socket auth options
    },
  },
  connectSaga,
  disconnectSaga
);

registerSocketEndpoint(
  "postTodoList",
  "todoSocket",
  "post_todo_list_event",
  function selectResponseForPostTodoList(
    event: string,
    args: [{ type: string; data: any }]
  ) {
    return event === "reply" && args[0].type === "post_todo_list";
  },
  function selectErrorForPostTodoList(
    event: string,
    args: [{ type: string; data: any }]
  ) {
    return event === "error:message" && args[0].type === "post_todo_list";
  }
);

first, you register a manager with a key, wich will take care of managing the underlying connection, passing it optional sagaHandler to react on connection events.

then, you declare a socket, providing it a key, the manager key, the socket io namespace to connect to, passing it optional sagaHandlers to react to client connection events.

finally, you declare a socket endpoint, providing it a key, the socket key, the event name to emit, a selector function, which will filter server response and route them to consumer if intended for this endpoint, and a error selector function, wich wil filter error response from the server in a likewise manner.

endpoint usage

in order to use the endpoints api and socket endpoints seamlessly, redux-saga-engine-network provide you with custom redux-saga effects :

putNetwork and takeNetwork

you can put an event to an endpoint, passing data to it, and wait for the answer with the take effect :

import { takeEvery, all, call } from "redux-saga/effects";
import { POST_TODO_LIST } from "../actions";
import { putNetwork, takeNetwork } from "redux-saga-engine-network/effects";

function* handlePostTodoList({ data }) {
  yield putNetwork(["postTodoList"], { data: [] });
}

export function* watcher() {
  yield takeEvery(POST_TODO_LIST, handlePostTodoList);
}

function* handleResultPostTodoList1() {
  // do something
}
function* handleResultPostTodoList2() {
  // here too
}

export function* watcherResults() {
  yield all([
    function* () {
      try {
        const data = yield takeNetwork(["postTodoList"]);
        yield call(handleResultPostTodoList1, data);
      } catch (e) {
        // handle error
      }
    },
    function* () {
      try {
        const data = yield takeNetwork(["postTodoList"]);
        yield call(handleResultPostTodoList2, data);
      } catch (e) {
        // handle error
      }
    },
  ]);
}

note that you can take on multiple points for a single response

callNetwork

if you don't need to retrieve data at multiple points, you can use the callNetwork effect, wich will wait for the data to be returned :

import { takeEvery } from "redux-saga/effects";
import { POST_TODO_LIST } from "../actions";
import { callNetwork } from "redux-saga-engine-network/effects";

function* handlePostTodoList({ data }) {
  try {
    const result = yield callNetwork("postTodoList", { data: [] });
  } catch (e) {
    // handle errors from network or error message if socket
  }
}

export function* watcher() {
  yield takeEvery(POST_TODO_LIST, handlePostTodoList);
}

takeEveryNetwork

finally, you can attach a handler for a specific endpoint, which would be in charge of handling every response :

import { takeEvery } from "redux-saga/effects";
import { POST_TODO_LIST } from "../actions";
import { callNetwork } from "redux-saga-engine-network/effects";

function* handlePostTodoList({ data }) {
  // do something on every response
}

function* handleErrorsPostTodoList(err) {
  // do something on error response from the server
}

export function* watcher() {
  yield takeEveryNetwork(
    "postTodoList",
    handlePostTodoList,
    handleErrorsPostTodoList
  );
  yield putNetwork(["postTodoList"], { data: [] });
  yield putNetwork(["postTodoList"], { data: [] });
  yield putNetwork(["postTodoList"], { data: [] });
}