ably-rest 0.8.1 → 0.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. checksums.yaml +5 -13
  2. data/CHANGELOG.md +45 -0
  3. data/LICENSE +15 -0
  4. data/README.md +14 -1
  5. data/lib/submodules/ably-ruby/CHANGELOG.md +45 -0
  6. data/lib/submodules/ably-ruby/LICENSE +15 -0
  7. data/lib/submodules/ably-ruby/README.md +18 -14
  8. data/lib/submodules/ably-ruby/SPEC.md +482 -336
  9. data/lib/submodules/ably-ruby/ably.gemspec +1 -1
  10. data/lib/submodules/ably-ruby/lib/ably.rb +1 -1
  11. data/lib/submodules/ably-ruby/lib/ably/exceptions.rb +4 -1
  12. data/lib/submodules/ably-ruby/lib/ably/models/{paginated_resource.rb → paginated_result.rb} +8 -8
  13. data/lib/submodules/ably-ruby/lib/ably/models/presence_message.rb +1 -1
  14. data/lib/submodules/ably-ruby/lib/ably/modules/conversions.rb +15 -0
  15. data/lib/submodules/ably-ruby/lib/ably/modules/encodeable.rb +2 -2
  16. data/lib/submodules/ably-ruby/lib/ably/modules/event_emitter.rb +8 -8
  17. data/lib/submodules/ably-ruby/lib/ably/modules/safe_deferrable.rb +15 -3
  18. data/lib/submodules/ably-ruby/lib/ably/modules/state_emitter.rb +2 -2
  19. data/lib/submodules/ably-ruby/lib/ably/modules/state_machine.rb +1 -1
  20. data/lib/submodules/ably-ruby/lib/ably/realtime/channel.rb +2 -4
  21. data/lib/submodules/ably-ruby/lib/ably/realtime/channel/channel_manager.rb +1 -1
  22. data/lib/submodules/ably-ruby/lib/ably/realtime/client.rb +4 -4
  23. data/lib/submodules/ably-ruby/lib/ably/realtime/client/incoming_message_dispatcher.rb +2 -2
  24. data/lib/submodules/ably-ruby/lib/ably/realtime/connection.rb +2 -2
  25. data/lib/submodules/ably-ruby/lib/ably/realtime/connection/connection_manager.rb +3 -3
  26. data/lib/submodules/ably-ruby/lib/ably/realtime/connection/connection_state_machine.rb +1 -1
  27. data/lib/submodules/ably-ruby/lib/ably/realtime/connection/websocket_transport.rb +2 -2
  28. data/lib/submodules/ably-ruby/lib/ably/realtime/presence.rb +23 -5
  29. data/lib/submodules/ably-ruby/lib/ably/realtime/presence/members_map.rb +16 -13
  30. data/lib/submodules/ably-ruby/lib/ably/rest/channel.rb +3 -2
  31. data/lib/submodules/ably-ruby/lib/ably/rest/client.rb +2 -2
  32. data/lib/submodules/ably-ruby/lib/ably/rest/presence.rb +4 -4
  33. data/lib/submodules/ably-ruby/lib/ably/util/pub_sub.rb +1 -1
  34. data/lib/submodules/ably-ruby/lib/ably/util/safe_deferrable.rb +1 -1
  35. data/lib/submodules/ably-ruby/lib/ably/version.rb +1 -1
  36. data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_history_spec.rb +1 -1
  37. data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_spec.rb +5 -15
  38. data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_failures_spec.rb +2 -2
  39. data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_spec.rb +16 -14
  40. data/lib/submodules/ably-ruby/spec/acceptance/realtime/message_spec.rb +91 -8
  41. data/lib/submodules/ably-ruby/spec/acceptance/realtime/presence_spec.rb +190 -71
  42. data/lib/submodules/ably-ruby/spec/acceptance/realtime/stats_spec.rb +2 -2
  43. data/lib/submodules/ably-ruby/spec/acceptance/rest/channel_spec.rb +1 -1
  44. data/lib/submodules/ably-ruby/spec/acceptance/rest/encoders_spec.rb +1 -1
  45. data/lib/submodules/ably-ruby/spec/acceptance/rest/message_spec.rb +73 -1
  46. data/lib/submodules/ably-ruby/spec/acceptance/rest/presence_spec.rb +4 -2
  47. data/lib/submodules/ably-ruby/spec/unit/models/{paginated_resource_spec.rb → paginated_result_spec.rb} +18 -18
  48. data/lib/submodules/ably-ruby/spec/unit/modules/event_emitter_spec.rb +27 -27
  49. data/lib/submodules/ably-ruby/spec/unit/modules/state_emitter_spec.rb +1 -1
  50. data/lib/submodules/ably-ruby/spec/unit/realtime/channel_spec.rb +2 -2
  51. data/lib/submodules/ably-ruby/spec/unit/realtime/connection_spec.rb +3 -3
  52. data/lib/submodules/ably-ruby/spec/unit/realtime/presence_spec.rb +2 -2
  53. metadata +35 -33
  54. data/LICENSE.txt +0 -22
  55. data/lib/submodules/ably-ruby/LICENSE.txt +0 -22
