Skip to content

Commit 74eec26

Browse files
committed
Initial commit
0 parents  commit 74eec26

File tree

7 files changed

+239
-0
lines changed

7 files changed

+239
-0
lines changed

Diff for: .gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules
2+
.DS_Store

Diff for: dist/index.js

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/**
2+
* Allows you to register actions that when dispatched, send the action to the server via a socket.io socket.
3+
*/
4+
'use strict';
5+
6+
Object.defineProperty(exports, '__esModule', {
7+
value: true
8+
});
9+
exports['default'] = createSocketIoMiddleware;
10+
11+
function createSocketIoMiddleware(socket) {
12+
var actionTypesOrTestFnOrPrefix = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];
13+
14+
return function (store) {
15+
//Wire socket.io to dispatch actions sent by the server.
16+
socket.on('action', store.dispatch);
17+
18+
var optionType = typeof actionTypesOrTestFnOrPrefix;
19+
20+
return function (next) {
21+
return function (action) {
22+
var type = action.type;
23+
24+
var result = next(action);
25+
26+
if (type) {
27+
var emit = false;
28+
// String Prefix
29+
if (optionType === 'string' && type.indexOf(actionTypesOrTestFnOrPrefix) === 0) {
30+
emit = true;
31+
}
32+
// test function
33+
else if (optionType === 'function' && actionTypesOrTestFnOrPrefix(type)) {
34+
emit = true;
35+
}
36+
// Array of types
37+
else if (Array.isArray(actionTypesOrTestFnOrPrefix) && actionTypesOrTestFnOrPrefix.indexOf(type) !== -1) {
38+
emit = true;
39+
}
40+
41+
if (emit) {
42+
socket.emit(type, action);
43+
}
44+
}
45+
return result;
46+
};
47+
};
48+
};
49+
}
50+
51+
module.exports = exports['default'];

Diff for: gulpfile.js

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
var gulp = require('gulp');
2+
var babel = require('gulp-babel');
3+
4+
gulp.task('babel', function() {
5+
return gulp.src('src/*.js')
6+
.pipe(babel())
7+
.pipe(gulp.dest('dist/'));
8+
});
9+
10+
gulp.task('watch', function() {
11+
gulp.watch('*.js', ['babel']);
12+
});
13+
14+
// Default Task
15+
gulp.task('default', ['babel']);

Diff for: package.json

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"name": "redux-socket.io",
3+
"version": "0.0.1",
4+
"description": "An opinionated connector between socket.io and redux",
5+
"main": "dist/index.js",
6+
"repository":"github:itaylor/redux-socket.io",
7+
"directories": {
8+
"test": "test"
9+
},
10+
"scripts": {
11+
"test": "mocha -r qunit-mocha-ui --ui qunit-mocha-ui --compilers js:babel/register"
12+
},
13+
"keywords": [
14+
"redux",
15+
"middleware",
16+
"socket.io",
17+
"action"
18+
],
19+
"author": "[email protected]",
20+
"license": "MIT",
21+
"devDependencies": {
22+
"babel": "^5.8.23",
23+
"gulp": "^3.9.0",
24+
"gulp-babel": "^5.3.0",
25+
"mocha": "^2.3.3",
26+
"qunit-mocha-ui": "0.0.5",
27+
"redux": "^3.0.3"
28+
}
29+
}

Diff for: readme.md

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# redux-socket.io
2+
An opinionated connector between socket.io and redux.
3+
4+
Philosophy
5+
-------------
6+
Socket.io client->server messages should should be sent by dispatching actions, where the action is the payload. Socket.io server->client messages should be dispatched as actions when received.
7+
8+
How to use
9+
-------------
10+
### Installation
11+
```
12+
npm install --save redux-socket.io
13+
```
14+
15+
16+
### MIT License
17+
Copyright (c) 2015 Ian Taylor
18+
19+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
20+
21+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
22+
23+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Diff for: src/index.js

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/**
2+
* Allows you to register actions that when dispatched, send the action to the server via a socket.io socket.
3+
*/
4+
export default function createSocketIoMiddleware(socket, actionTypesOrTestFnOrPrefix = []){
5+
6+
return store => {
7+
//Wire socket.io to dispatch actions sent by the server.
8+
socket.on('action', store.dispatch);
9+
10+
const optionType = typeof actionTypesOrTestFnOrPrefix;
11+
12+
return next => action => {
13+
const {type} = action;
14+
const result = next(action);
15+
16+
if(type){
17+
let emit = false;
18+
// String Prefix
19+
if (optionType === 'string' && (type.indexOf(actionTypesOrTestFnOrPrefix) === 0)){
20+
emit = true;
21+
}
22+
// test function
23+
else if(optionType === 'function' && actionTypesOrTestFnOrPrefix(type)){
24+
emit = true;
25+
}
26+
// Array of types
27+
else if(Array.isArray(actionTypesOrTestFnOrPrefix) && (actionTypesOrTestFnOrPrefix.indexOf(type) !== -1)){
28+
emit = true;
29+
}
30+
31+
if(emit){
32+
socket.emit(type, action);
33+
}
34+
}
35+
return result;
36+
}
37+
}
38+
}

