├── .babelrc
├── .browserslistrc
├── .github
├── dependabot.yml
└── workflows
│ ├── TestOnPushPR.yml
│ └── codeql-analysis.yml
├── .gitignore
├── .npmignore
├── LICENSE
├── README.md
├── config
└── setup.js
├── dist
└── index.js
├── lib
├── __tests__
│ └── index.test.js
└── index.js
├── package.json
└── yarn.lock
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["@babel/preset-env", "@babel/preset-react", "minify"]
3 | }
--------------------------------------------------------------------------------
/.browserslistrc:
--------------------------------------------------------------------------------
1 | defaults
2 | not ie 11
3 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: "npm"
4 | directory: "/"
5 | schedule:
6 | interval: "weekly"
7 | versioning-strategy: increase
8 |
--------------------------------------------------------------------------------
/.github/workflows/TestOnPushPR.yml:
--------------------------------------------------------------------------------
1 | name: Test commit on push and pr
2 |
3 | on: [push, pull_request]
4 |
5 | jobs:
6 | test:
7 | runs-on: ubuntu-latest
8 | steps:
9 | - name: Checkout branch
10 | uses: actions/checkout@v2
11 |
12 | - name: Install
13 | run: yarn
14 |
15 | - name: Test
16 | run: yarn test
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/.github/workflows/codeql-analysis.yml:
--------------------------------------------------------------------------------
1 | # For most projects, this workflow file will not need changing; you simply need
2 | # to commit it to your repository.
3 | #
4 | # You may wish to alter this file to override the set of languages analyzed,
5 | # or to provide custom queries or build logic.
6 | #
7 | # ******** NOTE ********
8 | # We have attempted to detect the languages in your repository. Please check
9 | # the `language` matrix defined below to confirm you have the correct set of
10 | # supported CodeQL languages.
11 | #
12 | name: "CodeQL"
13 |
14 | on:
15 | push:
16 | branches: [ master ]
17 | pull_request:
18 | # The branches below must be a subset of the branches above
19 | branches: [ master ]
20 | schedule:
21 | - cron: '21 11 * * 3'
22 |
23 | jobs:
24 | analyze:
25 | name: Analyze
26 | runs-on: ubuntu-latest
27 | permissions:
28 | actions: read
29 | contents: read
30 | security-events: write
31 |
32 | strategy:
33 | fail-fast: false
34 | matrix:
35 | language: [ 'javascript' ]
36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
37 | # Learn more about CodeQL language support at https://git.io/codeql-language-support
38 |
39 | steps:
40 | - name: Checkout repository
41 | uses: actions/checkout@v2
42 |
43 | # Initializes the CodeQL tools for scanning.
44 | - name: Initialize CodeQL
45 | uses: github/codeql-action/init@v1
46 | with:
47 | languages: ${{ matrix.language }}
48 | # If you wish to specify custom queries, you can do so here or in a config file.
49 | # By default, queries listed here will override any specified in a config file.
50 | # Prefix the list here with "+" to use these queries and those in the config file.
51 | # queries: ./path/to/local/query, your-org/your-repo/queries@main
52 |
53 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
54 | # If this step fails, then you should remove it and run the build manually (see below)
55 | - name: Autobuild
56 | uses: github/codeql-action/autobuild@v1
57 |
58 | # ℹ️ Command-line programs to run using the OS shell.
59 | # 📚 https://git.io/JvXDl
60 |
61 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
62 | # and modify them (or add more) to build your code if your project
63 | # uses a compiled language
64 |
65 | #- run: |
66 | # make bootstrap
67 | # make release
68 |
69 | - name: Perform CodeQL Analysis
70 | uses: github/codeql-action/analyze@v1
71 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 |
6 | # Runtime data
7 | pids
8 | *.pid
9 | *.seed
10 |
11 | # Directory for instrumented libs generated by jscoverage/JSCover
12 | lib-cov
13 |
14 | # Coverage directory used by tools like istanbul
15 | coverage
16 |
17 | # nyc test coverage
18 | .nyc_output
19 |
20 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
21 | .grunt
22 |
23 | # node-waf configuration
24 | .lock-wscript
25 |
26 | # Compiled binary addons (http://nodejs.org/api/addons.html)
27 | build/Release
28 |
29 | # Dependency directories
30 | node_modules
31 | jspm_packages
32 |
33 | # Optional npm cache directory
34 | .npm
35 |
36 | # Optional REPL history
37 | .node_repl_history
38 | .DS_Store
39 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | .babelrc
2 | .npmignore
3 | /config/
4 | yarn.lock
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Li Jie
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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ActionCable Provider for React
2 |
3 | This package provides an ActionCable context provider and consumer to allow you to subscribe to ActionCable channels in your React components.
4 |
5 | ## Requirements
6 |
7 | As this package uses React's new Context API, **React 16.3+ is required**.
8 |
9 | Run `npx browserslist` to see `default, not ie 11` option in `.browserslistrc` [compatibility](https://browserl.ist/?q=defaults). There is no IE 11 support starting in version 4.0.0.
10 |
11 | ## Install
12 |
13 | ```shell
14 | npm install --save @thrash-industries/react-actioncable-provider
15 | # OR
16 | yarn add @thrash-industries/react-actioncable-provider
17 | ```
18 |
19 | ## Usage
20 |
21 | The public API exports two components that you'll use: `` and ``.
22 |
23 | ### ``
24 |
25 | The provider is used in an outer container and wraps all of the components that may or may not consume the context. It accepts one of two props: `url` and `cable`. Passing `url` will result in the provider instantiating its own `ActionCable.Consumer` with that URL. Passing `cable` allows you to manually instantiate an `ActionCable.Consumer` on your own and pass it to the provider to be used by all descendent consumers.
26 |
27 | #### With `url`
28 |
29 | ```jsx
30 | ...
31 | ```
32 |
33 | #### With `cable`
34 |
35 | ```jsx
36 | import ActionCable from "actioncable";
37 |
38 | const cable = ActionCable.createConsumer("ws://test.example.com/cable");
39 |
40 | ...;
41 | ```
42 |
43 | ### ``
44 |
45 | The consumer will wrap an individual component. It accepts several props:
46 |
47 | - `channel` [String] Name of the channel to which you want to subscribe.
48 | - `channel` [Object] An object with a `channel` key which denotes the channel to which you want to subscribe. All other keys are passed to the channel as params.
49 | - `onConnected` [Function] A handler function that is called when the channel connects.
50 | - `onDisconnected` [Function] A handler function that is called when the channel disconnects.
51 | - `onInitialized` [Function] A handler function that is called when the `ActionCable`.`Consumer` is initialized.
52 | - `onRejected` [Function] A handler function that is called when the requested subscription is rejected.
53 | - `onReceived` [Function] A handler function that is called when the channel transmits a message to the client.
54 |
55 | ```jsx
56 | import React from "react";
57 | import PropTypes from "prop-types";
58 | import { ActionCableConsumer } from "@thrash-industries/react-actioncable-provider";
59 |
60 | export default class Widget extends React.Component {
61 | static propTypes = {
62 | message: PropTypes.string
63 | };
64 |
65 | constructor(...props) {
66 | super(...props);
67 |
68 | this.handleReceived = this.handleReceived.bind(this);
69 |
70 | this.state = {
71 | message: ""
72 | };
73 | }
74 |
75 | handleReceived(message) {
76 | this.setState(state => {
77 | return {
78 | message
79 | };
80 | });
81 | }
82 |
83 | render() {
84 | return (
85 |
89 | {this.state.message}
90 |
91 | );
92 | }
93 | }
94 | ```
95 |
96 | ## Publishing
97 |
98 | - `yarn` Install dependencies
99 | - `yarn test` Run tests
100 | - `yarn build` Build for production
101 | - `npm version [patch|minor|major]` Increment version
102 | - `npm publish` Publish to npm
103 | ## Other Uses
104 |
105 | ### React Native
106 |
107 | See https://github.com/cpunion/react-native-actioncable
108 |
109 | ### Server Side Rendering
110 |
111 | See https://github.com/cpunion/react-actioncable-provider/issues/8
112 |
113 | Example: https://github.com/cpunion/react-actioncable-ssr-example
114 |
--------------------------------------------------------------------------------
/config/setup.js:
--------------------------------------------------------------------------------
1 | import Enzyme from 'enzyme';
2 | import Adapter from 'enzyme-adapter-react-16';
3 |
4 | Enzyme.configure({ adapter: new Adapter() });
5 |
6 | const { JSDOM } = require('jsdom');
7 |
8 | const jsdom = new JSDOM('
');
9 | const { window } = jsdom;
10 |
11 | function copyProps(src, target) {
12 | const props = Object.getOwnPropertyNames(src)
13 | .filter(prop => typeof target[prop] === 'undefined')
14 | .reduce(
15 | (result, prop) => ({
16 | ...result,
17 | [prop]: Object.getOwnPropertyDescriptor(src, prop)
18 | }),
19 | {}
20 | );
21 | Object.defineProperties(target, props);
22 | }
23 |
24 | global.window = window;
25 | global.document = window.document;
26 | global.navigator = {
27 | userAgent: 'node.js'
28 | };
29 | copyProps(window, global);
30 |
--------------------------------------------------------------------------------
/dist/index.js:
--------------------------------------------------------------------------------
1 | "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var React=require("react"),PropTypes=require("prop-types"),actioncable=require("actioncable"),{Provider,Consumer}=React.createContext();class ActionCableProvider extends React.Component{UNSAFE_componentWillMount=function(){this.cable=this.props.cable?this.props.cable:actioncable.createConsumer(this.props.url)};componentWillUnmount=function(){!this.props.cable&&this.cable&&this.cable.disconnect()};UNSAFE_componentWillReceiveProps=function(a){// Props not changed
2 | this.props.cable===a.cable&&this.props.url===a.url||(// cable is created by self, disconnect it
3 | // create or assign cable
4 | this.componentWillUnmount(),this.UNSAFE_componentWillMount())};render=function(){return React.createElement(Provider,{value:{cable:this.cable}},this.props.children||null)}}ActionCableProvider.displayName="ActionCableProvider",ActionCableProvider.propTypes={cable:PropTypes.object,url:PropTypes.string,children:PropTypes.any};class ActionCableController extends React.Component{componentDidMount=function(){this.connectToChannel()};connectToChannel=function(){var a=this.props,b=a.onReceived,c=a.onInitialized,d=a.onConnected,e=a.onDisconnected,f=a.onRejected;this.cable=this.props.cable.subscriptions.create(this.props.channel,{received:function(a){b&&b(a)},initialized:function(){c&&c()},connected:function(){d&&d()},disconnected:function(){e&&e()},rejected:function(){f&&f()}})};disconnectFromChannel=function(){this.cable&&(this.props.cable.subscriptions.remove(this.cable),this.cable=null)};componentDidUpdate=function(a){JSON.stringify(a.channel)!==JSON.stringify(this.props.channel)&&(this.disconnectFromChannel(),this.connectToChannel())};componentWillUnmount=function(){this.disconnectFromChannel()};send=function(a){if(!this.cable)throw new Error("ActionCable component unloaded");this.cable.send(a)};perform=function(a,b){if(!this.cable)throw new Error("ActionCable component unloaded");this.cable.perform(a,b)};render=function(){return this.props.children||null}}ActionCableController.displayName="ActionCableController",ActionCableController.propTypes={cable:PropTypes.object,onReceived:PropTypes.func,onInitialized:PropTypes.func,onConnected:PropTypes.func,onDisconnected:PropTypes.func,onRejected:PropTypes.func,children:PropTypes.any};class Component extends React.Component{render=function(){return React.createElement(Consumer,null,a=>{let{cable:b}=a;return React.createElement(ActionCableController,{cable:b,...this.props,ref:this.props.forwardedRef},this.props.children||null)})}}Component.displayName="ActionCableConsumer",Component.propTypes={onReceived:PropTypes.func,onInitialized:PropTypes.func,onConnected:PropTypes.func,onDisconnected:PropTypes.func,onRejected:PropTypes.func,children:PropTypes.any};var ActionCableConsumer=React.forwardRef(function(a,b){return React.createElement(Component,{...a,forwardedRef:b},a.children||null)});class ActionCable extends React.Component{componentDidMount=function(){console.warn("DEPRECATION WARNING: The component has been deprecated and will be removed in a future release. Use instead.")};render=function(){return React.createElement(ActionCableConsumer,{...this.props},this.props.children||null)}}// Compatible old usage
5 | ActionCable.displayName="ActionCable",ActionCable.propTypes={onReceived:PropTypes.func,onInitialized:PropTypes.func,onConnected:PropTypes.func,onDisconnected:PropTypes.func,onRejected:PropTypes.func,children:PropTypes.any},exports.ActionCable=ActionCable,exports.ActionCableConsumer=ActionCableConsumer,exports.ActionCableController=ActionCableController,exports.ActionCableProvider=ActionCableProvider,exports.default=ActionCableProvider;
--------------------------------------------------------------------------------
/lib/__tests__/index.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { shallow, mount } from 'enzyme';
3 | import actioncable from 'actioncable';
4 | import {
5 | ActionCableProvider,
6 | ActionCableConsumer,
7 | ActionCableController
8 | } from '../index';
9 |
10 | describe(ActionCableProvider, () => {
11 | describe('with children', () => {
12 | it('renders children', () => {
13 | const node = shallow(
14 |
15 | Child
16 |
17 | );
18 |
19 | expect(node.children()).toHaveLength(1);
20 | });
21 | });
22 |
23 | describe('with no children', () => {
24 | it('renders null', () => {
25 | const node = shallow();
26 |
27 | expect(node.children()).toHaveLength(0);
28 | });
29 | });
30 | });
31 |
32 | describe('ActionCableConsumer', () => {
33 | describe('wrapped with ForwardRef', () => {
34 | it('renders the ForwardRef', () => {
35 | const node = shallow(
36 |
37 |
38 |
39 | );
40 |
41 | expect(node.find('ForwardRef')).toHaveLength(1);
42 | });
43 |
44 | it('renders the consumer', () => {
45 | const node = mount(
46 |
47 |
48 |
49 | );
50 |
51 | const consumer = node.find('ActionCableConsumer');
52 |
53 | expect(consumer).toHaveLength(1);
54 | });
55 |
56 | it('renders the controller', () => {
57 | const node = mount(
58 |
59 |
60 |
61 | );
62 |
63 | const controller = node.find('ActionCableController');
64 |
65 | expect(controller).toHaveLength(1);
66 | });
67 | });
68 | });
69 |
70 | describe('ActionCableController', () => {
71 | describe('with cable passed to provider', () => {
72 | it('passes cable to the controller as a prop', () => {
73 | const cable = actioncable.createConsumer('ws://test.example.com/cable');
74 |
75 | const node = mount(
76 |
77 |
78 |
79 | );
80 |
81 | const controller = node.find('ActionCableController');
82 |
83 | expect(controller.prop('cable')).toStrictEqual(cable);
84 | });
85 |
86 | describe('with children', () => {
87 | it('renders children', () => {
88 | const cable = actioncable.createConsumer('ws://test.example.com/cable');
89 |
90 | const node = mount(
91 |
92 |
93 | Child
94 |
95 |
96 | );
97 |
98 | const controller = node.find('ActionCableController');
99 |
100 | expect(controller.children()).toHaveLength(1);
101 | });
102 | });
103 |
104 | describe('without children', () => {
105 | it('renders null', () => {
106 | const cable = actioncable.createConsumer('ws://test.example.com/cable');
107 |
108 | const node = mount(
109 |
110 | >
111 |
112 | );
113 |
114 | const controller = node.find('ActionCableController');
115 |
116 | expect(controller.children()).toHaveLength(0);
117 | });
118 | });
119 | });
120 | });
121 |
--------------------------------------------------------------------------------
/lib/index.js:
--------------------------------------------------------------------------------
1 | "use strict"
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | })
6 |
7 | var React = require("react")
8 | var PropTypes = require("prop-types")
9 | var actioncable = require("actioncable")
10 | var { Provider, Consumer } = React.createContext()
11 |
12 | class ActionCableProvider extends React.Component {
13 | UNSAFE_componentWillMount = function () {
14 | if (this.props.cable) {
15 | this.cable = this.props.cable
16 | } else {
17 | this.cable = actioncable.createConsumer(this.props.url)
18 | }
19 | }
20 |
21 | componentWillUnmount = function () {
22 | if (!this.props.cable && this.cable) {
23 | this.cable.disconnect()
24 | }
25 | }
26 |
27 | UNSAFE_componentWillReceiveProps = function (nextProps) {
28 | // Props not changed
29 | if (
30 | this.props.cable === nextProps.cable &&
31 | this.props.url === nextProps.url
32 | ) {
33 | return
34 | }
35 |
36 | // cable is created by self, disconnect it
37 | this.componentWillUnmount()
38 |
39 | // create or assign cable
40 | this.UNSAFE_componentWillMount()
41 | }
42 |
43 | render = function () {
44 | return React.createElement(
45 | Provider,
46 | {
47 | value: {
48 | cable: this.cable
49 | }
50 | },
51 | this.props.children || null
52 | )
53 | }
54 | }
55 |
56 | ActionCableProvider.displayName = "ActionCableProvider"
57 |
58 | ActionCableProvider.propTypes = {
59 | cable: PropTypes.object,
60 | url: PropTypes.string,
61 | children: PropTypes.any
62 | }
63 |
64 | class ActionCableController extends React.Component {
65 | componentDidMount = function () {
66 | this.connectToChannel()
67 | }
68 | connectToChannel = function () {
69 | var self = this
70 | var _props = this.props
71 |
72 | var onReceived = _props.onReceived
73 |
74 | var onInitialized = _props.onInitialized
75 |
76 | var onConnected = _props.onConnected
77 |
78 | var onDisconnected = _props.onDisconnected
79 |
80 | var onRejected = _props.onRejected
81 |
82 | this.cable = this.props.cable.subscriptions.create(this.props.channel, {
83 | received: function (data) {
84 | onReceived && onReceived(data)
85 | },
86 | initialized: function () {
87 | onInitialized && onInitialized()
88 | },
89 | connected: function () {
90 | onConnected && onConnected()
91 | },
92 | disconnected: function () {
93 | onDisconnected && onDisconnected()
94 | },
95 | rejected: function () {
96 | onRejected && onRejected()
97 | }
98 | })
99 | }
100 | disconnectFromChannel = function() {
101 | if (this.cable) {
102 | this.props.cable.subscriptions.remove(this.cable)
103 | this.cable = null
104 | }
105 | }
106 | componentDidUpdate = function(prevProps) {
107 | if (
108 | JSON.stringify(prevProps.channel) !== JSON.stringify(this.props.channel)
109 | ) {
110 | this.disconnectFromChannel()
111 | this.connectToChannel()
112 | }
113 | }
114 | componentWillUnmount = function () {
115 | this.disconnectFromChannel()
116 | }
117 |
118 | send = function (data) {
119 | if (!this.cable) {
120 | throw new Error("ActionCable component unloaded")
121 | }
122 |
123 | this.cable.send(data)
124 | }
125 |
126 | perform = function (action, data) {
127 | if (!this.cable) {
128 | throw new Error("ActionCable component unloaded")
129 | }
130 |
131 | this.cable.perform(action, data)
132 | }
133 |
134 | render = function () {
135 | return this.props.children || null
136 | }
137 | }
138 |
139 | ActionCableController.displayName = "ActionCableController"
140 |
141 | ActionCableController.propTypes = {
142 | cable: PropTypes.object,
143 | onReceived: PropTypes.func,
144 | onInitialized: PropTypes.func,
145 | onConnected: PropTypes.func,
146 | onDisconnected: PropTypes.func,
147 | onRejected: PropTypes.func,
148 | children: PropTypes.any
149 | }
150 |
151 | class Component extends React.Component {
152 | render = function () {
153 | return React.createElement(Consumer, null, ({ cable }) => {
154 | return React.createElement(
155 | ActionCableController,
156 | {
157 | cable,
158 | ...this.props,
159 | ref: this.props.forwardedRef
160 | },
161 | this.props.children || null
162 | )
163 | })
164 | }
165 | }
166 |
167 | Component.displayName = "ActionCableConsumer"
168 |
169 | Component.propTypes = {
170 | onReceived: PropTypes.func,
171 | onInitialized: PropTypes.func,
172 | onConnected: PropTypes.func,
173 | onDisconnected: PropTypes.func,
174 | onRejected: PropTypes.func,
175 | children: PropTypes.any
176 | }
177 |
178 | var ActionCableConsumer = React.forwardRef(function (props, ref) {
179 | return React.createElement(
180 | Component,
181 | {
182 | ...props,
183 | forwardedRef: ref
184 | },
185 | props.children || null
186 | )
187 | })
188 |
189 | class ActionCable extends React.Component {
190 | componentDidMount = function () {
191 | console.warn(
192 | "DEPRECATION WARNING: The component has been deprecated and will be removed in a future release. Use instead."
193 | )
194 | }
195 | render = function () {
196 | return React.createElement(
197 | ActionCableConsumer,
198 | { ...this.props },
199 | this.props.children || null
200 | )
201 | }
202 | }
203 |
204 | ActionCable.displayName = "ActionCable"
205 |
206 | ActionCable.propTypes = {
207 | onReceived: PropTypes.func,
208 | onInitialized: PropTypes.func,
209 | onConnected: PropTypes.func,
210 | onDisconnected: PropTypes.func,
211 | onRejected: PropTypes.func,
212 | children: PropTypes.any
213 | }
214 |
215 | exports.ActionCable = ActionCable
216 | exports.ActionCableConsumer = ActionCableConsumer
217 | exports.ActionCableController = ActionCableController
218 | exports.ActionCableProvider = ActionCableProvider
219 |
220 | // Compatible old usage
221 | exports.default = ActionCableProvider
222 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@thrash-industries/react-actioncable-provider",
3 | "version": "4.0.3",
4 | "description": "ActionCable Provider for React",
5 | "main": "dist/index.js",
6 | "scripts": {
7 | "test": "jest --coverage",
8 | "test:watch": "jest --watch",
9 | "build": "babel lib/index.js --out-dir dist"
10 | },
11 | "repository": {
12 | "type": "git",
13 | "url": "git+https://github.com/JackHowa/react-actioncable-provider"
14 | },
15 | "keywords": [
16 | "ActionCable",
17 | "react",
18 | "Rails",
19 | "WebSockets"
20 | ],
21 | "files": [
22 | "dist/index.js"
23 | ],
24 | "author": "Li Jie ",
25 | "contributors": [
26 | "jackhowa ",
27 | "hashwin"
28 | ],
29 | "license": "MIT",
30 | "bugs": {
31 | "url": "https://github.com/JackHowa/react-actioncable-provider/issues"
32 | },
33 | "homepage": "https://github.com/JackHowa/react-actioncable-provider",
34 | "dependencies": {
35 | "actioncable": "^5.2.8",
36 | "prop-types": "^15.8.1",
37 | "react": "^16.9.0"
38 | },
39 | "devDependencies": {
40 | "@babel/cli": "^7.24.8",
41 | "@babel/core": "^7.25.2",
42 | "@babel/preset-env": "^7.25.3",
43 | "@babel/preset-react": "^7.24.7",
44 | "babel-jest": "^29.7.0",
45 | "babel-preset-minify": "^0.5.2",
46 | "chai": "^5.1.1",
47 | "enzyme": "^3.7.0",
48 | "enzyme-adapter-react-16": "^1.15.8",
49 | "jest": "^26.6.3",
50 | "react-dom": "^16.9.0",
51 | "react-test-renderer": "^16.9.0"
52 | },
53 | "jest": {
54 | "verbose": true,
55 | "collectCoverageFrom": [
56 | "lib/**/*.{js,jsx}"
57 | ],
58 | "coverageDirectory": "coverage",
59 | "setupFiles": [
60 | "/config/setup.js"
61 | ],
62 | "testPathIgnorePatterns": [
63 | "/(build|docs|node_modules)/"
64 | ]
65 | },
66 | "directories": {
67 | "lib": "lib"
68 | }
69 | }
70 |
--------------------------------------------------------------------------------