-
Notifications
You must be signed in to change notification settings - Fork 2
/
index.js
148 lines (130 loc) · 3.09 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import React, { Component, Children } from 'react';
import PropTypes from 'prop-types';
/**
* Helper component to work with the various of readyStates of a Primus
* connection. The `loading` component will only display it's contents when
* Primus is still opening the connection.
*
* @constructor
* @public
*/
export class Loading extends Component {
render() {
if (this.ctx.primus.readyState === Primus.OPEN) return null;
return Children.only(this.props.children);
}
}
/**
* Helper component to work with the various of readyStates of a Primus
* connection. The `loaded` component will only display it's contents when
* Primus is the connection is open.
*
* @constructor
* @public
*/
export class Loaded extends Component {
render() {
if (this.ctx.primus.readyState !== Primus.OPEN) return null;
return Children.only(this.props.children);
}
}
/**
* React based wrapper to share a single Primus connection between all child
* components. The only assumption this component makes is that there is
* a Primus global available once the component is mounted.
*
* @constructor
* @public
*/
export default class Ironhide extends Component {
constructor() {
super(...arguments);
this.primus = null; // Reference to the internal Primus instance.
}
/**
* Open a new Primus connection.
*
* @private
*/
open() {
const { url, config } = this.props;
//
// Prevent multiple connections from being opened at the same time.
//
if (this.primus) this.close();
this.primus = new Primus(url, {
...config,
//
// The following options are forced to ensure that we establish
// a connection that we can work with.
//
manual: false // Prevent manual opening of the connection.
});
}
/**
* Close and cleanup existing connections.
*
* @private
*/
close() {
try { this.primus.destroy(); }
catch (e) {}
this.primus = null;
}
/**
* Open the connection once the component is mounted.
*
* @private
*/
componentDidMount() {
this.open();
}
/**
* Close the connection once we're about to unmount the application.
*
* @private
*/
componentWillUnmount() {
this.close();
}
/**
* This is where the actual magic happens, we provide React with an object of
* "immutable" data or methods which is passed to the child components using
* `the this.ctx` object.
*
* @private
*/
getChildContext() {
return {
primus: this.primus
};
}
/**
* Render only the passed in children so we can work as an active wrapper.
*
* @returns {Component}
* @private
*/
render() {
return this.props.children;
}
}
/**
* Validation for the shared context object.
*
* @type {Object} Identical structure to what is returned by `getChildContext`.
* @private
*/
Ironhide.context = {
primus: PropTypes.object
};
/**
* Properties that are accepted by this component.
*
* @private
*/
Ironhide.propTypes = {
children: PropTypes.element.isRequired,
url: PropTypes.string.isRequired,
config: PropTypes.object
};