Diff for: test/index.js

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import { createStore, applyMiddleware } from 'redux';
2+
import createSocketIoMiddleware from '../dist/index.js';
3+
4+
suite('Redux-socket.io middleware basic tests');
5+
6+
test('Using a string prefix to determine whether to call socket', 5, () => {
7+
const socket = new MockSocket();
8+
const socketIoMiddleware = createSocketIoMiddleware(socket, 'server/');
9+
const createStoreWithMiddleware = applyMiddleware(socketIoMiddleware)(createStore);
10+
const store = createStoreWithMiddleware(simpleReducer);
11+
12+
store.dispatch({type:'server/socketAction1', payload:'action1'});
13+
store.dispatch({type:'action2', payload:'action2'});
14+
15+
equal(store.getState().socketAction1, 'action1');
16+
equal(store.getState().action2, 'action2');
17+
equal(socket.emitted.length, 1);
18+
equal(socket.emitted[0][0], 'server/socketAction1');
19+
equal(socket.emitted[0][1].payload, 'action1');
20+
});
21+
22+
test('Using an array of action names to determine whether to call socket', 5, () => {
23+
const socket = new MockSocket();
24+
const socketIoMiddleware = createSocketIoMiddleware(socket, ['server/socketAction1']);
25+
const createStoreWithMiddleware = applyMiddleware(socketIoMiddleware)(createStore);
26+
const store = createStoreWithMiddleware(simpleReducer);
27+
28+
store.dispatch({type:'server/socketAction1', payload:'action1'});
29+
store.dispatch({type:'action2', payload:'action2'});
30+
31+
equal(store.getState().socketAction1, 'action1');
32+
equal(store.getState().action2, 'action2');
33+
equal(socket.emitted.length, 1);
34+
equal(socket.emitted[0][0], 'server/socketAction1');
35+
equal(socket.emitted[0][1].payload, 'action1');
36+
});
37+
38+
test('Using a function to determine whether to call socket', 5, () => {
39+
const socket = new MockSocket();
40+
function callSocketTestFn(type) {
41+
return type.match(/server\//);
42+
}
43+
const socketIoMiddleware = createSocketIoMiddleware(socket, callSocketTestFn);
44+
const createStoreWithMiddleware = applyMiddleware(socketIoMiddleware)(createStore);
45+
const store = createStoreWithMiddleware(simpleReducer);
46+
47+
store.dispatch({type:'server/socketAction1', payload:'action1'});
48+
store.dispatch({type:'action2', payload:'action2'});
49+
50+
equal(store.getState().socketAction1, 'action1');
51+
equal(store.getState().action2, 'action2');
52+
equal(socket.emitted.length, 1);
53+
equal(socket.emitted[0][0], 'server/socketAction1');
54+
equal(socket.emitted[0][1].payload, 'action1');
55+
});
56+
57+
class MockSocket{
58+
constructor(){
59+
this.emitted = [];
60+
}
61+
emit(...args){
62+
this.emitted.push(args);
63+
}
64+
on(){
65+
}
66+
}
67+
68+
function simpleReducer(state={}, action){
69+
switch(action.type){
70+
case 'server/socketAction1':
71+
return Object.assign({}, state, {
72+
'socketAction1': action.payload
73+
});
74+
case 'action2':
75+
return Object.assign({}, state, {
76+
'action2': action.payload
77+
});
78+
default:
79+
return state;
80+
}
81+
}

0 commit comments

Comments
 (0)