@@ -24,7 +24,7 @@ Gem::Specification.new do |spec|
24
24
  spec.add_runtime_dependency 'faraday', '~> 0.9'
25
25
  spec.add_runtime_dependency 'json'
26
26
  spec.add_runtime_dependency 'websocket-driver', '~> 0.3'
27
- spec.add_runtime_dependency 'msgpack-ably', '~> 0.5.10'
27
+ spec.add_runtime_dependency 'msgpack', '0.6.0pre1'
28
28
 
29
29
  spec.add_development_dependency 'bundler', '~> 1.3'
30
30
  spec.add_development_dependency 'rake'
@@ -1,5 +1,5 @@
1
1
  %w(modules util).each do |namespace|
2
- Dir.glob(File.expand_path("ably/#{namespace}/*.rb", File.dirname(__FILE__))).each do |file|
2
+ Dir.glob(File.expand_path("ably/#{namespace}/*.rb", File.dirname(__FILE__))).sort.each do |file|
3
3
  require file
4
4
  end
5
5
  end
@@ -60,7 +60,7 @@ module Ably
60
60
  # The HTTP request has returned a 500 error
61
61
  class ServerError < BaseAblyException; end
62
62
 
63
- # PaginatedResource cannot retrieve the page
63
+ # PaginatedResult cannot retrieve the page
64
64
  class InvalidPageError < BaseAblyException; end
65
65
 
66
66
  # The expected response from the server was invalid
@@ -74,5 +74,8 @@ module Ably
74
74
 
75
75
  # The message could not be delivered to the server
76
76
  class MessageDeliveryError < BaseAblyException; end
77
+
78
+ # The data payload type is not supported
79
+ class UnsupportedDataTypeError < BaseAblyException; end
77
80
  end
78
81
  end
@@ -6,10 +6,10 @@ module Ably::Models
6
6
  #
7
7
  # Paging information is provided by Ably in the LINK HTTP headers
8
8
  #
9
- class PaginatedResource
9
+ class PaginatedResult
10
10
  include Ably::Modules::AsyncWrapper if defined?(Ably::Realtime)
11
11
 
12
- # The items contained within this {PaginatedResource}
12
+ # The items contained within this {PaginatedResult}
13
13
  # @return [Array]
14
14
  attr_reader :items
15
15
 
@@ -17,11 +17,11 @@ module Ably::Models
17
17
  # @param [String] base_url Base URL for request that generated the http_response so that subsequent paged requests can be made
18
18
  # @param [Client] client {Ably::Client} used to make the request to Ably
19
19
  # @param [Hash] options Options for this paged resource
20
- # @option options [Symbol,String] :coerce_into symbol or string representing class that should be used to create each item in the PaginatedResource
20
+ # @option options [Symbol,String] :coerce_into symbol or string representing class that should be used to create each item in the PaginatedResult
21
21
  #
22
22
  # @yield [Object] block will be called for each resource object for the current page. This is a useful way to apply a transformation to any page resources after they are retrieved
23
23
  #
