Skip to content

adamlewkowicz/reduxio

Repository files navigation

reduxio

Treat actions as they were events.



pipeline status Coverage Status

Lightweight Redux middleware that simplifies creating real-time apps with socket.io.

Getting started

npm i @art4/reduxio
import { createStore, applyMiddleware } from 'redux';
import io from 'socket.io-client';
import { createIoMiddleware } from '@art4/reduxio';

const socket = io('localhost');

const ioMiddleware = createIoMiddleware({
  socket,
  /* Listen to events (action types) that are going to be automatically dispatched to the store. */  
  listenTo: ['MESSAGE_RECEIVE']
});

const store = createStore(
  reducers,
  applyMiddleware(ioMiddleware)
);

How it works

Alt text

Example

Client

import { createStore, applyMiddleware } from 'redux';
import io from 'socket.io-client';
import { createIoMiddleware } from '@art4/reduxio';

const socket = io('localhost');

const ioMiddleware = createIoMiddleware({
  socket,
  listenTo: ['$_MESSAGE_RECEIVE']
});

const store = createStore(
  reducers,
  applyMiddleware(ioMiddleware)
);

store.dispatch({
  type: 'MESSAGE_SEND',
  payload: 'Message sent from client'
});

Server

socket.on('MESSAGE_SEND', (action, dispatchOnce) => {

  /* Emitting an action to connected clients, except the sender. */
  socket.emit('$_MESSAGE_RECEIVE', {
    type: '$_MESSAGE_RECEIVE',
    payload: action.payload
  });

  /*
    We are allowed to dispatch one action to the sender using the helper.
    Obviously, dispatching more actions is available through emit.
    Advantage of this approach is that we don't have to set up a listener for this action type.
  */
  dispatchOnce({ type: '$_MESSAGE_SUCCESS' });
});

API

createIoMiddleware (options: object)

Creates redux middleware with options.

Options:

Name Type Default Required Description
socket Object yes Socket.io client instance.
autoEmit Boolean true Automatically emit dispatched actions. Can be overwritten for specific action with meta io: false option.
listenTo Array [] Action types (event names) that are going to be automatically dispatched to the store.

io: boolean | object

Options that are passed to action's meta as io property.

io: boolean Determines if the action has to be emitted or not.

io: object Allows to pass options when emitting specific action.

Name Type Default Description
withState Boolean false Emits action with current store state (after this action has been dispatched).

More examples

Emit with client's state

Client

store.dispatch({
  type: 'MESSAGE_SEND',
  payload: 'Hello',
  meta: { io: { withState: true }}
});

Server

socket.on('MESSAGE_SEND', (action, state, dispatchOnce) => {
  /*
    Client's state is now available under the second argument.
    Keep in mind that dispatchOnce is always provided as last argument.
  */
});

Disable/enable emitting specific action

const ioMiddleware = createIoMiddleware({
  socket,
  autoEmit: true
});

const store = createStore(
  reducers,
  applyMiddleware(ioMiddleware)
);

store.dispatch({
  type: 'MESSAGE_SEND',
  payload: 'Hello',
  meta: {
    /* Auto emit option from middleware creator has lower priority, so this action won't be emitted. */
    io: false
  }
});