actioncable 5.0.0.1 → 5.0.1.rc1

Sign up to get free protection for your applications and to get access to all the features.
@@ -32,7 +32,11 @@ module ActionCable
32
32
  end
33
33
 
34
34
  def broadcast(channel, message)
35
- list = @sync.synchronize { @subscribers[channel].dup }
35
+ list = @sync.synchronize do
36
+ return if !@subscribers.key?(channel)
37
+ @subscribers[channel].dup
38
+ end
39
+
36
40
  list.each do |subscriber|
37
41
  invoke_callback(subscriber, message)
38
42
  end
@@ -1,590 +1,597 @@
1
1
  (function() {
2
- var slice = [].slice;
3
-
4
- this.ActionCable = {
5
- INTERNAL: {
6
- "message_types": {
7
- "welcome": "welcome",
8
- "ping": "ping",
9
- "confirmation": "confirm_subscription",
10
- "rejection": "reject_subscription"
11
- },
12
- "default_mount_path": "/cable",
13
- "protocols": ["actioncable-v1-json", "actioncable-unsupported"]
14
- },
15
- createConsumer: function(url) {
16
- var ref;
17
- if (url == null) {
18
- url = (ref = this.getConfig("url")) != null ? ref : this.INTERNAL.default_mount_path;
19
- }
20
- return new ActionCable.Consumer(this.createWebSocketURL(url));
21
- },
22
- getConfig: function(name) {
23
- var element;
24
- element = document.head.querySelector("meta[name='action-cable-" + name + "']");
25
- return element != null ? element.getAttribute("content") : void 0;
26
- },
27
- createWebSocketURL: function(url) {
28
- var a;
29
- if (url && !/^wss?:/i.test(url)) {
30
- a = document.createElement("a");
31
- a.href = url;
32
- a.href = a.href;
33
- a.protocol = a.protocol.replace("http", "ws");
34
- return a.href;
35
- } else {
36
- return url;
37
- }
38
- },
39
- startDebugging: function() {
40
- return this.debugging = true;
41
- },
42
- stopDebugging: function() {
43
- return this.debugging = null;
44
- },
45
- log: function() {
46
- var messages;
47
- messages = 1 <= arguments.length ? slice.call(arguments, 0) : [];
48
- if (this.debugging) {
49
- messages.push(Date.now());
50
- return console.log.apply(console, ["[ActionCable]"].concat(slice.call(messages)));
51
- }
52
- }
53
- };
54
-
55
- if (typeof window !== "undefined" && window !== null) {
56
- window.ActionCable = this.ActionCable;
57
- }
2
+ (function() {
3
+ (function() {
4
+ var slice = [].slice;
5
+
6
+ this.ActionCable = {
7
+ INTERNAL: {
8
+ "message_types": {
9
+ "welcome": "welcome",
10
+ "ping": "ping",
11
+ "confirmation": "confirm_subscription",
12
+ "rejection": "reject_subscription"
13
+ },
14
+ "default_mount_path": "/cable",
15
+ "protocols": ["actioncable-v1-json", "actioncable-unsupported"]
16
+ },
17
+ createConsumer: function(url) {
18
+ var ref;
19
+ if (url == null) {
20
+ url = (ref = this.getConfig("url")) != null ? ref : this.INTERNAL.default_mount_path;
21
+ }
22
+ return new ActionCable.Consumer(this.createWebSocketURL(url));
23
+ },
24
+ getConfig: function(name) {
25
+ var element;
26
+ element = document.head.querySelector("meta[name='action-cable-" + name + "']");
27
+ return element != null ? element.getAttribute("content") : void 0;
28
+ },
29
+ createWebSocketURL: function(url) {
30
+ var a;
31
+ if (url && !/^wss?:/i.test(url)) {
32
+ a = document.createElement("a");
33
+ a.href = url;
34
+ a.href = a.href;
35
+ a.protocol = a.protocol.replace("http", "ws");
36
+ return a.href;
37
+ } else {
38
+ return url;
39
+ }
40
+ },
41
+ startDebugging: function() {
42
+ return this.debugging = true;
43
+ },
44
+ stopDebugging: function() {
45
+ return this.debugging = null;
46
+ },
47
+ log: function() {
48
+ var messages;
49
+ messages = 1 <= arguments.length ? slice.call(arguments, 0) : [];
50
+ if (this.debugging) {
51
+ messages.push(Date.now());
52
+ return console.log.apply(console, ["[ActionCable]"].concat(slice.call(messages)));
53
+ }
54
+ }
55
+ };
58
56
 
59
- if (typeof module !== "undefined" && module !== null) {
60
- module.exports = this.ActionCable;
61
- }
57
+ }).call(this);
58
+ }).call(this);
62
59
 
63
- }).call(this);
64
- (function() {
65
- var bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
66
-
67
- ActionCable.ConnectionMonitor = (function() {
68
- var clamp, now, secondsSince;
69
-
70
- ConnectionMonitor.pollInterval = {
71
- min: 3,
72
- max: 30
73
- };
74
-
75
- ConnectionMonitor.staleThreshold = 6;
76
-
77
- function ConnectionMonitor(connection) {
78
- this.connection = connection;
79
- this.visibilityDidChange = bind(this.visibilityDidChange, this);
80
- this.reconnectAttempts = 0;
81
- }
82
-
83
- ConnectionMonitor.prototype.start = function() {
84
- if (!this.isRunning()) {
85
- this.startedAt = now();
86
- delete this.stoppedAt;
87
- this.startPolling();
88
- document.addEventListener("visibilitychange", this.visibilityDidChange);
89
- return ActionCable.log("ConnectionMonitor started. pollInterval = " + (this.getPollInterval()) + " ms");
90
- }
91
- };
92
-
93
- ConnectionMonitor.prototype.stop = function() {
94
- if (this.isRunning()) {
95
- this.stoppedAt = now();
96
- this.stopPolling();
97
- document.removeEventListener("visibilitychange", this.visibilityDidChange);
98
- return ActionCable.log("ConnectionMonitor stopped");
99
- }
100
- };
101
-
102
- ConnectionMonitor.prototype.isRunning = function() {
103
- return (this.startedAt != null) && (this.stoppedAt == null);
104
- };
105
-
106
- ConnectionMonitor.prototype.recordPing = function() {
107
- return this.pingedAt = now();
108
- };
109
-
110
- ConnectionMonitor.prototype.recordConnect = function() {
111
- this.reconnectAttempts = 0;
112
- this.recordPing();
113
- delete this.disconnectedAt;
114
- return ActionCable.log("ConnectionMonitor recorded connect");
115
- };
116
-
117
- ConnectionMonitor.prototype.recordDisconnect = function() {
118
- this.disconnectedAt = now();
119
- return ActionCable.log("ConnectionMonitor recorded disconnect");
120
- };
121
-
122
- ConnectionMonitor.prototype.startPolling = function() {
123
- this.stopPolling();
124
- return this.poll();
125
- };
126
-
127
- ConnectionMonitor.prototype.stopPolling = function() {
128
- return clearTimeout(this.pollTimeout);
129
- };
130
-
131
- ConnectionMonitor.prototype.poll = function() {
132
- return this.pollTimeout = setTimeout((function(_this) {
133
- return function() {
134
- _this.reconnectIfStale();
135
- return _this.poll();
136
- };
137
- })(this), this.getPollInterval());
138
- };
139
-
140
- ConnectionMonitor.prototype.getPollInterval = function() {
141
- var interval, max, min, ref;
142
- ref = this.constructor.pollInterval, min = ref.min, max = ref.max;
143
- interval = 5 * Math.log(this.reconnectAttempts + 1);
144
- return Math.round(clamp(interval, min, max) * 1000);
145
- };
146
-
147
- ConnectionMonitor.prototype.reconnectIfStale = function() {
148
- if (this.connectionIsStale()) {
149
- ActionCable.log("ConnectionMonitor detected stale connection. reconnectAttempts = " + this.reconnectAttempts + ", pollInterval = " + (this.getPollInterval()) + " ms, time disconnected = " + (secondsSince(this.disconnectedAt)) + " s, stale threshold = " + this.constructor.staleThreshold + " s");
150
- this.reconnectAttempts++;
151
- if (this.disconnectedRecently()) {
152
- return ActionCable.log("ConnectionMonitor skipping reopening recent disconnect");
153
- } else {
154
- ActionCable.log("ConnectionMonitor reopening");
155
- return this.connection.reopen();
60
+ var ActionCable = this.ActionCable;
61
+
62
+ (function() {
63
+ (function() {
64
+ var bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
65
+
66
+ ActionCable.ConnectionMonitor = (function() {
67
+ var clamp, now, secondsSince;
68
+
69
+ ConnectionMonitor.pollInterval = {
70
+ min: 3,
71
+ max: 30
72
+ };
73
+
74
+ ConnectionMonitor.staleThreshold = 6;
75
+
76
+ function ConnectionMonitor(connection) {
77
+ this.connection = connection;
78
+ this.visibilityDidChange = bind(this.visibilityDidChange, this);
79
+ this.reconnectAttempts = 0;
156
80
  }
157
- }
158
- };
159
-
160
- ConnectionMonitor.prototype.connectionIsStale = function() {
161
- var ref;
162
- return secondsSince((ref = this.pingedAt) != null ? ref : this.startedAt) > this.constructor.staleThreshold;
163
- };
164
-
165
- ConnectionMonitor.prototype.disconnectedRecently = function() {
166
- return this.disconnectedAt && secondsSince(this.disconnectedAt) < this.constructor.staleThreshold;
167
- };
168
-
169
- ConnectionMonitor.prototype.visibilityDidChange = function() {
170
- if (document.visibilityState === "visible") {
171
- return setTimeout((function(_this) {
172
- return function() {
173
- if (_this.connectionIsStale() || !_this.connection.isOpen()) {
174
- ActionCable.log("ConnectionMonitor reopening stale connection on visibilitychange. visbilityState = " + document.visibilityState);
175
- return _this.connection.reopen();
81
+
82
+ ConnectionMonitor.prototype.start = function() {
83
+ if (!this.isRunning()) {
84
+ this.startedAt = now();
85
+ delete this.stoppedAt;
86
+ this.startPolling();
87
+ document.addEventListener("visibilitychange", this.visibilityDidChange);
88
+ return ActionCable.log("ConnectionMonitor started. pollInterval = " + (this.getPollInterval()) + " ms");
89
+ }
90
+ };
91
+
92
+ ConnectionMonitor.prototype.stop = function() {
93
+ if (this.isRunning()) {
94
+ this.stoppedAt = now();
95
+ this.stopPolling();
96
+ document.removeEventListener("visibilitychange", this.visibilityDidChange);
97
+ return ActionCable.log("ConnectionMonitor stopped");
98
+ }
99
+ };
100
+
101
+ ConnectionMonitor.prototype.isRunning = function() {
102
+ return (this.startedAt != null) && (this.stoppedAt == null);
103
+ };
104
+
105
+ ConnectionMonitor.prototype.recordPing = function() {
106
+ return this.pingedAt = now();
107
+ };
108
+
109
+ ConnectionMonitor.prototype.recordConnect = function() {
110
+ this.reconnectAttempts = 0;
111
+ this.recordPing();
112
+ delete this.disconnectedAt;
113
+ return ActionCable.log("ConnectionMonitor recorded connect");
114
+ };
115
+
116
+ ConnectionMonitor.prototype.recordDisconnect = function() {
117
+ this.disconnectedAt = now();
118
+ return ActionCable.log("ConnectionMonitor recorded disconnect");
119
+ };
120
+
121
+ ConnectionMonitor.prototype.startPolling = function() {
122
+ this.stopPolling();
123
+ return this.poll();
124
+ };
125
+
126
+ ConnectionMonitor.prototype.stopPolling = function() {
127
+ return clearTimeout(this.pollTimeout);
128
+ };
129
+
130
+ ConnectionMonitor.prototype.poll = function() {
131
+ return this.pollTimeout = setTimeout((function(_this) {
132
+ return function() {
133
+ _this.reconnectIfStale();
134
+ return _this.poll();
135
+ };
136
+ })(this), this.getPollInterval());
137
+ };
138
+
139
+ ConnectionMonitor.prototype.getPollInterval = function() {
140
+ var interval, max, min, ref;
141
+ ref = this.constructor.pollInterval, min = ref.min, max = ref.max;
142
+ interval = 5 * Math.log(this.reconnectAttempts + 1);
143
+ return Math.round(clamp(interval, min, max) * 1000);
144
+ };
145
+
146
+ ConnectionMonitor.prototype.reconnectIfStale = function() {
147
+ if (this.connectionIsStale()) {
148
+ ActionCable.log("ConnectionMonitor detected stale connection. reconnectAttempts = " + this.reconnectAttempts + ", pollInterval = " + (this.getPollInterval()) + " ms, time disconnected = " + (secondsSince(this.disconnectedAt)) + " s, stale threshold = " + this.constructor.staleThreshold + " s");
149
+ this.reconnectAttempts++;
150
+ if (this.disconnectedRecently()) {
151
+ return ActionCable.log("ConnectionMonitor skipping reopening recent disconnect");
152
+ } else {
153
+ ActionCable.log("ConnectionMonitor reopening");
154
+ return this.connection.reopen();
176
155
  }
177
- };
178
- })(this), 200);
179
- }
180
- };
156
+ }
157
+ };
181
158
 
182
- now = function() {
183
- return new Date().getTime();
184
- };
159
+ ConnectionMonitor.prototype.connectionIsStale = function() {
160
+ var ref;
161
+ return secondsSince((ref = this.pingedAt) != null ? ref : this.startedAt) > this.constructor.staleThreshold;
162
+ };
185
163
 
186
- secondsSince = function(time) {
187
- return (now() - time) / 1000;
188
- };
164
+ ConnectionMonitor.prototype.disconnectedRecently = function() {
165
+ return this.disconnectedAt && secondsSince(this.disconnectedAt) < this.constructor.staleThreshold;
166
+ };
189
167
 
190
- clamp = function(number, min, max) {
191
- return Math.max(min, Math.min(max, number));
192
- };
168
+ ConnectionMonitor.prototype.visibilityDidChange = function() {
169
+ if (document.visibilityState === "visible") {
170
+ return setTimeout((function(_this) {
171
+ return function() {
172
+ if (_this.connectionIsStale() || !_this.connection.isOpen()) {
173
+ ActionCable.log("ConnectionMonitor reopening stale connection on visibilitychange. visbilityState = " + document.visibilityState);
174
+ return _this.connection.reopen();
175
+ }
176
+ };
177
+ })(this), 200);
178
+ }
179
+ };
193
180
 
194
- return ConnectionMonitor;
181
+ now = function() {
182
+ return new Date().getTime();
183
+ };
195
184
 
196
- })();
185
+ secondsSince = function(time) {
186
+ return (now() - time) / 1000;
187
+ };
197
188
 
198
- }).call(this);
199
- (function() {
200
- var i, message_types, protocols, ref, supportedProtocols, unsupportedProtocol,
201
- slice = [].slice,
202
- bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
203
- indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
204
-
205
- ref = ActionCable.INTERNAL, message_types = ref.message_types, protocols = ref.protocols;
206
-
207
- supportedProtocols = 2 <= protocols.length ? slice.call(protocols, 0, i = protocols.length - 1) : (i = 0, []), unsupportedProtocol = protocols[i++];
208
-
209
- ActionCable.Connection = (function() {
210
- Connection.reopenDelay = 500;
211
-
212
- function Connection(consumer) {
213
- this.consumer = consumer;
214
- this.open = bind(this.open, this);
215
- this.subscriptions = this.consumer.subscriptions;
216
- this.monitor = new ActionCable.ConnectionMonitor(this);
217
- this.disconnected = true;
218
- }
219
-
220
- Connection.prototype.send = function(data) {
221
- if (this.isOpen()) {
222
- this.webSocket.send(JSON.stringify(data));
223
- return true;
224
- } else {
225
- return false;
226
- }
227
- };
228
-
229
- Connection.prototype.open = function() {
230
- if (this.isActive()) {
231
- ActionCable.log("Attempted to open WebSocket, but existing socket is " + (this.getState()));
232
- throw new Error("Existing connection must be closed before opening");
233
- } else {
234
- ActionCable.log("Opening WebSocket, current state is " + (this.getState()) + ", subprotocols: " + protocols);
235
- if (this.webSocket != null) {
236
- this.uninstallEventHandlers();
237
- }
238
- this.webSocket = new WebSocket(this.consumer.url, protocols);
239
- this.installEventHandlers();
240
- this.monitor.start();
241
- return true;
242
- }
243
- };
244
-
245
- Connection.prototype.close = function(arg) {
246
- var allowReconnect, ref1;
247
- allowReconnect = (arg != null ? arg : {
248
- allowReconnect: true
249
- }).allowReconnect;
250
- if (!allowReconnect) {
251
- this.monitor.stop();
252
- }
253
- if (this.isActive()) {
254
- return (ref1 = this.webSocket) != null ? ref1.close() : void 0;
255
- }
256
- };
257
-
258
- Connection.prototype.reopen = function() {
259
- var error, error1;
260
- ActionCable.log("Reopening WebSocket, current state is " + (this.getState()));
261
- if (this.isActive()) {
262
- try {
263
- return this.close();
264
- } catch (error1) {
265
- error = error1;
266
- return ActionCable.log("Failed to reopen WebSocket", error);
267
- } finally {
268
- ActionCable.log("Reopening WebSocket in " + this.constructor.reopenDelay + "ms");
269
- setTimeout(this.open, this.constructor.reopenDelay);
270
- }
271
- } else {
272
- return this.open();
273
- }
274
- };
275
-
276
- Connection.prototype.getProtocol = function() {
277
- var ref1;
278
- return (ref1 = this.webSocket) != null ? ref1.protocol : void 0;
279
- };
280
-
281
- Connection.prototype.isOpen = function() {
282
- return this.isState("open");
283
- };
284
-
285
- Connection.prototype.isActive = function() {
286
- return this.isState("open", "connecting");
287
- };
288
-
289
- Connection.prototype.isProtocolSupported = function() {
290
- var ref1;
291
- return ref1 = this.getProtocol(), indexOf.call(supportedProtocols, ref1) >= 0;
292
- };
293
-
294
- Connection.prototype.isState = function() {
295
- var ref1, states;
296
- states = 1 <= arguments.length ? slice.call(arguments, 0) : [];
297
- return ref1 = this.getState(), indexOf.call(states, ref1) >= 0;
298
- };
299
-
300
- Connection.prototype.getState = function() {
301
- var ref1, state, value;
302
- for (state in WebSocket) {
303
- value = WebSocket[state];
304
- if (value === ((ref1 = this.webSocket) != null ? ref1.readyState : void 0)) {
305
- return state.toLowerCase();
306
- }
307
- }
308
- return null;
309
- };
310
-
311
- Connection.prototype.installEventHandlers = function() {
312
- var eventName, handler;
313
- for (eventName in this.events) {
314
- handler = this.events[eventName].bind(this);
315
- this.webSocket["on" + eventName] = handler;
316
- }
317
- };
318
-
319
- Connection.prototype.uninstallEventHandlers = function() {
320
- var eventName;
321
- for (eventName in this.events) {
322
- this.webSocket["on" + eventName] = function() {};
323
- }
324
- };
325
-
326
- Connection.prototype.events = {
327
- message: function(event) {
328
- var identifier, message, ref1, type;
329
- if (!this.isProtocolSupported()) {
330
- return;
189
+ clamp = function(number, min, max) {
190
+ return Math.max(min, Math.min(max, number));
191
+ };
192
+
193
+ return ConnectionMonitor;
194
+
195
+ })();
196
+
197
+ }).call(this);
198
+ (function() {
199
+ var i, message_types, protocols, ref, supportedProtocols, unsupportedProtocol,
200
+ slice = [].slice,
201
+ bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
202
+ indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
203
+
204
+ ref = ActionCable.INTERNAL, message_types = ref.message_types, protocols = ref.protocols;
205
+
206
+ supportedProtocols = 2 <= protocols.length ? slice.call(protocols, 0, i = protocols.length - 1) : (i = 0, []), unsupportedProtocol = protocols[i++];
207
+
208
+ ActionCable.Connection = (function() {
209
+ Connection.reopenDelay = 500;
210
+
211
+ function Connection(consumer) {
212
+ this.consumer = consumer;
213
+ this.open = bind(this.open, this);
214
+ this.subscriptions = this.consumer.subscriptions;
215
+ this.monitor = new ActionCable.ConnectionMonitor(this);
216
+ this.disconnected = true;
331
217
  }
332
- ref1 = JSON.parse(event.data), identifier = ref1.identifier, message = ref1.message, type = ref1.type;
333
- switch (type) {
334
- case message_types.welcome:
335
- this.monitor.recordConnect();
336
- return this.subscriptions.reload();
337
- case message_types.ping:
338
- return this.monitor.recordPing();
339
- case message_types.confirmation:
340
- return this.subscriptions.notify(identifier, "connected");
341
- case message_types.rejection:
342
- return this.subscriptions.reject(identifier);
343
- default:
344
- return this.subscriptions.notify(identifier, "received", message);
218
+
219
+ Connection.prototype.send = function(data) {
220
+ if (this.isOpen()) {
221
+ this.webSocket.send(JSON.stringify(data));
222
+ return true;
223
+ } else {
224
+ return false;
225
+ }
226
+ };
227
+
228
+ Connection.prototype.open = function() {
229
+ if (this.isActive()) {
230
+ ActionCable.log("Attempted to open WebSocket, but existing socket is " + (this.getState()));
231
+ throw new Error("Existing connection must be closed before opening");
232
+ } else {
233
+ ActionCable.log("Opening WebSocket, current state is " + (this.getState()) + ", subprotocols: " + protocols);
234
+ if (this.webSocket != null) {
235
+ this.uninstallEventHandlers();
236
+ }
237
+ this.webSocket = new WebSocket(this.consumer.url, protocols);
238
+ this.installEventHandlers();
239
+ this.monitor.start();
240
+ return true;
241
+ }
242
+ };
243
+
244
+ Connection.prototype.close = function(arg) {
245
+ var allowReconnect, ref1;
246
+ allowReconnect = (arg != null ? arg : {
247
+ allowReconnect: true
248
+ }).allowReconnect;
249
+ if (!allowReconnect) {
250
+ this.monitor.stop();
251
+ }
252
+ if (this.isActive()) {
253
+ return (ref1 = this.webSocket) != null ? ref1.close() : void 0;
254
+ }
255
+ };
256
+
257
+ Connection.prototype.reopen = function() {
258
+ var error, error1;
259
+ ActionCable.log("Reopening WebSocket, current state is " + (this.getState()));
260
+ if (this.isActive()) {
261
+ try {
262
+ return this.close();
263
+ } catch (error1) {
264
+ error = error1;
265
+ return ActionCable.log("Failed to reopen WebSocket", error);
266
+ } finally {
267
+ ActionCable.log("Reopening WebSocket in " + this.constructor.reopenDelay + "ms");
268
+ setTimeout(this.open, this.constructor.reopenDelay);
269
+ }
270
+ } else {
271
+ return this.open();
272
+ }
273
+ };
274
+
275
+ Connection.prototype.getProtocol = function() {
276
+ var ref1;
277
+ return (ref1 = this.webSocket) != null ? ref1.protocol : void 0;
278
+ };
279
+
280
+ Connection.prototype.isOpen = function() {
281
+ return this.isState("open");
282
+ };
283
+
284
+ Connection.prototype.isActive = function() {
285
+ return this.isState("open", "connecting");
286
+ };
287
+
288
+ Connection.prototype.isProtocolSupported = function() {
289
+ var ref1;
290
+ return ref1 = this.getProtocol(), indexOf.call(supportedProtocols, ref1) >= 0;
291
+ };
292
+
293
+ Connection.prototype.isState = function() {
294
+ var ref1, states;
295
+ states = 1 <= arguments.length ? slice.call(arguments, 0) : [];
296
+ return ref1 = this.getState(), indexOf.call(states, ref1) >= 0;
297
+ };
298
+
299
+ Connection.prototype.getState = function() {
300
+ var ref1, state, value;
301
+ for (state in WebSocket) {
302
+ value = WebSocket[state];
303
+ if (value === ((ref1 = this.webSocket) != null ? ref1.readyState : void 0)) {
304
+ return state.toLowerCase();
305
+ }
306
+ }
307
+ return null;
308
+ };
309
+
310
+ Connection.prototype.installEventHandlers = function() {
311
+ var eventName, handler;
312
+ for (eventName in this.events) {
313
+ handler = this.events[eventName].bind(this);
314
+ this.webSocket["on" + eventName] = handler;
315
+ }
316
+ };
317
+
318
+ Connection.prototype.uninstallEventHandlers = function() {
319
+ var eventName;
320
+ for (eventName in this.events) {
321
+ this.webSocket["on" + eventName] = function() {};
322
+ }
323
+ };
324
+
325
+ Connection.prototype.events = {
326
+ message: function(event) {
327
+ var identifier, message, ref1, type;
328
+ if (!this.isProtocolSupported()) {
329
+ return;
330
+ }
331
+ ref1 = JSON.parse(event.data), identifier = ref1.identifier, message = ref1.message, type = ref1.type;
332
+ switch (type) {
333
+ case message_types.welcome:
334
+ this.monitor.recordConnect();
335
+ return this.subscriptions.reload();
336
+ case message_types.ping:
337
+ return this.monitor.recordPing();
338
+ case message_types.confirmation:
339
+ return this.subscriptions.notify(identifier, "connected");
340
+ case message_types.rejection:
341
+ return this.subscriptions.reject(identifier);
342
+ default:
343
+ return this.subscriptions.notify(identifier, "received", message);
344
+ }
345
+ },
346
+ open: function() {
347
+ ActionCable.log("WebSocket onopen event, using '" + (this.getProtocol()) + "' subprotocol");
348
+ this.disconnected = false;
349
+ if (!this.isProtocolSupported()) {
350
+ ActionCable.log("Protocol is unsupported. Stopping monitor and disconnecting.");
351
+ return this.close({
352
+ allowReconnect: false
353
+ });
354
+ }
355
+ },
356
+ close: function(event) {
357
+ ActionCable.log("WebSocket onclose event");
358
+ if (this.disconnected) {
359
+ return;
360
+ }
361
+ this.disconnected = true;
362
+ this.monitor.recordDisconnect();
363
+ return this.subscriptions.notifyAll("disconnected", {
364
+ willAttemptReconnect: this.monitor.isRunning()
365
+ });
366
+ },
367
+ error: function() {
368
+ return ActionCable.log("WebSocket onerror event");
369
+ }
370
+ };
371
+
372
+ return Connection;
373
+
374
+ })();
375
+
376
+ }).call(this);
377
+ (function() {
378
+ var slice = [].slice;
379
+
380
+ ActionCable.Subscriptions = (function() {
381
+ function Subscriptions(consumer) {
382
+ this.consumer = consumer;
383
+ this.subscriptions = [];
345
384
  }
346
- },
347
- open: function() {
348
- ActionCable.log("WebSocket onopen event, using '" + (this.getProtocol()) + "' subprotocol");
349
- this.disconnected = false;
350
- if (!this.isProtocolSupported()) {
351
- ActionCable.log("Protocol is unsupported. Stopping monitor and disconnecting.");
352
- return this.close({
353
- allowReconnect: false
385
+
386
+ Subscriptions.prototype.create = function(channelName, mixin) {
387
+ var channel, params, subscription;
388
+ channel = channelName;
389
+ params = typeof channel === "object" ? channel : {
390
+ channel: channel
391
+ };
392
+ subscription = new ActionCable.Subscription(this.consumer, params, mixin);
393
+ return this.add(subscription);
394
+ };
395
+
396
+ Subscriptions.prototype.add = function(subscription) {
397
+ this.subscriptions.push(subscription);
398
+ this.consumer.ensureActiveConnection();
399
+ this.notify(subscription, "initialized");
400
+ this.sendCommand(subscription, "subscribe");
401
+ return subscription;
402
+ };
403
+
404
+ Subscriptions.prototype.remove = function(subscription) {
405
+ this.forget(subscription);
406
+ if (!this.findAll(subscription.identifier).length) {
407
+ this.sendCommand(subscription, "unsubscribe");
408
+ }
409
+ return subscription;
410
+ };
411
+
412
+ Subscriptions.prototype.reject = function(identifier) {
413
+ var i, len, ref, results, subscription;
414
+ ref = this.findAll(identifier);
415
+ results = [];
416
+ for (i = 0, len = ref.length; i < len; i++) {
417
+ subscription = ref[i];
418
+ this.forget(subscription);
419
+ this.notify(subscription, "rejected");
420
+ results.push(subscription);
421
+ }
422
+ return results;
423
+ };
424
+
425
+ Subscriptions.prototype.forget = function(subscription) {
426
+ var s;
427
+ this.subscriptions = (function() {
428
+ var i, len, ref, results;
429
+ ref = this.subscriptions;
430
+ results = [];
431
+ for (i = 0, len = ref.length; i < len; i++) {
432
+ s = ref[i];
433
+ if (s !== subscription) {
434
+ results.push(s);
435
+ }
436
+ }
437
+ return results;
438
+ }).call(this);
439
+ return subscription;
440
+ };
441
+
442
+ Subscriptions.prototype.findAll = function(identifier) {
443
+ var i, len, ref, results, s;
444
+ ref = this.subscriptions;
445
+ results = [];
446
+ for (i = 0, len = ref.length; i < len; i++) {
447
+ s = ref[i];
448
+ if (s.identifier === identifier) {
449
+ results.push(s);
450
+ }
451
+ }
452
+ return results;
453
+ };
454
+
455
+ Subscriptions.prototype.reload = function() {
456
+ var i, len, ref, results, subscription;
457
+ ref = this.subscriptions;
458
+ results = [];
459
+ for (i = 0, len = ref.length; i < len; i++) {
460
+ subscription = ref[i];
461
+ results.push(this.sendCommand(subscription, "subscribe"));
462
+ }
463
+ return results;
464
+ };
465
+
466
+ Subscriptions.prototype.notifyAll = function() {
467
+ var args, callbackName, i, len, ref, results, subscription;
468
+ callbackName = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
469
+ ref = this.subscriptions;
470
+ results = [];
471
+ for (i = 0, len = ref.length; i < len; i++) {
472
+ subscription = ref[i];
473
+ results.push(this.notify.apply(this, [subscription, callbackName].concat(slice.call(args))));
474
+ }
475
+ return results;
476
+ };
477
+
478
+ Subscriptions.prototype.notify = function() {
479
+ var args, callbackName, i, len, results, subscription, subscriptions;
480
+ subscription = arguments[0], callbackName = arguments[1], args = 3 <= arguments.length ? slice.call(arguments, 2) : [];
481
+ if (typeof subscription === "string") {
482
+ subscriptions = this.findAll(subscription);
483
+ } else {
484
+ subscriptions = [subscription];
485
+ }
486
+ results = [];
487
+ for (i = 0, len = subscriptions.length; i < len; i++) {
488
+ subscription = subscriptions[i];
489
+ results.push(typeof subscription[callbackName] === "function" ? subscription[callbackName].apply(subscription, args) : void 0);
490
+ }
491
+ return results;
492
+ };
493
+
494
+ Subscriptions.prototype.sendCommand = function(subscription, command) {
495
+ var identifier;
496
+ identifier = subscription.identifier;
497
+ return this.consumer.send({
498
+ command: command,
499
+ identifier: identifier
354
500
  });
355
- }
356
- },
357
- close: function(event) {
358
- ActionCable.log("WebSocket onclose event");
359
- if (this.disconnected) {
360
- return;
361
- }
362
- this.disconnected = true;
363
- this.monitor.recordDisconnect();
364
- return this.subscriptions.notifyAll("disconnected", {
365
- willAttemptReconnect: this.monitor.isRunning()
366
- });
367
- },
368
- error: function() {
369
- return ActionCable.log("WebSocket onerror event");
370
- }
371
- };
501
+ };
372
502
 
373
- return Connection;
503
+ return Subscriptions;
374
504
 
375
- })();
505
+ })();
376
506
 
377
- }).call(this);
378
- (function() {
379
- var slice = [].slice;
380
-
381
- ActionCable.Subscriptions = (function() {
382
- function Subscriptions(consumer) {
383
- this.consumer = consumer;
384
- this.subscriptions = [];
385
- }
386
-
387
- Subscriptions.prototype.create = function(channelName, mixin) {
388
- var channel, params, subscription;
389
- channel = channelName;
390
- params = typeof channel === "object" ? channel : {
391
- channel: channel
392
- };
393
- subscription = new ActionCable.Subscription(this.consumer, params, mixin);
394
- return this.add(subscription);
395
- };
396
-
397
- Subscriptions.prototype.add = function(subscription) {
398
- this.subscriptions.push(subscription);
399
- this.consumer.ensureActiveConnection();
400
- this.notify(subscription, "initialized");
401
- this.sendCommand(subscription, "subscribe");
402
- return subscription;
403
- };
404
-
405
- Subscriptions.prototype.remove = function(subscription) {
406
- this.forget(subscription);
407
- if (!this.findAll(subscription.identifier).length) {
408
- this.sendCommand(subscription, "unsubscribe");
409
- }
410
- return subscription;
411
- };
412
-
413
- Subscriptions.prototype.reject = function(identifier) {
414
- var i, len, ref, results, subscription;
415
- ref = this.findAll(identifier);
416
- results = [];
417
- for (i = 0, len = ref.length; i < len; i++) {
418
- subscription = ref[i];
419
- this.forget(subscription);
420
- this.notify(subscription, "rejected");
421
- results.push(subscription);
422
- }
423
- return results;
424
- };
425
-
426
- Subscriptions.prototype.forget = function(subscription) {
427
- var s;
428
- this.subscriptions = (function() {
429
- var i, len, ref, results;
430
- ref = this.subscriptions;
431
- results = [];
432
- for (i = 0, len = ref.length; i < len; i++) {
433
- s = ref[i];
434
- if (s !== subscription) {
435
- results.push(s);
507
+ }).call(this);
508
+ (function() {
509
+ ActionCable.Subscription = (function() {
510
+ var extend;
511
+
512
+ function Subscription(consumer, params, mixin) {
513
+ this.consumer = consumer;
514
+ if (params == null) {
515
+ params = {};
436
516
  }
517
+ this.identifier = JSON.stringify(params);
518
+ extend(this, mixin);
437
519
  }
438
- return results;
439
- }).call(this);
440
- return subscription;
441
- };
442
-
443
- Subscriptions.prototype.findAll = function(identifier) {
444
- var i, len, ref, results, s;
445
- ref = this.subscriptions;
446
- results = [];
447
- for (i = 0, len = ref.length; i < len; i++) {
448
- s = ref[i];
449
- if (s.identifier === identifier) {
450
- results.push(s);
451
- }
452
- }
453
- return results;
454
- };
455
-
456
- Subscriptions.prototype.reload = function() {
457
- var i, len, ref, results, subscription;
458
- ref = this.subscriptions;
459
- results = [];
460
- for (i = 0, len = ref.length; i < len; i++) {
461
- subscription = ref[i];
462
- results.push(this.sendCommand(subscription, "subscribe"));
463
- }
464
- return results;
465
- };
466
-
467
- Subscriptions.prototype.notifyAll = function() {
468
- var args, callbackName, i, len, ref, results, subscription;
469
- callbackName = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
470
- ref = this.subscriptions;
471
- results = [];
472
- for (i = 0, len = ref.length; i < len; i++) {
473
- subscription = ref[i];
474
- results.push(this.notify.apply(this, [subscription, callbackName].concat(slice.call(args))));
475
- }
476
- return results;
477
- };
478
-
479
- Subscriptions.prototype.notify = function() {
480
- var args, callbackName, i, len, results, subscription, subscriptions;
481
- subscription = arguments[0], callbackName = arguments[1], args = 3 <= arguments.length ? slice.call(arguments, 2) : [];
482
- if (typeof subscription === "string") {
483
- subscriptions = this.findAll(subscription);
484
- } else {
485
- subscriptions = [subscription];
486
- }
487
- results = [];
488
- for (i = 0, len = subscriptions.length; i < len; i++) {
489
- subscription = subscriptions[i];
490
- results.push(typeof subscription[callbackName] === "function" ? subscription[callbackName].apply(subscription, args) : void 0);
491
- }
492
- return results;
493
- };
494
-
495
- Subscriptions.prototype.sendCommand = function(subscription, command) {
496
- var identifier;
497
- identifier = subscription.identifier;
498
- return this.consumer.send({
499
- command: command,
500
- identifier: identifier
501
- });
502
- };
503
-
504
- return Subscriptions;
505
-
506
- })();
507
520
 
508
- }).call(this);
509
- (function() {
510
- ActionCable.Subscription = (function() {
511
- var extend;
512
-
513
- function Subscription(consumer, params, mixin) {
514
- this.consumer = consumer;
515
- if (params == null) {
516
- params = {};
517
- }
518
- this.identifier = JSON.stringify(params);
519
- extend(this, mixin);
520
- }
521
-
522
- Subscription.prototype.perform = function(action, data) {
523
- if (data == null) {
524
- data = {};
525
- }
526
- data.action = action;
527
- return this.send(data);
528
- };
529
-
530
- Subscription.prototype.send = function(data) {
531
- return this.consumer.send({
532
- command: "message",
533
- identifier: this.identifier,
534
- data: JSON.stringify(data)
535
- });
536
- };
537
-
538
- Subscription.prototype.unsubscribe = function() {
539
- return this.consumer.subscriptions.remove(this);
540
- };
541
-
542
- extend = function(object, properties) {
543
- var key, value;
544
- if (properties != null) {
545
- for (key in properties) {
546
- value = properties[key];
547
- object[key] = value;
548
- }
549
- }
550
- return object;
551
- };
521
+ Subscription.prototype.perform = function(action, data) {
522
+ if (data == null) {
523
+ data = {};
524
+ }
525
+ data.action = action;
526
+ return this.send(data);
527
+ };
552
528
 
553
- return Subscription;
529
+ Subscription.prototype.send = function(data) {
530
+ return this.consumer.send({
531
+ command: "message",
532
+ identifier: this.identifier,
533
+ data: JSON.stringify(data)
534
+ });
535
+ };
554
536
 
555
- })();
537
+ Subscription.prototype.unsubscribe = function() {
538
+ return this.consumer.subscriptions.remove(this);
539
+ };
556
540
 
557
- }).call(this);
558
- (function() {
559
- ActionCable.Consumer = (function() {
560
- function Consumer(url) {
561
- this.url = url;
562
- this.subscriptions = new ActionCable.Subscriptions(this);
563
- this.connection = new ActionCable.Connection(this);
564
- }
541
+ extend = function(object, properties) {
542
+ var key, value;
543
+ if (properties != null) {
544
+ for (key in properties) {
545
+ value = properties[key];
546
+ object[key] = value;
547
+ }
548
+ }
549
+ return object;
550
+ };
565
551
 
566
- Consumer.prototype.send = function(data) {
567
- return this.connection.send(data);
568
- };
552
+ return Subscription;
569
553
 
570
- Consumer.prototype.connect = function() {
571
- return this.connection.open();
572
- };
554
+ })();
573
555
 
574
- Consumer.prototype.disconnect = function() {
575
- return this.connection.close({
576
- allowReconnect: false
577
- });
578
- };
556
+ }).call(this);
557
+ (function() {
558
+ ActionCable.Consumer = (function() {
559
+ function Consumer(url) {
560
+ this.url = url;
561
+ this.subscriptions = new ActionCable.Subscriptions(this);
562
+ this.connection = new ActionCable.Connection(this);
563
+ }
579
564
 
580
- Consumer.prototype.ensureActiveConnection = function() {
581
- if (!this.connection.isActive()) {
582
- return this.connection.open();
583
- }
584
- };
565
+ Consumer.prototype.send = function(data) {
566
+ return this.connection.send(data);
567
+ };
585
568
 
586
- return Consumer;
569
+ Consumer.prototype.connect = function() {
570
+ return this.connection.open();
571
+ };
587
572
 
588
- })();
573
+ Consumer.prototype.disconnect = function() {
574
+ return this.connection.close({
575
+ allowReconnect: false
576
+ });
577
+ };
578
+
579
+ Consumer.prototype.ensureActiveConnection = function() {
580
+ if (!this.connection.isActive()) {
581
+ return this.connection.open();
582
+ }
583
+ };
584
+
585
+ return Consumer;
586
+
587
+ })();
589
588
 
589
+ }).call(this);
590
+ }).call(this);
591
+
592
+ if (typeof module === "object" && module.exports) {
593
+ module.exports = ActionCable;
594
+ } else if (typeof define === "function" && define.amd) {
595
+ define(ActionCable);
596
+ }
590
597
  }).call(this);