24
- # @return [PaginatedResource]
24
+ # @return [PaginatedResult]
25
25
  def initialize(http_response, base_url, client, options = {}, &each_block)
26
26
  @http_response = http_response
27
27
  @client = client
@@ -40,11 +40,11 @@ module Ably::Models
40
40
  # When used as part of the {Ably::Realtime} library, it will return a {Ably::Util::SafeDeferrable} object,
41
41
  # and allows an optional success callback block to be provided.
42
42
  #
43
- # @return [PaginatedResource,Ably::Util::SafeDeferrable]
43
+ # @return [PaginatedResult,Ably::Util::SafeDeferrable]
44
44
  def first(&success_callback)
45
45
  async_wrap_if_realtime(success_callback) do
46
46
  return nil unless supports_pagination?
47
- PaginatedResource.new(client.get(pagination_url('first')), base_url, client, pagination_options, &each_block)
47
+ PaginatedResult.new(client.get(pagination_url('first')), base_url, client, pagination_options, &each_block)
48
48
  end
49
49
  end
50
50
 
@@ -52,11 +52,11 @@ module Ably::Models
52
52
  # When used as part of the {Ably::Realtime} library, it will return a {Ably::Util::SafeDeferrable} object,
53
53
  # and allows an optional success callback block to be provided.
54
54
  #
55
- # @return [PaginatedResource,Ably::Util::SafeDeferrable]
55
+ # @return [PaginatedResult,Ably::Util::SafeDeferrable]
56
56
  def next(&success_callback)
57
57
  async_wrap_if_realtime(success_callback) do
58
58
  return nil unless has_next?
59
- PaginatedResource.new(client.get(pagination_url('next')), base_url, client, pagination_options, &each_block)
59
+ PaginatedResult.new(client.get(pagination_url('next')), base_url, client, pagination_options, &each_block)
60
60
  end
61
61
  end
62
62
 
@@ -20,7 +20,7 @@ module Ably::Models
20
20
  # via the Ably Realtime service.
21
21
  #
22
22
  # @!attribute [r] action
23
- # @return [STATE] the state change event signified by a PresenceMessage
23
+ # @return [ACTION] the state change event signified by a PresenceMessage
24
24
  # @!attribute [r] client_id
25
25
  # @return [String] The client_id associated with this presence state
26
26
  # @!attribute [r] connection_id
@@ -96,5 +96,20 @@ module Ably::Modules
96
96
  rescue Encoding::UndefinedConversionError, Encoding::InvalidByteSequenceError => e
97
97
  raise ArgumentError, "#{field_name} could not be converted to UTF-8: #{e.message}"
98
98
  end
99
+
100
+ # Ensures that the payload is a type supported by all Ably client libraries.
101
+ # Ably guarantees interoperability between client libraries and subsequently
102
+ # client libraries must reject unsupported types
103
+ #
104
+ # @return <void>
105
+ #
106
+ def ensure_supported_payload(payload)
107
+ return if payload.kind_of?(String) ||
108
+ payload.kind_of?(Hash) ||
109
+ payload.kind_of?(Array) ||
110
+ payload.nil?
111
+
112
+ raise Ably::Exceptions::UnsupportedDataTypeError.new('Invalid data payload', 400, 40011)
113
+ end
99
114
  end
100
115
  end
@@ -58,9 +58,9 @@ module Ably::Modules
58
58
 
59
59
  set_hash_object message_hash
60
60
  rescue Ably::Exceptions::CipherError => cipher_error
61
- if channel.respond_to?(:trigger)
61
+ if channel.respond_to?(:emit)
62
62
  channel.client.logger.error "Encoder error #{cipher_error.code} trying to #{method} message: #{cipher_error.message}"
63
- channel.trigger :error, cipher_error
63
+ channel.emit :error, cipher_error
64
64
  else
65
65
  raise cipher_error
66
66
  end
@@ -2,7 +2,7 @@ require 'ably/modules/safe_yield'
2
2
 
3
3
  module Ably
4
4
  module Modules
5
- # EventEmitter provides methods to attach to public events and trigger events on any class instance
5
+ # EventEmitter provides methods to attach to public events and emit events on any class instance
6
6
  #
