danthes 1.0.3 → 1.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +8 -0
- data/Gemfile +3 -3
- data/README.md +4 -4
- data/Rakefile +1 -0
- data/app/assets/javascripts/danthes.js.coffee +47 -28
- data/danthes.gemspec +1 -1
- data/lib/danthes/version.rb +1 -1
- data/lib/generators/templates/danthes.ru +1 -1
- data/spec/coffeescripts/danthes_spec.js.coffee +61 -32
- data/spec/javascripts/support/jasmine_config.rb +1 -0
- data/spec/javascripts/support/jasmine_runner.rb +1 -0
- metadata +3 -4
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
# d'Anthès
|
2
2
|
|
3
|
+
## 1.0.4 (February 25 2013)
|
4
|
+
|
5
|
+
* Added possibility to activate Faye's subscription later on subscribe call
|
6
|
+
|
7
|
+
## 1.0.3 (September 26 2012)
|
8
|
+
|
9
|
+
* Fix IE support
|
10
|
+
|
3
11
|
## 1.0.2 (September 7 2012)
|
4
12
|
|
5
13
|
* Subscription callback through sign call
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,12 +1,12 @@
|
|
1
|
-
# d'Anthès [![Build Status](https://secure.travis-ci.org/
|
1
|
+
# d'Anthès [![Build Status](https://secure.travis-ci.org/phenomena/danthes.png?branch=master)](http://travis-ci.org/phenomena/danthes)
|
2
2
|
|
3
3
|
d'Anthès is a Ruby gem for use with Rails to publish and subscribe to messages through [Faye](http://faye.jcoglan.com/). It allows you to easily provide real-time updates through an open socket without tying up a Rails process. All channels are private so users can only listen to events you subscribe them to. Based on PrivatePub gem.
|
4
4
|
|
5
5
|
## Docs
|
6
6
|
|
7
|
-
[Ruby](http://rubydoc.info/github/
|
7
|
+
[Ruby](http://rubydoc.info/github/phenomena/danthes/frames)
|
8
8
|
|
9
|
-
[CoffeeScript](https://github.com/
|
9
|
+
[CoffeeScript](https://github.com/phenomena/danthes/wiki/CoffeeScript-documentation)
|
10
10
|
|
11
11
|
## Setup
|
12
12
|
|
@@ -146,7 +146,7 @@ The `publish_to` method will send a post request to the Faye server (using `Net:
|
|
146
146
|
|
147
147
|
## Development & Feedback
|
148
148
|
|
149
|
-
Questions or comments? Please use the [issue tracker](https://github.com/
|
149
|
+
Questions or comments? Please use the [issue tracker](https://github.com/phenomena/danthes/issues). Tests can be run with `bundle` and `rake` commands.
|
150
150
|
|
151
151
|
## TODO
|
152
152
|
|
data/Rakefile
CHANGED
@@ -10,16 +10,18 @@
|
|
10
10
|
# channel: 'somechannel'
|
11
11
|
# signature: 'dc1c71d3e959ebb6f49aa6af0c86304a0740088d'
|
12
12
|
# timestamp: 1302306682972
|
13
|
-
#
|
14
|
-
# console.log(
|
13
|
+
# connect: (subscription) ->
|
14
|
+
# console.log(subscription)
|
15
|
+
# error: (subscription, error) ->
|
16
|
+
# console.log("error: #{error}")
|
15
17
|
|
16
18
|
window.Danthes = class Danthes
|
17
|
-
|
18
|
-
@debug: false
|
19
|
+
|
20
|
+
@debug: false
|
19
21
|
|
20
22
|
@debugMessage: (message) ->
|
21
23
|
console.log(message) if @debug
|
22
|
-
|
24
|
+
|
23
25
|
# Reset all
|
24
26
|
@reset: ->
|
25
27
|
@connecting = false
|
@@ -58,7 +60,7 @@ window.Danthes = class Danthes
|
|
58
60
|
else
|
59
61
|
@debugMessage 'faye already inited'
|
60
62
|
@connectToFaye()
|
61
|
-
|
63
|
+
|
62
64
|
# Faye extension for incoming and outgoing messages
|
63
65
|
@fayeExtension:
|
64
66
|
incoming : (message, callback) =>
|
@@ -73,7 +75,7 @@ window.Danthes = class Danthes
|
|
73
75
|
message.ext.danthes_signature = subscription.signature
|
74
76
|
message.ext.danthes_timestamp = subscription.timestamp
|
75
77
|
callback(message)
|
76
|
-
|
78
|
+
|
77
79
|
# Initialize Faye client
|
78
80
|
@connectToFaye: ->
|
79
81
|
if @server && Faye?
|
@@ -96,18 +98,28 @@ window.Danthes = class Danthes
|
|
96
98
|
@subscriptions[channel]['callback'] = options['callback'] if options['callback']?
|
97
99
|
@subscriptions[channel]['opts'] =
|
98
100
|
signature: options['signature']
|
99
|
-
timestamp: options['timestamp']
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
101
|
+
timestamp: options['timestamp']
|
102
|
+
# If we have 'connect' or 'error' option then force channel activation
|
103
|
+
if options['connect']? || options['error']?
|
104
|
+
@activateChannel channel, options
|
105
|
+
|
106
|
+
# Activating channel subscription
|
107
|
+
# @param channel [String] channel name
|
108
|
+
# @param options [Object] subscription callback options
|
109
|
+
@activateChannel: (channel, options = {}) ->
|
110
|
+
return true if @subscriptions[channel]['activated']
|
111
|
+
@faye (faye) =>
|
112
|
+
subscription = faye.subscribe channel, (message) => @handleResponse(message)
|
113
|
+
if subscription?
|
114
|
+
@subscriptions[channel]['sub'] = subscription
|
115
|
+
subscription.callback =>
|
116
|
+
options['connect']?(subscription)
|
117
|
+
@debugMessage "subscription for #{channel} is active now"
|
118
|
+
subscription.errback (error) =>
|
119
|
+
options['error']?(subscription, error)
|
120
|
+
@debugMessage "error for #{channel}: #{error.message}"
|
121
|
+
@subscriptions[channel]['activated'] = true
|
122
|
+
|
111
123
|
# Handle response from Faye
|
112
124
|
# @param [Object] message from Faye
|
113
125
|
@handleResponse: (message) ->
|
@@ -117,7 +129,7 @@ window.Danthes = class Danthes
|
|
117
129
|
return unless @subscriptions[channel]?
|
118
130
|
if callback = @subscriptions[channel]['callback']
|
119
131
|
callback(message.data, channel)
|
120
|
-
|
132
|
+
|
121
133
|
# Disable transports
|
122
134
|
# @param [String] name of transport
|
123
135
|
@disableTransport: (transport) ->
|
@@ -126,29 +138,36 @@ window.Danthes = class Danthes
|
|
126
138
|
@disables.push(transport)
|
127
139
|
@debugMessage "#{transport} faye transport will be disabled"
|
128
140
|
true
|
129
|
-
|
141
|
+
|
130
142
|
# Subscribe to channel with callback
|
131
143
|
# @param channel [String] Channel name
|
132
144
|
# @param callback [Function] Callback function
|
133
|
-
@
|
145
|
+
# @param options [Object] subscription callbacks options
|
146
|
+
@subscribe: (channel, callback, options = {}) ->
|
134
147
|
@debugMessage "subscribing to #{channel}"
|
135
148
|
if @subscriptions[channel]?
|
149
|
+
@activateChannel(channel, options)
|
136
150
|
# Changing callback on every call
|
137
151
|
@subscriptions[channel]['callback'] = callback
|
138
152
|
else
|
139
153
|
@debugMessage "Cannot subscribe on channel '#{channel}'. You need sign to channel first."
|
140
154
|
return false
|
141
155
|
true
|
142
|
-
|
156
|
+
|
143
157
|
# Unsubscribe from channel
|
144
158
|
# @param [String] Channel name
|
145
|
-
@
|
159
|
+
# @param [Boolean] Full unsubscribe
|
160
|
+
@unsubscribe: (channel, fullUnsubscribe = false) ->
|
146
161
|
@debugMessage "unsubscribing from #{channel}"
|
147
|
-
if @subscriptions[channel]
|
162
|
+
if @subscriptions[channel] && @subscriptions[channel]['activated']
|
148
163
|
@subscriptions[channel]['sub'].cancel()
|
149
|
-
|
150
|
-
|
151
|
-
|
164
|
+
if fullUnsubscribe
|
165
|
+
delete @subscriptions[channel]
|
166
|
+
else
|
167
|
+
delete @subscriptions[channel]['activated']
|
168
|
+
delete @subscriptions[channel]['sub']
|
169
|
+
|
170
|
+
# Unsubscribe from all channels
|
152
171
|
@unsubscribeAll: ->
|
153
172
|
@unsubscribe(channel) for channel, _ of @subscriptions
|
154
173
|
|
data/danthes.gemspec
CHANGED
@@ -7,7 +7,7 @@ Gem::Specification.new do |s|
|
|
7
7
|
s.platform = Gem::Platform::RUBY
|
8
8
|
s.author = ["Alexander Simonov"]
|
9
9
|
s.email = ["alex@simonov.me"]
|
10
|
-
s.homepage = "http://github.com/
|
10
|
+
s.homepage = "http://github.com/phenomena/danthes"
|
11
11
|
s.summary = "Private pub/sub messaging through Faye."
|
12
12
|
s.description = "Private pub/sub messaging in Rails through Faye. More Faye features supported. Based on PrivatePub."
|
13
13
|
s.files = `git ls-files`.split($\)
|
data/lib/danthes/version.rb
CHANGED
@@ -1,22 +1,25 @@
|
|
1
1
|
describe "Danthes", ->
|
2
2
|
window.Faye = undefined
|
3
3
|
pub = undefined
|
4
|
-
|
5
|
-
signToChannel = (channel) ->
|
6
|
-
|
4
|
+
|
5
|
+
signToChannel = (channel, addOptions = {}) ->
|
6
|
+
sub = {callback: jasmine.createSpy(), errback: jasmine.createSpy()}
|
7
|
+
faye = {subscribe: jasmine.createSpy().andReturn(sub)}
|
7
8
|
spyOn(pub, 'faye').andCallFake (callback) ->
|
8
9
|
callback(faye)
|
9
10
|
options = {server: "server", channel: "#{channel}", timestamp: 1234567890, signature: '1234567890'}
|
11
|
+
options['connect'] = addOptions['connect'] if addOptions['connect']?
|
12
|
+
options['error'] = addOptions['error'] if addOptions['error']?
|
10
13
|
pub.sign(options)
|
11
14
|
return [faye, options]
|
12
|
-
|
15
|
+
|
13
16
|
beforeEach ->
|
14
17
|
pub = window.Danthes
|
15
18
|
pub.reset()
|
16
19
|
script = document.getElementById('faye-connection-script')
|
17
20
|
if script?
|
18
21
|
script.parentNode.removeChild(script)
|
19
|
-
|
22
|
+
|
20
23
|
it "not adds a subscription callback without signing", ->
|
21
24
|
expect(pub.subscribe("hello", "callback")).toBe(false)
|
22
25
|
expect(pub.subscriptions).toEqual({})
|
@@ -73,13 +76,35 @@ describe "Danthes", ->
|
|
73
76
|
expect(script).toBeDefined()
|
74
77
|
expect(script.type).toEqual("text/javascript")
|
75
78
|
expect(script.src).toMatch("path/to/faye/client.js")
|
76
|
-
|
77
|
-
it "adds a
|
79
|
+
|
80
|
+
it "adds a signed channel to subscribe later", ->
|
81
|
+
pub.fayeClient = 'string'
|
82
|
+
[faye, options] = signToChannel('somechannel')
|
83
|
+
expect(faye.subscribe).not.toHaveBeenCalled()
|
84
|
+
expect(pub.subscriptions.somechannel.activated).toBeUndefined()
|
85
|
+
expect(pub.subscriptions.somechannel).toBeDefined()
|
86
|
+
expect(pub.subscriptions.somechannel.opts.signature).toEqual('1234567890')
|
87
|
+
expect(pub.subscriptions.somechannel.opts.timestamp).toEqual(1234567890)
|
88
|
+
expect(pub.subscriptions.somechannel.activated).toBeUndefined()
|
89
|
+
|
90
|
+
it "adds a faye subscription with response handler when sign with connect option", ->
|
91
|
+
pub.fayeClient = 'string'
|
92
|
+
[faye, options] = signToChannel('somechannel', {'connect': jasmine.createSpy()})
|
93
|
+
expect(faye.subscribe).toHaveBeenCalled()
|
94
|
+
expect(pub.subscriptions.somechannel.activated).toBeDefined()
|
95
|
+
|
96
|
+
it "adds a faye subscription with response handler when sign with error option", ->
|
97
|
+
pub.fayeClient = 'string'
|
98
|
+
[faye, options] = signToChannel('somechannel', {'error': jasmine.createSpy()})
|
99
|
+
expect(faye.subscribe).toHaveBeenCalled()
|
100
|
+
expect(pub.subscriptions.somechannel.activated).toBeDefined()
|
101
|
+
|
102
|
+
it "adds a faye subscription with response handler when first time subscribing", ->
|
78
103
|
pub.fayeClient = 'string'
|
79
104
|
[faye, options] = signToChannel('somechannel')
|
105
|
+
pub.subscribe('somechannel', ->)
|
80
106
|
expect(faye.subscribe).toHaveBeenCalled()
|
81
|
-
expect(pub.
|
82
|
-
expect(pub.subscriptions.somechannel.opts).toEqual(timestamp: options['timestamp'], signature: options['signature'])
|
107
|
+
expect(pub.subscriptions.somechannel.activated).toBeDefined()
|
83
108
|
|
84
109
|
it "connects to faye server, adds extension, and executes callbacks", ->
|
85
110
|
callback = jasmine.createSpy()
|
@@ -95,20 +120,20 @@ describe "Danthes", ->
|
|
95
120
|
expect(pub.fayeClient).toEqual(client)
|
96
121
|
expect(client.addExtension).toHaveBeenCalledWith(pub.fayeExtension)
|
97
122
|
expect(callback).toHaveBeenCalledWith(client)
|
98
|
-
|
123
|
+
|
99
124
|
it "adds transport to disables", ->
|
100
125
|
expect(pub.disableTransport('websocket')).toBeTruthy()
|
101
126
|
expect(pub.disables).toEqual(['websocket'])
|
102
|
-
|
127
|
+
|
103
128
|
it "adds transport to disables only one time", ->
|
104
129
|
pub.disableTransport('websocket')
|
105
130
|
pub.disableTransport('websocket')
|
106
131
|
expect(pub.disables).toEqual(['websocket'])
|
107
|
-
|
132
|
+
|
108
133
|
it "returns false if not accepted transport wants to be disabled", ->
|
109
134
|
expect(pub.disableTransport('websocket123')).toBeUndefined()
|
110
135
|
expect(pub.disables).toEqual([])
|
111
|
-
|
136
|
+
|
112
137
|
it "connects to faye server, and executes disable once", ->
|
113
138
|
callback = jasmine.createSpy()
|
114
139
|
client = {addExtension: jasmine.createSpy(), disable: jasmine.createSpy()}
|
@@ -118,7 +143,7 @@ describe "Danthes", ->
|
|
118
143
|
pub.disableTransport('websocket')
|
119
144
|
pub.connectToFaye()
|
120
145
|
expect(client.disable).toHaveBeenCalledWith('websocket')
|
121
|
-
|
146
|
+
|
122
147
|
it "connects to faye server, and executes disable once", ->
|
123
148
|
callback = jasmine.createSpy()
|
124
149
|
client = {addExtension: jasmine.createSpy(), disable: jasmine.createSpy()}
|
@@ -130,53 +155,57 @@ describe "Danthes", ->
|
|
130
155
|
pub.connectToFaye()
|
131
156
|
expect(client.disable).toHaveBeenCalledWith('websocket')
|
132
157
|
expect(client.disable).toHaveBeenCalledWith('long-polling')
|
133
|
-
|
158
|
+
|
134
159
|
it "adds subscription faye object into channel object", ->
|
135
160
|
sub = {callback: jasmine.createSpy(), errback: jasmine.createSpy()}
|
136
161
|
pub.fayeClient = {subscribe: jasmine.createSpy().andReturn(sub)}
|
137
162
|
options = {server: "server", channel: 'somechannel'}
|
138
163
|
pub.sign(options)
|
164
|
+
pub.subscribe("somechannel", jasmine.createSpy())
|
139
165
|
expect(sub.callback).toHaveBeenCalled()
|
140
166
|
expect(sub.errback).toHaveBeenCalled()
|
141
167
|
expect(pub.subscriptions.somechannel.sub).toEqual(sub)
|
142
|
-
|
168
|
+
|
143
169
|
it "adds subscription faye object into channel object and call connect callback after connection", ->
|
144
|
-
sub =
|
145
|
-
callback: (f) ->
|
170
|
+
sub =
|
171
|
+
callback: (f) ->
|
146
172
|
f()
|
147
173
|
errback: jasmine.createSpy()
|
148
174
|
pub.fayeClient = {subscribe: jasmine.createSpy().andReturn(sub)}
|
149
|
-
options = {server: "server", channel: 'somechannel'
|
175
|
+
options = {server: "server", channel: 'somechannel'}
|
150
176
|
pub.sign(options)
|
151
|
-
|
152
|
-
|
177
|
+
connectSpy = jasmine.createSpy()
|
178
|
+
pub.subscribe('somechannel', jasmine.createSpy(), connect: connectSpy)
|
179
|
+
expect(connectSpy).toHaveBeenCalledWith(sub)
|
180
|
+
|
153
181
|
it "adds subscription faye object into channel object and call error callback after connection", ->
|
154
|
-
sub =
|
182
|
+
sub =
|
155
183
|
callback: jasmine.createSpy()
|
156
|
-
errback: (f) ->
|
184
|
+
errback: (f) ->
|
157
185
|
f('error')
|
158
186
|
pub.fayeClient = {subscribe: jasmine.createSpy().andReturn(sub)}
|
159
|
-
|
187
|
+
erroSpy = jasmine.createSpy()
|
188
|
+
options = {server: "server", channel: 'somechannel'}
|
160
189
|
pub.sign(options)
|
161
|
-
|
162
|
-
|
190
|
+
pub.subscribe("somechannel", jasmine.createSpy(), error: erroSpy)
|
191
|
+
expect(erroSpy).toHaveBeenCalledWith(sub, 'error')
|
192
|
+
|
163
193
|
it "removes subscription to the channel", ->
|
164
194
|
sub = {callback: jasmine.createSpy(), errback: jasmine.createSpy(), cancel: jasmine.createSpy()}
|
165
195
|
pub.fayeClient = {subscribe: jasmine.createSpy().andReturn(sub)}
|
166
196
|
options = {server: "server", channel: 'somechannel'}
|
167
197
|
pub.sign(options)
|
198
|
+
pub.subscribe('somechannel', jasmine.createSpy())
|
168
199
|
pub.unsubscribe('somechannel')
|
169
200
|
expect(sub.cancel).toHaveBeenCalled()
|
170
|
-
expect(pub.subscriptions.somechannel).toBeUndefined()
|
171
|
-
|
172
|
-
|
201
|
+
expect(pub.subscriptions.somechannel.sub).toBeUndefined()
|
202
|
+
|
173
203
|
it "removes all subscription to the channels", ->
|
174
204
|
sub = {callback: jasmine.createSpy(), errback: jasmine.createSpy(), cancel: jasmine.createSpy()}
|
175
205
|
pub.fayeClient = {subscribe: jasmine.createSpy().andReturn(sub)}
|
176
206
|
options = {server: "server", channel: 'somechannel'}
|
177
207
|
pub.sign(options)
|
208
|
+
pub.subscribe "somechannel", jasmine.createSpy()
|
178
209
|
pub.unsubscribeAll()
|
179
210
|
expect(sub.cancel).toHaveBeenCalled()
|
180
|
-
expect(pub.subscriptions.somechannel).toBeUndefined()
|
181
|
-
expect(pub.subscriptions).toEqual({})
|
182
|
-
|
211
|
+
expect(pub.subscriptions.somechannel.sub).toBeUndefined()
|
@@ -1,6 +1,7 @@
|
|
1
1
|
$:.unshift(ENV['JASMINE_GEM_PATH']) if ENV['JASMINE_GEM_PATH'] # for gem testing purposes
|
2
2
|
|
3
3
|
require 'rubygems'
|
4
|
+
require 'yaml'
|
4
5
|
require 'jasmine'
|
5
6
|
jasmine_config_overrides = File.expand_path(File.join(File.dirname(__FILE__), 'jasmine_config.rb'))
|
6
7
|
require jasmine_config_overrides if File.exist?(jasmine_config_overrides)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: danthes
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-02-25 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: faye
|
@@ -67,7 +67,7 @@ files:
|
|
67
67
|
- spec/javascripts/support/jasmine_config.rb
|
68
68
|
- spec/javascripts/support/jasmine_runner.rb
|
69
69
|
- spec/spec_helper.rb
|
70
|
-
homepage: http://github.com/
|
70
|
+
homepage: http://github.com/phenomena/danthes
|
71
71
|
licenses: []
|
72
72
|
post_install_message:
|
73
73
|
rdoc_options: []
|
@@ -101,4 +101,3 @@ test_files:
|
|
101
101
|
- spec/javascripts/support/jasmine_config.rb
|
102
102
|
- spec/javascripts/support/jasmine_runner.rb
|
103
103
|
- spec/spec_helper.rb
|
104
|
-
has_rdoc:
|