├── .babelrc
├── .eslintrc
├── .gitignore
├── .npmignore
├── .travis.yml
├── LICENSE
├── README.md
├── dist.js
├── lib
└── .gitkeep
├── package.json
├── src
├── dist.js
├── index.js
├── listener.js
└── socket.js
└── test.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | "react",
4 | "es2015",
5 | "stage-2"
6 | ]
7 | }
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "parser": "babel-eslint",
3 | "env" : {
4 | "browser": true
5 | },
6 | "rules" : {
7 | "no-class-assign" : 2,
8 | "no-confusing-arrow" : 0,
9 | "no-const-assign" : 2,
10 | "no-dupe-class-members" : 2,
11 | "no-new-symbol" : 2,
12 | "no-this-before-super" : 2,
13 | "no-useless-constructor" : 2,
14 | "no-var" : 2,
15 | "arrow-body-style" : [2, "as-needed"],
16 | "arrow-parens" : 0,
17 | "arrow-spacing" : [
18 | 2,
19 | {
20 | "before": true,
21 | "after" : true
22 | }
23 | ],
24 | "constructor-super" : 2,
25 | "object-shorthand" : [2, "always"],
26 | "prefer-arrow-callback" : 2,
27 | "prefer-const" : 2,
28 | "prefer-rest-params" : 2,
29 | "prefer-spread" : 2,
30 | "prefer-template" : 1,
31 | "template-curly-spacing" : [2, "always"],
32 | "strict" : 0,
33 | "new-cap" : 0,
34 | "eqeqeq" : 2,
35 | "curly" : 2,
36 | "quotes" : [1, "single"],
37 | "no-unreachable" : 2,
38 | "space-before-blocks" : 2,
39 | "space-before-function-paren": 2,
40 | "no-multi-spaces" : 0,
41 | "key-spacing" : 0,
42 | "no-mixed-requires" : 0
43 | }
44 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .DS_Store
3 | .idea
4 | *.log
5 | .nyc_output
6 | .nyc_cache
7 | /coverage
8 | /lib/*
9 | !/lib/.gitkeep
10 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | dist.js
2 | src
3 | test.js
4 | *.test.js
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js :
3 | - "iojs"
4 | deploy:
5 | provider: npm
6 | email: eduardo@comakai.com
7 | api_key:
8 | secure: JX1zgdfsP3rwISjl2mn6LNFOwNYcy2XIuL1mHXhAllDE5utvvaum8/zt/PWuBY7qlocGN8NZfjDsWc3PlDiezs9o0JZ0y0ipBgcPLPJJqbXc6U5EIVAUwnOMs7HorF1yz4S5T4GfBWwWfhFPr3setSHmRDTKyjmUBUqnvUj9Pq8=
9 | on:
10 | tags: true
11 | repo: coma/react-socket
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Eduardo García Sanz
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | react-socket
2 | ============
3 |
4 | [](https://travis-ci.org/coma/react-socket)
5 | [](http://david-dm.org/coma/react-socket)
6 | [](http://badge.fury.io/js/react-socket)
7 |
8 | A React wrapper for Socket.IO
9 |
10 | Usage
11 | -----
12 |
13 | Just mount a socket on one of your components:
14 |
15 | ```javascript
16 | var React = require('react'),
17 | Socket = require('react-socket').Socket;
18 |
19 | module.exports = module.exports = React.createClass({
20 | render: function () {
21 |
22 | return (
23 |
24 |
25 |
26 | );
27 | }
28 | });
29 | ```
30 |
31 | and then start listening to it:
32 |
33 | ```javascript
34 | var React = require('react'),
35 | SocketEvent = require('react-socket').Event;
36 |
37 | module.exports = module.exports = React.createClass({
38 | onSocketMessage: function (message) {
39 |
40 | ...
41 | },
42 | render: function () {
43 |
44 | return (
45 |
46 |
47 |
48 | );
49 | }
50 | });
51 | ```
52 |
53 | Use the name property to mount more than one socket:
54 |
55 | ```javascript
56 | var React = require('react'),
57 | Socket = require('react-socket');
58 |
59 | module.exports = module.exports = React.createClass({
60 | render: function () {
61 |
62 | return (
63 |
64 |
65 |
66 |
67 |
68 |
69 | );
70 | }
71 | });
72 | ```
73 |
74 | Every mounted socket gets disconnect before its component gets unmounted and the same goes to the events.
--------------------------------------------------------------------------------
/dist.js:
--------------------------------------------------------------------------------
1 | !function(e){function t(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,t),o.l=!0,o.exports}var n={};return t.m=e,t.c=n,t.i=function(e){return e},t.d=function(e,t,n){Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:n})},t.n=function(e){var n=e&&e.__esModule?function(){return e["default"]}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=35)}([function(e,t){function n(){throw new Error("setTimeout has not been defined")}function r(){throw new Error("clearTimeout has not been defined")}function o(e){if(l===setTimeout)return setTimeout(e,0);if((l===n||!l)&&setTimeout)return l=setTimeout,setTimeout(e,0);try{return l(e,0)}catch(t){try{return l.call(null,e,0)}catch(t){return l.call(this,e,0)}}}function i(e){if(p===clearTimeout)return clearTimeout(e);if((p===r||!p)&&clearTimeout)return p=clearTimeout,clearTimeout(e);try{return p(e)}catch(t){try{return p.call(null,e)}catch(t){return p.call(this,e)}}}function a(){v&&d&&(v=!1,d.length?y=d.concat(y):h=-1,y.length&&u())}function u(){if(!v){var e=o(a);v=!0;for(var t=y.length;t;){for(d=y,y=[];++h1)for(var n=1;n1?t-1:0),r=1;r2?r-2:0),i=2;i1){for(var N=Array(b),_=0;_1){for(var N=Array(b),_=0;_.")}return t}function i(e,n){if(e._store&&!e._store.validated&&null==e.key){e._store.validated=!0;var r=h.uniqueKey||(h.uniqueKey={}),i=o(n);if(!r[i]){r[i]=!0;var a="";e&&e._owner&&e._owner!==c.current&&(a=" It was passed a child from "+e._owner.getName()+"."),"production"!==t.env.NODE_ENV?v(!1,'Each child in an array or iterator should have a unique "key" prop.%s%s See https://fb.me/react-warning-keys for more information.%s',i,a,s.getCurrentStackAddendum(e)):void 0}}}function a(e,t){if("object"==typeof e)if(Array.isArray(e))for(var n=0;n1?u-1:0),s=1;s>",k={array:a("array"),bool:a("boolean"),func:a("function"),number:a("number"),object:a("object"),string:a("string"),symbol:a("symbol"),any:u(),arrayOf:c,element:s(),instanceOf:l,node:y(),objectOf:f,oneOf:p,oneOfType:d,shape:v};o.prototype=Error.prototype,e.exports=k}).call(t,n(0))},function(e,t,n){"use strict";function r(e,t,n){this.props=e,this.context=t,this.refs=c,this.updater=n||u}function o(){}var i=n(5),a=n(9),u=n(11),c=n(8);o.prototype=a.prototype,r.prototype=new o,r.prototype.constructor=r,i(r.prototype,a.prototype),r.prototype.isPureReactComponent=!0,e.exports=r},function(e,t){"use strict";e.exports="15.3.1"},function(e,t,n){"use strict";(function(t){function r(e,r,p,f,d,y){for(var v in e)if(e.hasOwnProperty(v)){var h;try{"function"!=typeof e[v]?"production"!==t.env.NODE_ENV?c(!1,"%s: %s type `%s` is invalid; it must be a function, usually from React.PropTypes.",f||"React class",a[p],v):i("84",f||"React class",a[p],v):void 0,h=e[v](r,v,f,p,null,u)}catch(m){h=m}if("production"!==t.env.NODE_ENV?s(!h||h instanceof Error,"%s: type specification of %s `%s` is invalid; the type checker function must return `null` or an `Error` but returned a %s. You may have forgotten to pass an argument to the type checker creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and shape all require an argument).",f||"React class",a[p],v,typeof h):void 0,h instanceof Error&&!(h.message in l)){l[h.message]=!0;var E="";"production"!==t.env.NODE_ENV&&(o||(o=n(10)),null!==y?E=o.getStackAddendumByID(y):null!==d&&(E=o.getCurrentStackAddendum(d))),"production"!==t.env.NODE_ENV?s(!1,"Failed %s type: %s%s",p,h.message,E):void 0}}}var o,i=n(4),a=n(12),u=n(19),c=n(2),s=n(1);"undefined"!=typeof t&&t.env&&"test"===t.env.NODE_ENV&&(o=n(10));var l={};e.exports=r}).call(t,n(0))},function(e,t,n){"use strict";(function(t){function r(e){return i.isValidElement(e)?void 0:"production"!==t.env.NODE_ENV?a(!1,"React.Children.only expected to receive a single React element child."):o("143"),e}var o=n(4),i=n(3),a=n(2);e.exports=r}).call(t,n(0))},function(e,t,n){"use strict";(function(t){function r(e,t){return e&&"object"==typeof e&&null!=e.key?p.escape(e.key):t.toString(36)}function o(e,n,i,h){var m=typeof e;if("undefined"!==m&&"boolean"!==m||(e=null),null===e||"string"===m||"number"===m||c.isValidElement(e))return i(h,e,""===n?d+r(e,0):n),1;var E,g,b=0,N=""===n?d:n+y;if(Array.isArray(e))for(var _=0;_ SOCKETS.hasOwnProperty(name);
8 |
9 | export const get = (name = NAME) => {
10 |
11 | if (!has(name)) {
12 |
13 | throw new Error(`There is no "${ name }" socket mounted.`);
14 | }
15 |
16 | return SOCKETS[name];
17 | };
18 |
19 | class Socket extends Component {
20 |
21 | componentWillMount () {
22 |
23 | const {name, url, options} = this.props;
24 |
25 | if (has(name)) {
26 |
27 | throw new Error(`Another "${ name }" socket is already mounted.`);
28 | }
29 |
30 | SOCKETS[name] = io(url, options);
31 | }
32 |
33 | componentWillUnmount () {
34 |
35 | const {name} = this.props;
36 |
37 | SOCKETS[name].disconnect();
38 | delete SOCKETS[name];
39 | }
40 |
41 | render () {
42 |
43 | return false;
44 | }
45 | }
46 |
47 | Socket.displayName = 'Socket';
48 |
49 | Socket.propTypes = {
50 | url : PropTypes.string,
51 | name : PropTypes.string,
52 | options: PropTypes.object
53 | };
54 |
55 | Socket.defaultProps = {
56 | url : '/',
57 | name: NAME
58 | };
59 |
60 | export default Socket;
--------------------------------------------------------------------------------
/test.js:
--------------------------------------------------------------------------------
1 | const path = require('path'),
2 | glob = require('glob'),
3 | tape = require('tape'),
4 | report = require('faucet'),
5 | ignore = require('ignore-styles');
6 |
7 | tape
8 | .createStream()
9 | .pipe(report())
10 | .pipe(process.stdout);
11 |
12 | let files = process.argv.slice(2);
13 |
14 | if (files.length < 1) {
15 |
16 | files = glob.sync('src/**/*.test.js');
17 | }
18 |
19 | files.map(file => require(path.resolve(__dirname, file)));
--------------------------------------------------------------------------------