7
7
  # EventEmitter are typically used for public interfaces, and as such, may be overriden in
8
8
  # the classes to enforce `event` names match expected values.
@@ -16,7 +16,7 @@ module Ably
16
16
  #
17
17
  # event_emitter = Example.new
18
18
  # event_emitter.on(:signal) { |name| puts "Signal #{name} received" }
19
- # event_emitter.trigger :signal, "Test"
19
+ # event_emitter.emit :signal, "Test"
20
20
  # #=> "Signal Test received"
21
21
  #
22
22
  module EventEmitter
@@ -84,15 +84,15 @@ module Ably
84
84
  end
85
85
  end
86
86
 
87
- # Trigger an event with event_name that will in turn call all matching callbacks setup with `on`
88
- def trigger(event_name, *args)
87
+ # Emit an event with event_name that will in turn call all matching callbacks setup with `on`
88
+ def emit(event_name, *args)
89
89
  callbacks[callbacks_event_coerced(event_name)].
90
90
  clone.
91
91
  select do |proc_hash|
92
92
  if proc_hash[:unsafe]
93
- proc_hash[:trigger_proc].call *args
93
+ proc_hash[:emit_proc].call *args
94
94
  else
95
- safe_yield proc_hash[:trigger_proc], *args
95
+ safe_yield proc_hash[:emit_proc], *args
96
96
  end
97
97
  end.each do |callback|
98
98
  callbacks[callbacks_event_coerced(event_name)].delete callback
@@ -129,10 +129,10 @@ module Ably
129
129
  end
130
130
 
131
131
  # Create a Hash with a proc that calls the provided block and returns true if option :delete_once_run is set to true.
132
- # #trigger automatically deletes any blocks that return true thus allowing a block to be run once
132
+ # #emit automatically deletes any blocks that return true thus allowing a block to be run once
133
133
  def proc_for_block(block, options = {})
