├── .gitattributes ├── tests ├── .eslintrc └── index-test.js ├── .gitignore ├── nwb.config.js ├── README.md ├── LICENSE ├── src └── index.js ├── package.json └── demo └── src └── index.js /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto -------------------------------------------------------------------------------- /tests/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "mocha": true 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | gh-pages/ 3 | dist-modules/ 4 | node_modules/ 5 | coverage/ 6 | npm-debug.log 7 | .eslintcache 8 | yarn.lock 9 | creds.json -------------------------------------------------------------------------------- /nwb.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | type: 'react-component', 3 | npm: { 4 | esModules: true, 5 | umd: { 6 | global: 'ReactEventSource', 7 | externals: { 8 | react: 'React' 9 | } 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tests/index-test.js: -------------------------------------------------------------------------------- 1 | import expect from 'expect' 2 | import React from 'react' 3 | import {render, unmountComponentAtNode} from 'react-dom' 4 | 5 | import Component from 'src/' 6 | 7 | describe('Component', () => { 8 | let node 9 | 10 | beforeEach(() => { 11 | node = document.createElement('div') 12 | }) 13 | 14 | afterEach(() => { 15 | unmountComponentAtNode(node) 16 | }) 17 | 18 | it('displays a welcome message', () => { 19 | render(, node, () => { 20 | expect(node.innerHTML).toContain('Welcome to React components') 21 | }) 22 | }) 23 | }) 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-eventsource 2 | 3 | > Connect your react components to any [EventSource](https://developer.mozilla.org/en-US/docs/Web/API/EventSource) 4 | 5 | ## Usage 6 | 7 | ```js 8 | import ReactEventSource from 'react-eventsource' 9 | 10 | const renderEvent = event =>
{ event }
11 | 12 | 13 | { events => events.map(renderEvent) } 14 | 15 | ``` 16 | 17 | By default, `ReactEventSource` will listen to `message` events. 18 | 19 | If you use custom message types, you can specify them using `types={['data', 'patch']}` 20 | 21 | You can pass your own `EventSource` using source prop `source={new EventSource(url)}`, 22 | 23 | See working demo with Live Bitcoin value update : http://revolunet.github.io/react-eventsource/#/demo 24 | 25 | ## Dev 26 | 27 | This project use [nwb](https://github.com/insin/nwb) 28 | 29 | 30 | ## License 31 | 32 | *react-eventsource* is available under MIT. See LICENSE for more details. 33 | 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 Julien Bouquillon 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import propIsRequiredIf from 'react-proptype-conditional-require'; 4 | 5 | class EventSourceHOC extends React.Component { 6 | 7 | state = { 8 | events: [] 9 | } 10 | 11 | componentDidMount() { 12 | // connect to the EventSource 13 | this.source = this.props.source ? this.props.source : new EventSource(this.props.url); 14 | const cb = message => { 15 | this.setState(prevState => { 16 | let newEvents = prevState.events.concat(message.data) 17 | return { 18 | events: newEvents 19 | } 20 | }); 21 | }; 22 | this.props.types.forEach(type => { 23 | this.source.addEventListener(type, cb, false); 24 | }); 25 | if (this.props.onEventSourceError) { 26 | this.source.onerror = this.props.onEventSourceError; 27 | } 28 | } 29 | componentWillUnmount() { 30 | this.source.close(); 31 | } 32 | render() { 33 | return
{ this.props.children(this.state.events) }
34 | } 35 | } 36 | 37 | EventSourceHOC.propTypes = { 38 | url: propIsRequiredIf(PropTypes.string, props => !props.hasOwnProperty('source')), 39 | source: propIsRequiredIf(PropTypes.object, props => !props.hasOwnProperty('url')), 40 | onEventSourceError: PropTypes.func, 41 | types: PropTypes.array, 42 | children: PropTypes.func.isRequired 43 | }; 44 | 45 | EventSourceHOC.defaultProps = { 46 | types: ['message'] 47 | }; 48 | 49 | export default EventSourceHOC; 50 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-eventsource", 3 | "description": "Connect react components to any EventSource", 4 | "author": "Julien Bouquillon ", 5 | "user": "revolunet", 6 | "version": "1.1.0", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/revolunet/react-eventsource.git" 10 | }, 11 | "homepage": "https://revolunet.github.io/react-eventsource/", 12 | "bugs": { 13 | "url": "https://github.com/revolunet/react-eventsource/issues" 14 | }, 15 | "keywords": [ 16 | "react", 17 | "react-component", 18 | "reactjs", 19 | "eventsource", 20 | "sse", 21 | "stream" 22 | ], 23 | "license": "MIT", 24 | "main": "lib/index.js", 25 | "module": "es/index.js", 26 | "files": [ 27 | "css", 28 | "es", 29 | "lib", 30 | "umd" 31 | ], 32 | "scripts": { 33 | "build": "nwb build-react-component", 34 | "clean": "nwb clean-module && nwb clean-demo", 35 | "start": "nwb serve-react-demo", 36 | "test": "nwb test-react", 37 | "test:coverage": "nwb test-react --coverage", 38 | "test:watch": "nwb test-react --server", 39 | "gh-pages": "gh-pages -d ./demo/dist" 40 | }, 41 | "dependencies": { 42 | "prop-types": "^15.5.10", 43 | "react-github-corner": "^0.3.0", 44 | "react-proptype-conditional-require": "^1.0.4" 45 | }, 46 | "peerDependencies": { 47 | "react": "15.x" 48 | }, 49 | "devDependencies": { 50 | "gh-pages": "^1.0.0", 51 | "nwb": "0.15.x", 52 | "react": "^15.5.4", 53 | "react-dom": "^15.5.4" 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /demo/src/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { render } from "react-dom"; 3 | import GithubCorner from "react-github-corner"; 4 | 5 | import ReactEventSource from "../../src"; 6 | 7 | const Entry = ({ title = "BTC value", value }) => ( 8 |
9 | {title} : {value} 10 |
11 | ); 12 | 13 | const BTCVolume = () => { 14 | return ( 15 | 16 | {events => { 17 | events.reverse(); 18 | return ( 19 |
20 |

21 | {events.length} events 22 |

23 | {events.map((e, i) => { 24 | const data = JSON.parse(e); 25 | return
{data.user}
; 26 | })} 27 |
28 | ); 29 | }} 30 |
31 | ); 32 | }; 33 | 34 | const Demo = () => { 35 | const style = { 36 | padding: 20 37 | }; 38 | return ( 39 |
40 | 48 |
49 |

Real-time wikipedia changes

50 |

This example use https://wikitech.wikimedia.org/wiki/EventStreams

51 |

What a while...

52 |

53 | See this example code on{" "} 54 | 55 | github 56 | 57 |

58 | 59 |
60 |
61 | ); 62 | }; 63 | 64 | render(, document.getElementById("demo")); 65 | --------------------------------------------------------------------------------