ably-rest 0.9.3 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ably-rest.gemspec +2 -1
- data/lib/submodules/ably-ruby/.travis.yml +6 -4
- data/lib/submodules/ably-ruby/CHANGELOG.md +52 -61
- data/lib/submodules/ably-ruby/README.md +10 -0
- data/lib/submodules/ably-ruby/SPEC.md +1473 -852
- data/lib/submodules/ably-ruby/ably.gemspec +2 -1
- data/lib/submodules/ably-ruby/lib/ably/auth.rb +57 -25
- data/lib/submodules/ably-ruby/lib/ably/exceptions.rb +34 -8
- data/lib/submodules/ably-ruby/lib/ably/logger.rb +10 -1
- data/lib/submodules/ably-ruby/lib/ably/models/auth_details.rb +42 -0
- data/lib/submodules/ably-ruby/lib/ably/models/channel_state_change.rb +18 -4
- data/lib/submodules/ably-ruby/lib/ably/models/connection_details.rb +6 -3
- data/lib/submodules/ably-ruby/lib/ably/models/connection_state_change.rb +4 -3
- data/lib/submodules/ably-ruby/lib/ably/models/error_info.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/models/message.rb +12 -1
- data/lib/submodules/ably-ruby/lib/ably/models/message_encoders/base.rb +101 -97
- data/lib/submodules/ably-ruby/lib/ably/models/presence_message.rb +13 -1
- data/lib/submodules/ably-ruby/lib/ably/models/protocol_message.rb +20 -3
- data/lib/submodules/ably-ruby/lib/ably/modules/async_wrapper.rb +7 -3
- data/lib/submodules/ably-ruby/lib/ably/modules/enum.rb +17 -7
- data/lib/submodules/ably-ruby/lib/ably/modules/event_emitter.rb +29 -14
- data/lib/submodules/ably-ruby/lib/ably/modules/state_emitter.rb +7 -4
- data/lib/submodules/ably-ruby/lib/ably/modules/state_machine.rb +2 -4
- data/lib/submodules/ably-ruby/lib/ably/modules/uses_state_machine.rb +7 -3
- data/lib/submodules/ably-ruby/lib/ably/realtime.rb +2 -0
- data/lib/submodules/ably-ruby/lib/ably/realtime/auth.rb +79 -31
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel.rb +62 -26
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel/channel_manager.rb +154 -65
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel/channel_state_machine.rb +14 -15
- data/lib/submodules/ably-ruby/lib/ably/realtime/client.rb +16 -3
- data/lib/submodules/ably-ruby/lib/ably/realtime/client/incoming_message_dispatcher.rb +38 -29
- data/lib/submodules/ably-ruby/lib/ably/realtime/client/outgoing_message_dispatcher.rb +6 -1
- data/lib/submodules/ably-ruby/lib/ably/realtime/connection.rb +108 -49
- data/lib/submodules/ably-ruby/lib/ably/realtime/connection/connection_manager.rb +165 -59
- data/lib/submodules/ably-ruby/lib/ably/realtime/connection/connection_state_machine.rb +22 -3
- data/lib/submodules/ably-ruby/lib/ably/realtime/connection/websocket_transport.rb +19 -10
- data/lib/submodules/ably-ruby/lib/ably/realtime/presence.rb +67 -45
- data/lib/submodules/ably-ruby/lib/ably/realtime/presence/members_map.rb +198 -36
- data/lib/submodules/ably-ruby/lib/ably/realtime/presence/presence_manager.rb +30 -6
- data/lib/submodules/ably-ruby/lib/ably/realtime/presence/presence_state_machine.rb +5 -12
- data/lib/submodules/ably-ruby/lib/ably/rest/channel.rb +3 -3
- data/lib/submodules/ably-ruby/lib/ably/rest/client.rb +21 -8
- data/lib/submodules/ably-ruby/lib/ably/rest/middleware/exceptions.rb +1 -3
- data/lib/submodules/ably-ruby/lib/ably/rest/middleware/logger.rb +2 -2
- data/lib/submodules/ably-ruby/lib/ably/rest/presence.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/util/pub_sub.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/util/safe_deferrable.rb +26 -0
- data/lib/submodules/ably-ruby/lib/ably/version.rb +2 -2
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/auth_spec.rb +416 -99
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_history_spec.rb +5 -3
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_spec.rb +1011 -160
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/client_spec.rb +2 -2
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_failures_spec.rb +458 -27
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_spec.rb +436 -97
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/message_spec.rb +52 -23
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/presence_history_spec.rb +5 -3
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/presence_spec.rb +1160 -105
- data/lib/submodules/ably-ruby/spec/acceptance/rest/auth_spec.rb +151 -22
- data/lib/submodules/ably-ruby/spec/acceptance/rest/channel_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/acceptance/rest/client_spec.rb +88 -27
- data/lib/submodules/ably-ruby/spec/acceptance/rest/message_spec.rb +42 -15
- data/lib/submodules/ably-ruby/spec/acceptance/rest/presence_spec.rb +4 -4
- data/lib/submodules/ably-ruby/spec/rspec_config.rb +2 -1
- data/lib/submodules/ably-ruby/spec/shared/client_initializer_behaviour.rb +2 -2
- data/lib/submodules/ably-ruby/spec/shared/safe_deferrable_behaviour.rb +6 -2
- data/lib/submodules/ably-ruby/spec/support/debug_failure_helper.rb +20 -4
- data/lib/submodules/ably-ruby/spec/support/event_machine_helper.rb +32 -1
- data/lib/submodules/ably-ruby/spec/unit/auth_spec.rb +4 -11
- data/lib/submodules/ably-ruby/spec/unit/logger_spec.rb +28 -2
- data/lib/submodules/ably-ruby/spec/unit/models/auth_details_spec.rb +49 -0
- data/lib/submodules/ably-ruby/spec/unit/models/channel_state_change_spec.rb +23 -3
- data/lib/submodules/ably-ruby/spec/unit/models/connection_details_spec.rb +12 -1
- data/lib/submodules/ably-ruby/spec/unit/models/connection_state_change_spec.rb +15 -4
- data/lib/submodules/ably-ruby/spec/unit/models/message_spec.rb +34 -2
- data/lib/submodules/ably-ruby/spec/unit/models/presence_message_spec.rb +73 -2
- data/lib/submodules/ably-ruby/spec/unit/models/protocol_message_spec.rb +64 -6
- data/lib/submodules/ably-ruby/spec/unit/models/token_details_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/unit/models/token_request_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/unit/modules/async_wrapper_spec.rb +2 -1
- data/lib/submodules/ably-ruby/spec/unit/modules/enum_spec.rb +69 -0
- data/lib/submodules/ably-ruby/spec/unit/modules/event_emitter_spec.rb +149 -22
- data/lib/submodules/ably-ruby/spec/unit/modules/state_emitter_spec.rb +9 -3
- data/lib/submodules/ably-ruby/spec/unit/realtime/client_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/unit/realtime/connection_spec.rb +8 -5
- data/lib/submodules/ably-ruby/spec/unit/realtime/incoming_message_dispatcher_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/unit/realtime/presence_spec.rb +4 -3
- data/lib/submodules/ably-ruby/spec/unit/rest/client_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/unit/util/crypto_spec.rb +3 -3
- metadata +7 -5
@@ -11,7 +11,7 @@ module Ably::Models
|
|
11
11
|
# @!attribute [r] attributes
|
12
12
|
# @return [Hash] Access the protocol message Hash object ruby'fied to use symbolized keys
|
13
13
|
#
|
14
|
-
class ErrorInfo
|
14
|
+
class ErrorInfo < Ably::Exceptions::BaseAblyException
|
15
15
|
include Ably::Modules::ModelCommon
|
16
16
|
|
17
17
|
def initialize(hash_object)
|
@@ -124,6 +124,17 @@ module Ably::Models
|
|
124
124
|
@protocol_message
|
125
125
|
end
|
126
126
|
|
127
|
+
# Contains any arbitrary key value pairs which may also contain other primitive JSON types, JSON-encodable objects or JSON-encodable arrays.
|
128
|
+
# The extras field is provided to contain message metadata and/or ancillary payloads in support of specific functionality, e.g. push
|
129
|
+
# @api private
|
130
|
+
def extras
|
131
|
+
attributes[:extras].tap do |val|
|
132
|
+
unless val.kind_of?(IdiomaticRubyWrapper) || val.kind_of?(Array) || val.kind_of?(Hash) || val.nil?
|
133
|
+
raise ArgumentError, "extras contains an unsupported type #{val.class}"
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
127
138
|
private
|
128
139
|
def raw_hash_object
|
129
140
|
@raw_hash_object
|
@@ -134,7 +145,7 @@ module Ably::Models
|
|
134
145
|
end
|
135
146
|
|
136
147
|
def set_attributes_object(new_attributes)
|
137
|
-
@attributes = IdiomaticRubyWrapper(new_attributes.clone.freeze, stop_at: [:data])
|
148
|
+
@attributes = IdiomaticRubyWrapper(new_attributes.clone.freeze, stop_at: [:data, :extras])
|
138
149
|
end
|
139
150
|
|
140
151
|
def logger
|
@@ -7,115 +7,119 @@ require 'ably/modules/conversions'
|
|
7
7
|
# of the message is defined as 'json'.
|
8
8
|
# Encrypted messages are encoded & decoded by the Cipher encoder.
|
9
9
|
#
|
10
|
-
module Ably
|
11
|
-
|
10
|
+
module Ably
|
11
|
+
module Models
|
12
|
+
module MessageEncoders
|
13
|
+
extend Ably::Modules::Conversions
|
12
14
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
15
|
+
# Base interface for an Ably Encoder
|
16
|
+
#
|
17
|
+
class Base
|
18
|
+
attr_reader :client, :options
|
17
19
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
20
|
+
def initialize(client, options = {})
|
21
|
+
@client = client
|
22
|
+
@options = options
|
23
|
+
end
|
22
24
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
25
|
+
# #encode is called once before a message is sent to Ably
|
26
|
+
#
|
27
|
+
# It is the responsibility of the #encode method to detect the intended encoding and modify the :data & :encoding properties of the message object.
|
28
|
+
#
|
29
|
+
# @param [Hash] message the message as a Hash object received directly from Ably.
|
30
|
+
# The message contains properties :name, :data, :encoding, :timestamp, and optionally :id and :client_id.
|
31
|
+
# This #encode method should modify the message Hash if any encoding action is to be taken
|
32
|
+
# @param [Hash] channel_options the options used to initialize the channel that this message was received on
|
33
|
+
#
|
34
|
+
# @return [void]
|
35
|
+
def encode(message, channel_options)
|
36
|
+
raise "Not yet implemented"
|
37
|
+
end
|
36
38
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
39
|
+
# #decode is called once for every encoding step
|
40
|
+
# i.e. if message encoding arrives with 'utf-8/cipher+aes-128-cbc/base64'
|
41
|
+
# the decoder will call #decode once for each encoding part such as 'base64', then 'cipher+aes-128-cbc', and finally 'utf-8'
|
42
|
+
#
|
43
|
+
# It is the responsibility of the #decode method to detect the current encoding part and modify the :data & :encoding properties of the message object.
|
44
|
+
#
|
45
|
+
# @param [Hash] message the message as a Hash object received directly from Ably.
|
46
|
+
# The message contains properties :name, :data, :encoding, :timestamp, and optionally :id and :client_id.
|
47
|
+
# This #encode method should modify the message Hash if any decoding action is to be taken
|
48
|
+
# @param [Hash] channel_options the options used to initialize the channel that this message was received on
|
49
|
+
#
|
50
|
+
# @return [void]
|
51
|
+
def decode(message, channel_options)
|
52
|
+
raise "Not yet implemented"
|
53
|
+
end
|
52
54
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
55
|
+
# Add encoding to the message Hash.
|
56
|
+
# Ensures that encoding delimeter is used where required i.e utf-8/cipher+aes-128-cbc/base64
|
57
|
+
#
|
58
|
+
# @param [Hash] message the message as a Hash object received directly from Ably.
|
59
|
+
# @param [String] encoding encoding to add to the current encoding
|
60
|
+
#
|
61
|
+
# @return [void]
|
62
|
+
def add_encoding_to_message(encoding, message)
|
63
|
+
message[:encoding] = [message[:encoding], encoding].compact.join('/')
|
64
|
+
end
|
63
65
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
66
|
+
# Returns the right most encoding form a meessage encoding, and nil if none exists
|
67
|
+
# i.e. current_encoding_part('utf-8/cipher+aes-128-cbc/base64') => 'base64'
|
68
|
+
#
|
69
|
+
# @return [String,nil]
|
70
|
+
def current_encoding_part(message)
|
71
|
+
if message[:encoding]
|
72
|
+
message[:encoding].split('/')[-1]
|
73
|
+
end
|
74
|
+
end
|
73
75
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
76
|
+
# Strip the current encoding part within the message Hash.
|
77
|
+
#
|
78
|
+
# For example, calling this method on an :encoding value of 'utf-8/cipher+aes-128-cbc/base64' would update the attribute
|
79
|
+
# :encoding to 'utf-8/cipher+aes-128-cbc'
|
80
|
+
#
|
81
|
+
# @param [Hash] message the message as a Hash object received directly from Ably.
|
82
|
+
#
|
83
|
+
# @return [void]
|
84
|
+
def strip_current_encoding_part(message)
|
85
|
+
raise "Cannot strip encoding when there is no encoding for this message" unless message[:encoding]
|
86
|
+
message[:encoding] = message[:encoding].split('/')[0...-1].join('/')
|
87
|
+
message[:encoding] = nil if message[:encoding].empty?
|
88
|
+
end
|
87
89
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
90
|
+
# True of the message data payload is empty
|
91
|
+
#
|
92
|
+
# @param [Hash] message the message as a Hash object received directly from Ably.
|
93
|
+
#
|
94
|
+
# @return [Boolean]
|
95
|
+
def is_empty?(message)
|
96
|
+
message[:data].nil? || message[:data] == ''
|
97
|
+
end
|
98
|
+
end
|
97
99
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
100
|
+
# @api private
|
101
|
+
def self.register_default_encoders(client, options = {})
|
102
|
+
binary_protocol = !!options[:binary_protocol]
|
103
|
+
client.register_encoder Ably::Models::MessageEncoders::Utf8
|
104
|
+
client.register_encoder Ably::Models::MessageEncoders::Json
|
105
|
+
client.register_encoder Ably::Models::MessageEncoders::Cipher
|
106
|
+
client.register_encoder Ably::Models::MessageEncoders::Base64, binary_protocol: binary_protocol
|
107
|
+
end
|
108
|
+
|
109
|
+
# @api private
|
110
|
+
def self.encoder_from(encoder, options)
|
111
|
+
encoder_klass = if encoder.kind_of?(String)
|
112
|
+
encoder.split('::').inject(Kernel) do |base, klass_name|
|
113
|
+
base.public_send(:const_get, klass_name)
|
114
|
+
end
|
115
|
+
else
|
116
|
+
encoder
|
117
|
+
end
|
106
118
|
|
107
|
-
|
108
|
-
|
109
|
-
encoder_klass = if encoder.kind_of?(String)
|
110
|
-
encoder.split('::').inject(Kernel) do |base, klass_name|
|
111
|
-
base.public_send(:const_get, klass_name)
|
119
|
+
raise "Encoder must inherit from `Ably::Models::MessageEncoders::Base`" unless encoder_klass.ancestors.include?(Ably::Models::MessageEncoders::Base)
|
120
|
+
encoder_klass.new(self, options)
|
112
121
|
end
|
113
|
-
else
|
114
|
-
encoder
|
115
122
|
end
|
116
|
-
|
117
|
-
raise "Encoder must inherit from `Ably::Models::MessageEncoders::Base`" unless encoder_klass.ancestors.include?(Ably::Models::MessageEncoders::Base)
|
118
|
-
encoder_klass.new(self, options)
|
119
123
|
end
|
120
124
|
end
|
121
125
|
|
@@ -123,7 +123,6 @@ module Ably::Models
|
|
123
123
|
end.to_json
|
124
124
|
end
|
125
125
|
|
126
|
-
|
127
126
|
# Assign this presence message to a ProtocolMessage before delivery to the Ably system
|
128
127
|
# @api private
|
129
128
|
def assign_to_protocol_message(protocol_message)
|
@@ -145,6 +144,19 @@ module Ably::Models
|
|
145
144
|
@protocol_message
|
146
145
|
end
|
147
146
|
|
147
|
+
# Create a static shallow clone of this object with the optional attributes to overide existing values
|
148
|
+
# Shallow clones have no dependency on the originating ProtocolMessage as all field values are stored as opposed to calculated
|
149
|
+
# Clones are useful when the original PresenceMessage needs to be mutated, such as storing in a PresenceMap with action :present
|
150
|
+
def shallow_clone(new_attributes = {})
|
151
|
+
new_attributes = IdiomaticRubyWrapper(new_attributes.clone.freeze, stop_at: [:data])
|
152
|
+
|
153
|
+
self.class.new(attributes.to_hash.merge(
|
154
|
+
id: new_attributes[:id] || id,
|
155
|
+
connection_id: new_attributes[:connection_id] || connection_id,
|
156
|
+
timestamp: new_attributes[:timestamp] || as_since_epoch(timestamp)
|
157
|
+
).merge(new_attributes.to_hash))
|
158
|
+
end
|
159
|
+
|
148
160
|
private
|
149
161
|
def raw_hash_object
|
150
162
|
@raw_hash_object
|
@@ -8,6 +8,8 @@ module Ably::Models
|
|
8
8
|
#
|
9
9
|
# @!attribute [r] action
|
10
10
|
# @return [ACTION] Protocol Message action {Ably::Modules::Enum} from list of {ACTION}. Returns nil if action is unsupported by protocol
|
11
|
+
# @!attribute [r] auth
|
12
|
+
# @return [Ably::Models::AuthDetails] Authentication details used to perform authentication upgrades over an existing transport
|
11
13
|
# @!attribute [r] count
|
12
14
|
# @return [Integer] The count field is used for ACK and NACK actions. See {http://docs.ably.io/client-lib-development-guide/protocol/#message-acknowledgement message acknowledgement protocol}
|
13
15
|
# @!attribute [r] error
|
@@ -15,7 +17,7 @@ module Ably::Models
|
|
15
17
|
# @!attribute [r] channel
|
16
18
|
# @return [String] Channel name for messages
|
17
19
|
# @!attribute [r] channel_serial
|
18
|
-
# @return [String] Contains a serial number for a message on the current
|
20
|
+
# @return [String] Contains a serial number for a message on the current channel
|
19
21
|
# @!attribute [r] connection_id
|
20
22
|
# @return [String] Contains a string public identifier for the connection
|
21
23
|
# @!attribute [r] connection_key
|
@@ -62,13 +64,14 @@ module Ably::Models
|
|
62
64
|
detached: 13,
|
63
65
|
presence: 14,
|
64
66
|
message: 15,
|
65
|
-
sync: 16
|
67
|
+
sync: 16,
|
68
|
+
auth: 17
|
66
69
|
)
|
67
70
|
|
68
71
|
# Indicates this protocol message action will generate an ACK response such as :message or :presence
|
69
72
|
# @api private
|
70
73
|
def self.ack_required?(for_action)
|
71
|
-
|
74
|
+
ACTION(for_action).match_any?(ACTION.Presence, ACTION.Message)
|
72
75
|
end
|
73
76
|
|
74
77
|
# {ProtocolMessage} initializer
|
@@ -193,10 +196,24 @@ module Ably::Models
|
|
193
196
|
flags & 1 == 1
|
194
197
|
end
|
195
198
|
|
199
|
+
# @api private
|
200
|
+
def has_backlog_flag?
|
201
|
+
flags & 2 == 2
|
202
|
+
end
|
203
|
+
|
204
|
+
# @api private
|
205
|
+
def has_channel_resumed_flag?
|
206
|
+
flags & 4 == 4
|
207
|
+
end
|
208
|
+
|
196
209
|
def connection_details
|
197
210
|
@connection_details ||= Ably::Models::ConnectionDetails(attributes[:connection_details])
|
198
211
|
end
|
199
212
|
|
213
|
+
def auth
|
214
|
+
@auth ||= Ably::Models::AuthDetails(attributes[:auth])
|
215
|
+
end
|
216
|
+
|
200
217
|
# Indicates this protocol message will generate an ACK response when sent
|
201
218
|
# Examples of protocol messages required ACK include :message and :presence
|
202
219
|
# @api private
|
@@ -38,7 +38,7 @@ module Ably::Modules
|
|
38
38
|
# @yield [Object] operation block that is run in a thread
|
39
39
|
# @return [Ably::Util::SafeDeferrable]
|
40
40
|
#
|
41
|
-
def async_wrap(success_callback = nil)
|
41
|
+
def async_wrap(success_callback = nil, custom_error_handling = nil)
|
42
42
|
raise ArgumentError, 'Block required' unless block_given?
|
43
43
|
|
44
44
|
Ably::Util::SafeDeferrable.new(logger).tap do |deferrable|
|
@@ -48,8 +48,12 @@ module Ably::Modules
|
|
48
48
|
begin
|
49
49
|
yield
|
50
50
|
rescue StandardError => err
|
51
|
-
|
52
|
-
|
51
|
+
if custom_error_handling
|
52
|
+
custom_error_handling.call err, deferrable
|
53
|
+
else
|
54
|
+
logger.error { "An exception in an AsyncWrapper block was caught. #{err.class}: #{err.message}\n#{err.backtrace.join("\n")}" }
|
55
|
+
deferrable.fail err
|
56
|
+
end
|
53
57
|
end
|
54
58
|
end
|
55
59
|
|
@@ -49,11 +49,11 @@ module Ably::Modules
|
|
49
49
|
def get(identifier)
|
50
50
|
case identifier
|
51
51
|
when Symbol
|
52
|
-
by_symbol.fetch(identifier)
|
52
|
+
by_symbol.fetch(identifier) { raise KeyError, "#{name} key not found: :#{identifier}" }
|
53
53
|
when String
|
54
|
-
by_symbol.fetch(convert_to_snake_case_symbol(identifier))
|
54
|
+
by_symbol.fetch(convert_to_snake_case_symbol(identifier)) { raise KeyError, "#{name} key not found: '#{identifier}'" }
|
55
55
|
when Numeric
|
56
|
-
by_index.fetch(identifier)
|
56
|
+
by_index.fetch(identifier) { raise KeyError, "#{name} key not found: #{identifier}" }
|
57
57
|
when ancestors.first
|
58
58
|
identifier
|
59
59
|
else
|
@@ -89,6 +89,12 @@ module Ably::Modules
|
|
89
89
|
@enum_name
|
90
90
|
end
|
91
91
|
|
92
|
+
# Array of Enum values as symbols
|
93
|
+
# @return [Array<Symbol>]
|
94
|
+
def to_sym_arr
|
95
|
+
@by_symbol.keys
|
96
|
+
end
|
97
|
+
|
92
98
|
private
|
93
99
|
def by_index
|
94
100
|
@by_index
|
@@ -158,7 +164,7 @@ module Ably::Modules
|
|
158
164
|
|
159
165
|
# Allow comparison of Enum objects based on:
|
160
166
|
#
|
161
|
-
# * Other equivalent Enum objects
|
167
|
+
# * Other equivalent Enum objects compared by Symbol (not Integer value)
|
162
168
|
# * Symbol
|
163
169
|
# * String
|
164
170
|
# * Integer index of Enum
|
@@ -171,13 +177,17 @@ module Ably::Modules
|
|
171
177
|
self.to_sym == convert_to_snake_case_symbol(other)
|
172
178
|
when Numeric
|
173
179
|
self.to_i == other.to_i
|
174
|
-
when self.class
|
175
|
-
self.to_i == other.to_i
|
176
180
|
else
|
177
|
-
|
181
|
+
if other.kind_of?(Ably::Modules::Enum::Base)
|
182
|
+
self.to_sym == other.to_sym
|
183
|
+
end
|
178
184
|
end
|
179
185
|
end
|
180
186
|
|
187
|
+
def match_any?(*enums)
|
188
|
+
enums.any? { |enum| self.==(enum) }
|
189
|
+
end
|
190
|
+
|
181
191
|
private
|
182
192
|
def name
|
183
193
|
@name
|
@@ -54,7 +54,7 @@ module Ably
|
|
54
54
|
end
|
55
55
|
|
56
56
|
# Equivalent of {#on} but any exception raised in a block will bubble up and cause this client library to fail.
|
57
|
-
# This method
|
57
|
+
# This method is designed to be used internally by the client library.
|
58
58
|
# @api private
|
59
59
|
def unsafe_on(*event_names, &block)
|
60
60
|
add_callback event_names, proc_for_block(block, unsafe: true)
|
@@ -70,7 +70,7 @@ module Ably
|
|
70
70
|
end
|
71
71
|
|
72
72
|
# Equivalent of {#once} but any exception raised in a block will bubble up and cause this client library to fail.
|
73
|
-
# This method
|
73
|
+
# This method is designed to be used internally by the client library.
|
74
74
|
# @api private
|
75
75
|
def unsafe_once(*event_names, &block)
|
76
76
|
add_callback event_names, proc_for_block(block, delete_once_run: true, unsafe: true)
|
@@ -101,30 +101,45 @@ module Ably
|
|
101
101
|
#
|
102
102
|
# @return [void]
|
103
103
|
def off(*event_names, &block)
|
104
|
+
off_internal(false, *event_names, &block)
|
105
|
+
end
|
106
|
+
|
107
|
+
# Equivalent of {#off} but only unsafe listeners are removed.
|
108
|
+
# This method is designed to be used internally by the client library.
|
109
|
+
# @api private
|
110
|
+
def unsafe_off(*event_names, &block)
|
111
|
+
off_internal(true, *event_names, &block)
|
112
|
+
end
|
113
|
+
|
114
|
+
private
|
115
|
+
def off_internal(unsafe, *event_names, &block)
|
104
116
|
keys = if event_names.empty?
|
105
117
|
callbacks.keys
|
106
118
|
else
|
107
119
|
event_names
|
108
120
|
end
|
109
121
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
122
|
+
if event_names.empty?
|
123
|
+
callbacks_any.delete_if do |proc_hash|
|
124
|
+
if block_given?
|
125
|
+
(proc_hash[:unsafe] == unsafe) && (proc_hash[:block] == block)
|
126
|
+
else
|
127
|
+
proc_hash[:unsafe] == unsafe
|
128
|
+
end
|
115
129
|
end
|
116
130
|
end
|
117
131
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
132
|
+
keys.each do |event_name|
|
133
|
+
callbacks[callbacks_event_coerced(event_name)].delete_if do |proc_hash|
|
134
|
+
if block_given?
|
135
|
+
(proc_hash[:unsafe] == unsafe) && (proc_hash[:block] == block)
|
136
|
+
else
|
137
|
+
proc_hash[:unsafe] == unsafe
|
138
|
+
end
|
123
139
|
end
|
124
140
|
end
|
125
141
|
end
|
126
142
|
|
127
|
-
private
|
128
143
|
def self.included(klass)
|
129
144
|
klass.extend ClassMethods
|
130
145
|
end
|
@@ -148,7 +163,7 @@ module Ably
|
|
148
163
|
true if options[:delete_once_run]
|
149
164
|
end,
|
150
165
|
block: block,
|
151
|
-
unsafe: options[:unsafe]
|
166
|
+
unsafe: options[:unsafe] || false
|
152
167
|
}
|
153
168
|
end
|
154
169
|
|