134
134
  {
135
- trigger_proc: Proc.new do |*args|
135
+ emit_proc: Proc.new do |*args|
136
136
  block.call *args
137
137
  true if options[:delete_once_run]
138
138
  end,
@@ -3,7 +3,7 @@ require 'eventmachine'
3
3
  module Ably::Modules
4
4
  # SafeDeferrable module provides an EventMachine::Deferrable interface to the object it is included in
5
5
  # and is safe to use for for public interfaces of this client library.
6
- # Any exceptions raised in the success or failure callbacks is caught and logged to #logger
6
+ # Any exceptions raised in the success or failure callbacks are caught and logged to #logger
7
7
  #
8
8
  # An exception in a callback provided by a developer should not break this client library
9
9
  # and stop further execution of code.
@@ -18,6 +18,9 @@ module Ably::Modules
18
18
  # Specify a block to be executed if and when the Deferrable object receives
19
19
  # a status of :succeeded.
20
20
  # See http://www.rubydoc.info/gems/eventmachine/1.0.7/EventMachine/Deferrable#callback-instance_method
21
+ #
22
+ # @return [void]
23
+ #
21
24
  def callback(&block)
22
25
  super do |*args|
23
26
  safe_deferrable_block(*args, &block)
@@ -27,20 +30,29 @@ module Ably::Modules
27
30
  # Specify a block to be executed if and when the Deferrable object receives
28
31
  # a status of :failed.
29
32
  # See http://www.rubydoc.info/gems/eventmachine/1.0.7/EventMachine/Deferrable#errback-instance_method
33
+ #
34
+ # @return [void]
35
+ #
30
36
  def errback(&block)
31
37
  super do |*args|
32
38
  safe_deferrable_block(*args, &block)
33
39
  end
34
40
  end
35
41
 
36
- # Mark the Deferrable as succeeded and trigger all callbacks
42
+ # Mark the Deferrable as succeeded and trigger all callbacks.
37
43
  # See http://www.rubydoc.info/gems/eventmachine/1.0.7/EventMachine/Deferrable#succeed-instance_method
44
+ #
45
+ # @return [void]
46
+ #
38
47
  def succeed(*args)
39
48
  super(*args)
40
49
  end
41
50
 
42
- # Mark the Deferrable as failed and trigger all callbacks
51
+ # Mark the Deferrable as failed and trigger all callbacks.
43
52
  # See http://www.rubydoc.info/gems/eventmachine/1.0.7/EventMachine/Deferrable#fail-instance_method
53
+ #
54
+ # @return [void]
55
+ #
44
56
  def fail(*args)
45
57
  super(*args)
46
58
  end
@@ -26,7 +26,7 @@ module Ably::Modules
26
26
  # connection.connecting? # => true
27
27
  # connection.state # => STATE.Connecting
28
28
  # connection.state = :invalid # raises an Exception as only a valid state can be defined
29
- # connection.trigger :invalid # raises an Exception as only a valid state can be used for EventEmitter
29
+ # connection.emit :invalid # raises an Exception as only a valid state can be used for EventEmitter
30
30
  # connection.change_state :connected # emits :connected event via EventEmitter, returns STATE.Connected
31
31
  # connection.once_or_if(:connected) { puts 'block called once when state is connected or becomes connected' }
32
32
  #
@@ -53,7 +53,7 @@ module Ably::Modules
53
53
  if state != new_state
54
54
  logger.debug("#{self.class}: StateEmitter changed from #{state} => #{new_state}") if respond_to?(:logger, true)
55
55
  @state = STATE(new_state)
56
- trigger @state, *args
56
+ emit @state, *args
57
57
  end
58
58
  end
59
59
  alias_method :change_state, :state=
@@ -24,7 +24,7 @@ module Ably::Modules
24
24
  def transition_state(state, *args)
25
25
  unless result = transition_to(state, *args)
26
26
  exception = exception_for_state_change_to(state)
27
- object.trigger :error, exception
27
+ object.emit :error, exception
28
28
  logger.fatal "#{self.class}: #{exception.message}"
29
29
  end
30
30
  result
@@ -122,6 +122,7 @@ module Ably
122
122
  #
123
123
  def publish(name, data, &success_block)
124
124
  ensure_utf_8 :name, name
125
+ ensure_supported_payload data
125
126
 
126
127
  create_message(name, data).tap do |message|
127
128
  message.callback(&success_block) if block_given?
@@ -181,12 +182,9 @@ module Ably
181
182
  # presence on the channel and may also be used to obtain presence information
182
183
  # and change events for other members of the channel.
183
184
  #
184
- # When accessing presence, if the channel is not attached, the channel is implicitly attached
185
- #
186
185
  # @return {Ably::Realtime::Presence}
187
186
  #
188
187
  def presence
189
- attach if initialized?
190
188
  @presence
191
189
  end
192
190
 
@@ -200,7 +198,7 @@ module Ably
200
198
  # @option options (see Ably::Rest::Channel#history)
201
199
  # @option options [Boolean] :until_attach When true, the history request will be limited only to messages published before this channel was attached. Channel must be attached
202
200
  #
203
- # @yield [Ably::Models::PaginatedResource<Ably::Models::Message>] First {Ably::Models::PaginatedResource page} of {Ably::Models::Message} objects accessible with {Ably::Models::PaginatedResource#items #items}.
201
+ # @yield [Ably::Models::PaginatedResult<Ably::Models::Message>] First {Ably::Models::PaginatedResult page} of {Ably::Models::Message} objects accessible with {Ably::Models::PaginatedResult#items #items}.
204
202
  #
205
203
  # @return [Ably::Util::SafeDeferrable]
206
204
  #
@@ -46,7 +46,7 @@ module Ably::Realtime
46
46
  # An error has occurred on the channel
47
47
  def emit_error(error)
48
48
  logger.error "ChannelManager: Channel '#{channel.name}' error: #{error}"
49
- channel.trigger :error, error
49
+ channel.emit :error, error
50
50
  end
51
51
 
52
52
  # Detach a channel as a result of an error
@@ -44,7 +44,7 @@ module Ably
44
44
 
45
45
  # When true, as soon as the client library is instantiated it will connect to Ably. If this attribute is false, a connection must be opened explicitly
46
46
  # @return [Boolean]
47
- attr_reader :connect_automatically
47
+ attr_reader :auto_connect
48
48
 
49
49
  # When a recover option is specified a connection inherits the state of a previous connection that may have existed under a different instance of the Realtime library, please refer to the API documentation for further information on connection state recovery
50
50
  # @return [String,Nil]
@@ -62,7 +62,7 @@ module Ably
62
62
  # @option options [Boolean] :queue_messages If false, this disables the default behaviour whereby the library queues messages on a connection in the disconnected or connecting states
63
63
  # @option options [Boolean] :echo_messages If false, prevents messages originating from this connection being echoed back on the same connection
64
64
  # @option options [String] :recover When a recover option is specified a connection inherits the state of a previous connection that may have existed under a different instance of the Realtime library, please refer to the API documentation for further information on connection state recovery
65
- # @option options [Boolean] :connect_automatically By default as soon as the client library is instantiated it will connect to Ably. You can optionally set this to false and explicitly connect.
65
+ # @option options [Boolean] :auto_connect By default as soon as the client library is instantiated it will connect to Ably. You can optionally set this to false and explicitly connect.
66
66
  #
67
67
  # @return [Ably::Realtime::Client]
68
68
  #
@@ -79,7 +79,7 @@ module Ably
79
79
  @channels = Ably::Realtime::Channels.new(self)
80
80
  @echo_messages = @rest_client.options.fetch(:echo_messages, true) == false ? false : true
81
81
  @custom_realtime_host = @rest_client.options[:realtime_host] || @rest_client.options[:ws_host]
82
- @connect_automatically = @rest_client.options.fetch(:connect_automatically, true) == false ? false : true
82
+ @auto_connect = @rest_client.options.fetch(:auto_connect, true) == false ? false : true
83
83
  @recover = @rest_client.options[:recover]
84
84
 
85
85
  raise ArgumentError, "Recovery key is invalid" if @recover && !@recover.match(Connection::RECOVER_REGEX)
@@ -110,7 +110,7 @@ module Ably
110
110
  # @param (see Ably::Rest::Client#stats)
111
111
  # @option options (see Ably::Rest::Client#stats)
112
112
  #
113
- # @yield [Ably::Models::PaginatedResource<Ably::Models::Stats>] An Array of Stats
113
+ # @yield [Ably::Models::PaginatedResult<Ably::Models::Stats>] An Array of Stats
114
114
  #
115
115
  # @return [Ably::Util::SafeDeferrable]
116
116
  #
@@ -49,7 +49,7 @@ module Ably::Realtime
49
49
  connection
50
50
  end
51
51
  error_message = "Protocol error, duplicate message received for serial #{protocol_message.connection_serial}"
52
- error_target.trigger :error, Ably::Exceptions::ProtocolError.new(error_message, 400, 80013)
52
+ error_target.emit :error, Ably::Exceptions::ProtocolError.new(error_message, 400, 80013)
53
53
  logger.error error_message
54
54
  return
55
55
  end
@@ -117,7 +117,7 @@ module Ably::Realtime
117
117
 
118
118
  else
119
119
  error = Ably::Exceptions::ProtocolError.new("Protocol Message Action #{protocol_message.action} is unsupported by this MessageDispatcher", 400, 80013)
120
- client.connection.trigger :error, error
120
+ client.connection.emit :error, error
121
121
  logger.fatal error.message
122
122
  end
123
123
  end
@@ -200,7 +200,7 @@ module Ably
200
200
  end
201
201
 
202
202
  # @!attribute [r] recovery_key
203
- # @return [String] recovery key that can be used by another client to recover this connection with the :recover option
203
+ # @return [String] recovery key that can be used by another client to recover this connection with the :recover option
204
204
  def recovery_key
205
205
  "#{key}:#{serial}" if connection_resumable?
206
206
  end
@@ -370,7 +370,7 @@ module Ably
370
370
  @error_reason = nil
371
371
  end
372
372
 
373
- # Triggers registered callbacks for a successful connection resume event
373
+ # Executes registered callbacks for a successful connection resume event
374
374
  # @api private
375
375
  def resumed
376
376
  resume_callbacks.each(&:call)
@@ -39,7 +39,7 @@ module Ably::Realtime
39
39
 
40
40
  EventMachine.next_tick do
41
41
  # Connect once Connection object is initialised
42
- connection.connect if client.connect_automatically
42
+ connection.connect if client.auto_connect
43
43
  end
44
44
  end
45
45
 
@@ -144,7 +144,7 @@ module Ably::Realtime
144
144
  def fail(error)
145
145
  connection.logger.fatal "ConnectionManager: Connection failed - #{error}"
146
146
  connection.manager.destroy_transport
147
- connection.unsafe_once(:failed) { connection.trigger :error, error }
147
+ connection.unsafe_once(:failed) { connection.emit :error, error }
148
148
  end
149
149
 
150
150
  # When a connection is disconnected whilst connecting, attempt reconnect and/or set state to :suspended or :failed
@@ -178,7 +178,7 @@ module Ably::Realtime
178
178
 
179
179
  error = current_transition.metadata
180
180
  if error.kind_of?(Ably::Models::ErrorInfo) && error.code != RESOLVABLE_ERROR_CODES.fetch(:token_expired)
181
- connection.trigger :error, error
181
+ connection.emit :error, error
182
182
  logger.error "ConnectionManager: Error in Disconnected ProtocolMessage received from the server - #{error}"
183
183
  end
184
184
 
@@ -48,7 +48,7 @@ module Ably::Realtime
48
48
  protocol_message = current_transition.metadata
49
49
  if is_error_type?(protocol_message.error)
50
50
  connection.logger.warn "ConnectionManager: Connected with error - #{protocol_message.error.message}"
51
- connection.trigger :error, protocol_message.error
51
+ connection.emit :error, protocol_message.error
52
52
  end
53
53
  end
54
54
 
@@ -25,7 +25,7 @@ module Ably::Realtime
25
25
  end
26
26
 
27
27
  # Disconnect the socket transport connection and write all pending text.
28
- # If Disconnected state is not automatically triggered, it will be triggered automatically
28
+ # If Disconnected state is not automatically emitted, it will be emitted automatically
29
29
  # @return [void]
30
30
  # @api public
31
31
  def disconnect
@@ -149,7 +149,7 @@ module Ably::Realtime
149
149
 
150
150
  if protocol_message.invalid?
151
151
  error = Ably::Exceptions::ProtocolError.new("Invalid Protocol Message received: #{event_data}\nMessage has been discarded", 400, 80013)
152
- connection.trigger :error, error
152
+ connection.emit :error, error
153
153
  logger.fatal "WebsocketTransport: #{error.message}"
154
154
  else
155
155
  __incoming_protocol_msgbus__.publish :protocol_message, protocol_message
@@ -1,6 +1,7 @@
1
1
  module Ably::Realtime
2
2
  # Presence provides access to presence operations and state for the associated Channel
3
3
  class Presence
4
+ include Ably::Modules::Conversions
4
5
  include Ably::Modules::EventEmitter
5
6
  include Ably::Modules::AsyncWrapper
6
7
  include Ably::Modules::MessageEmitter
@@ -69,11 +70,16 @@ module Ably::Realtime
69
70
  # @return [Ably::Util::SafeDeferrable] Deferrable that supports both success (callback) and failure (errback) callbacks
70
71
  #
71
72
  def enter(options = {}, &success_block)
72
- @client_id = options.fetch(:client_id, client_id)
73
- @data = options.fetch(:data, nil)
73
+ client_id = options.fetch(:client_id, self.client_id)
74
+ data = options.fetch(:data, nil)
74
75
  deferrable = create_deferrable
75
76
 
77
+ ensure_supported_payload data unless data.nil?
76
78
  raise Ably::Exceptions::Standard.new('Unable to enter presence channel without a client_id', 400, 91000) unless client_id
79
+
80
+ @data = data
81
+ @client_id = client_id
82
+
77
83
  return deferrable_succeed(deferrable, &success_block) if state == STATE.Entered
78
84
 
79
85
  ensure_channel_attached(deferrable) do
@@ -113,6 +119,7 @@ module Ably::Realtime
113
119
  #
114
120
  def enter_client(client_id, options = {}, &success_block)
115
121
  raise ArgumentError, 'options must be a Hash' unless options.kind_of?(Hash)
122
+ ensure_supported_payload options[:data] if options.has_key?(:data)
116
123
  raise Ably::Exceptions::Standard.new('Unable to enter presence channel without a client_id', 400, 91000) unless client_id
117
124
 
118
125
  send_presence_action_for_client(Ably::Models::PresenceMessage::ACTION.Enter, client_id, options, &success_block)
@@ -128,10 +135,14 @@ module Ably::Realtime
128
135
  # @return (see Presence#enter)
129
136
  #
130
137
  def leave(options = {}, &success_block)
131
- @data = options.fetch(:data, data) # nil value defaults leave data to existing value
138
+ data = options.fetch(:data, self.data) # nil value defaults leave data to existing value
132
139
  deferrable = create_deferrable
133
140
 
141
+ ensure_supported_payload data unless data.nil?
134
142
  raise Ably::Exceptions::Standard.new('Unable to leave presence channel that is not entered', 400, 91002) unless able_to_leave?
143
+
144
+ @data = data
145
+
135
146
  return deferrable_succeed(deferrable, &success_block) if state == STATE.Left
136
147
 
137
148
  ensure_channel_attached(deferrable) do
@@ -165,6 +176,7 @@ module Ably::Realtime
165
176
  #
166
177
  def leave_client(client_id, options = {}, &success_block)
167
178
  raise ArgumentError, 'options must be a Hash' unless options.kind_of?(Hash)
179
+ ensure_supported_payload options[:data] if options.has_key?(:data)
168
180
  raise Ably::Exceptions::Standard.new('Unable to leave presence channel without a client_id', 400, 91000) unless client_id
169
181
 
170
182
  send_presence_action_for_client(Ably::Models::PresenceMessage::ACTION.Leave, client_id, options, &success_block)
@@ -181,9 +193,14 @@ module Ably::Realtime
181
193
  # @return (see Presence#enter)
182
194
  #
183
195
  def update(options = {}, &success_block)
184
- @data = options.fetch(:data, nil)
196
+ data = options.fetch(:data, nil)
185
197
  deferrable = create_deferrable
186
198
 
199
+ ensure_supported_payload data unless data.nil?
200
+ raise Ably::Exceptions::Standard.new('Unable to update presence channel without a client_id', 400, 91000) unless client_id
201
+
202
+ @data = data
203
+
187
204
  ensure_channel_attached(deferrable) do
188
205
  send_protocol_message_and_transition_state_to(
189
206
  Ably::Models::PresenceMessage::ACTION.Update,
@@ -210,6 +227,7 @@ module Ably::Realtime
210
227
  #
211
228
  def update_client(client_id, options = {}, &success_block)
212
229
  raise ArgumentError, 'options must be a Hash' unless options.kind_of?(Hash)
230
+ ensure_supported_payload options[:data] if options.has_key?(:data)
213
231
  raise Ably::Exceptions::Standard.new('Unable to enter presence channel without a client_id', 400, 91000) unless client_id
214
232
 
215
233
  send_presence_action_for_client(Ably::Models::PresenceMessage::ACTION.Update, client_id, options, &success_block)
@@ -274,7 +292,7 @@ module Ably::Realtime
274
292
  # @option options (see Ably::Rest::Presence#history)
275
293
  # @option options [Boolean] :until_attach When true, request for history will be limited only to messages published before the associated channel was attached. The associated channel must be attached.
276
294
  #
277
- # @yield [Ably::Models::PaginatedResource<Ably::Models::PresenceMessage>] First {Ably::Models::PaginatedResource page} of {Ably::Models::PresenceMessage} objects accessible with {Ably::Models::PaginatedResource#items #items}.
295
+ # @yield [Ably::Models::PaginatedResult<Ably::Models::PresenceMessage>] First {Ably::Models::PaginatedResult page} of {Ably::Models::PresenceMessage} objects accessible with {Ably::Models::PaginatedResult#items #items}.
278
296
  #
279
297
  # @return [Ably::Util::SafeDeferrable]
280
298
  #