skyfall 0.6.1 → 0.7.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5d216f6eca172d8982c358d594511fa31212dd9dfdb949ed1149d16b23862bfa
4
- data.tar.gz: c381c2abebdb22265568b0183b7d78525a6cbbbd01192b32faad4ed1dadbec02
3
+ metadata.gz: a3e987d12df25109508c0f673894e9a334a81d60d02f57c118e699de5e68dc4d
4
+ data.tar.gz: 152dfdced7c5fc6414f8cbf04d7cff6d184c592a0ed42463f0b156b373c8c8ac
5
5
  SHA512:
6
- metadata.gz: 1d4c45ef3103036b5e13c5614615f20b61d9beaa7092af2058b8135cd4b460ede00c23b1d05cc5b57751a64a50e6286946d438ccd80c899023c9d92be6ac710e
7
- data.tar.gz: d7bd5bb732b86db3c56b9389a25a5e6d80f57629ec27621c32330ad0155c379864388eb347381e8f5e38387c4b22ce019fd4879c0e33eb46852e1565c2aef844
6
+ metadata.gz: 59c9da3c3d60b953f3963c16a86c56bb9e75561696ea47d0b8ce5a3274c00a8d831529f22aacace27df0d1dba55b5dc7db58301f1baa7aa19528756d77eb7ccd
7
+ data.tar.gz: 0575c825184297417f40a5f7248e2560fc24f19913631c23371b1f535feea3d3b38b62b76c0a4c610dafc2e52783ba58521eaf1f3407aa59699d26640fb0f94c
data/CHANGELOG.md CHANGED
@@ -1,3 +1,46 @@
1
+ ## [0.7.0] - 2026-02-13
2
+
3
+ The main change in this version is that inline YARD documentation has been added. This was also a good opportunity to review some APIs and tweak some things in order to get Skyfall a bit closer to 1.0.
4
+
5
+ New APIs:
6
+
7
+ - the `Skyfall::Firehose` initializer now allows skipping `:subscribe_repos`, i.e. `.new(host)` or `.new(host, cursor)`
8
+ - added `Skyfall::Jetstream::CommitMessage#operation` (aliased as `op`) which returns the (always single) operation in the `operations` array
9
+ - added `#kind` as alias for `#type` in both `Message` classes
10
+ - added a base class for error types, `Skyfall::Error`
11
+ - added `#blocks` to `Skyfall::Firehose::SyncMessage`
12
+ - added `#rev`, `#since` and `#prev_data` to `Skyfall::Firehose::CommitMessage`
13
+
14
+ Deprecated & removed APIs:
15
+
16
+ - removed deprecated `HandleMessage` and `TombstoneMessage` message classes
17
+ - removed deprecated `CommitMessage#prev`
18
+ - deprecated `#path` in both `Operation` classes
19
+
20
+ Optimizations:
21
+
22
+ - much faster `Skyfall::Firehose::Message#time` parsing on Ruby 3.2+
23
+ - lazy decoding of sections in `CarArchive` – saves quite a lot of work if sections are only accessed through `Operation#raw_record`
24
+ - added `frozen_string_literal: true` in all files to reduce garbage collection
25
+
26
+ Access level changes:
27
+
28
+ - restricted `Stream#start_heartbeat_timer` & `Stream#stop_heartbeat_timer` methods' access to private
29
+ - restricted `Stream#handle_message` method access to protected
30
+ - restricted `Stream#last_update` to read-only access
31
+ - restricted `#inspectable_variables` access to either private or protected
32
+ - relaxed `Stream#build_websocket_url` & `Stream#build_websocket_client` access from private to protected
33
+ - fixed private class method `Skyfall::Firehose::Message.decode_cbor_objects` which wasn't actually private
34
+
35
+ Additional validations and other changes:
36
+
37
+ - `Stream#connect` throws an error if neither `on_message` nor `on_raw_message` handlers have been configured
38
+ - `Message` subclasses do additional checks if the fields they require to not be nil aren't nil
39
+ - `Message` subclasses raise an error if `.new` is called on a subclass (and not on the base `Message`) passing the data of a wrong kind of message (instead of returning e.g. a `CommitMessage` from `AccountMessage.new` as it worked previously)
40
+ - made `LabelsMessage` a subclass of `Firehose::Message`
41
+ - fixed the `require`s config in some files so they can be loaded in any order
42
+
43
+
1
44
  ## [0.6.1] - 2026-01-08
2
45
 
3
46
  - added `:bsky_notif_declaration` shortcode for `app.bsky.notification.declaration` collection
@@ -7,7 +50,7 @@
7
50
 
8
51
  ## [0.6.0] - 2025-06-25
9
52
 
10
- - significantly speeded up reading of events from the binary firehose (`Skyfall::Firehose`) - up to 4-5x faster than before
53
+ - significantly speeded up reading of events from the binary firehose (`Skyfall::Firehose`) up to 4-5x faster than before
11
54
  - removed the `Skyfall::Stream.new` constructor deprecated in 0.5.0
12
55
 
13
56
  ## [0.5.1] - 2025-05-18
@@ -30,11 +73,11 @@ This required some breaking changes in the existing API:
30
73
 
31
74
  In most cases, you should only need to update the `Skyfall::Stream` class name in the constructor. If you've referenced message classes like `Skyfall::CommitMessage` directly, it's probably better to just check the `#type` property instead.
32
75
 
33
- Also, small change to the user agent API: `Skyfall::Stream` now has an additional metod `version_string`, which will always return `Skyfall/0.x.y` - it's recommended to use that instead of `default_user_agent` to build your own user agent string that includes the library version. `default_user_agent` now passes through to `version_string`, but it could be changed in future to return something else.
76
+ Also, small change to the user agent API: `Skyfall::Stream` now has an additional metod `version_string`, which will always return `Skyfall/0.x.y` it's recommended to use that instead of `default_user_agent` to build your own user agent string that includes the library version. `default_user_agent` now passes through to `version_string`, but it could be changed in future to return something else.
34
77
 
35
78
  ## [0.4.1] - 2024-10-04
36
79
 
37
- - performance fix - don't decode CAR sections which aren't needed, which is most of them; this cuts the amount of memory that GC has to free up by about one third, and should speed up processing by around ~10%
80
+ - performance fix don't decode CAR sections which aren't needed, which is most of them; this cuts the amount of memory that GC has to free up by about one third, and should speed up processing by around ~10%
38
81
 
39
82
  ## [0.4.0] - 2024-09-23
40
83
 
@@ -48,15 +91,15 @@ Also, small change to the user agent API: `Skyfall::Stream` now has an additiona
48
91
  - added `#account` event type (`AccountMessage`)
49
92
  - added `handle` field to `IdentityMessage`
50
93
  - fixed param validation on `Stream` initialization
51
- - reverted the change that added Ruby stdlib dependencies explicitly to the gemspec, since this causes more problems than it's worth - only `base64` is left there, since it's the one now required to be listed
94
+ - reverted the change that added Ruby stdlib dependencies explicitly to the gemspec, since this causes more problems than it's worth only `base64` is left there, since it's the one now required to be listed
52
95
 
53
96
  ## [0.3.0] - 2024-03-21
54
97
 
55
98
  - added support for labeller firehose, served by labeller services at the `com.atproto.label.subscribeLabels` endpoint (aliased as `:subscribe_labels`)
56
99
  - the `#labels` messages from the labeller firehose are parsed into a `LabelsMessage`, which includes a `labels` array of `Label` objects
57
100
  - `Stream` callbacks can now also be assigned via setters, e.g. `stream.on_message = proc { ... }`
58
- - added default error handler to `Stream` which logs the error to `$stdout` - set `stream.on_error = nil` to disable
59
- - added Ruby stdlib dependencies explicitly to the gemspec - fixes a warning in Ruby 3.3 when requiring `base64`, which will be extracted as an optional gem in 3.4
101
+ - added default error handler to `Stream` which logs the error to `$stdout` set `stream.on_error = nil` to disable
102
+ - added Ruby stdlib dependencies explicitly to the gemspec fixes a warning in Ruby 3.3 when requiring `base64`, which will be extracted as an optional gem in 3.4
60
103
 
61
104
  ## [0.2.5] - 2024-03-14
62
105
 
@@ -83,7 +126,7 @@ Also, small change to the user agent API: `Skyfall::Stream` now has an additiona
83
126
 
84
127
  ## [0.2.1] - 2023-08-19
85
128
 
86
- - optimized `WebsocketMessage` parsing performance - lazy parsing of most properties (message decoding should be over 50% faster on average)
129
+ - optimized `WebsocketMessage` parsing performance lazy parsing of most properties (message decoding should be over 50% faster on average)
87
130
  - added separate subclasses of `WebsocketMessage` for different message types
88
131
  - added support for `#handle`, `#info` and `#tombstone` message types
89
132
  - `UnknownMessage` is returned for unrecognized message types
@@ -91,13 +134,13 @@ Also, small change to the user agent API: `Skyfall::Stream` now has an additiona
91
134
  ## [0.2.0] - 2023-07-24
92
135
 
93
136
  - switched the websocket library from `websocket-client-simple` to `faye-websocket`, which should make event parsing up to ~30× faster (!)
94
- - added `auto_reconnect` property to `Stream` (on by default) - if true, it will try to reconnect with an exponential backoff when the websocket disconnects, until you call `Stream#disconnect`
137
+ - added `auto_reconnect` property to `Stream` (on by default) if true, it will try to reconnect with an exponential backoff when the websocket disconnects, until you call `Stream#disconnect`
95
138
 
96
139
  Note:
97
140
 
98
- - calling `sleep` is no longer needed after connecting - call `connect` on a new thread instead to get previously default behavior of running the event loop asynchronously
141
+ - calling `sleep` is no longer needed after connecting call `connect` on a new thread instead to get previously default behavior of running the event loop asynchronously
99
142
  - the disconnect event no longer passes an error object in the argument
100
- - there is currently no "heartbeat" feature as in 0.1.x that checks for a stuck connection - but it doesn't seem to be needed
143
+ - there is currently no "heartbeat" feature as in 0.1.x that checks for a stuck connection but it doesn't seem to be needed
101
144
 
102
145
  ## [0.1.3] - 2023-07-04
103
146
 
data/README.md CHANGED
@@ -130,14 +130,11 @@ Each message passed to `on_message` is an instance of a subclass of either `Skyf
130
130
  - `CommitMessage` (`#commit`) - represents a change in a user's repo; most messages are of this type
131
131
  - `IdentityMessage` (`#identity`) - notifies about a change in user's DID document, e.g. a handle change or a migration to a new PDS
132
132
  - `AccountMessage` (`#account`) - notifies about a change of an account's status (de/activation, suspension, deletion)
133
- - `HandleMessage` (`#handle` - deprecated) - when a different handle is assigned to a user's DID
134
- - `TombstoneMessage` (`#tombstone` - deprecated) - when an account is deleted
133
+ - `SyncMessage` (`#sync`) - updates repository state, can be used to trigger account resynchronization
135
134
  - `LabelsMessage` (`#labels`) - only used in `subscribe_labels` endpoint
136
135
  - `InfoMessage` (`#info`) - a protocol error message, e.g. about an invalid cursor parameter
137
136
  - `UnknownMessage` is used for other unrecognized message types
138
137
 
139
- `#handle` and `#tombstone` events are considered deprecated, replaced by `#identity` and `#account` respectively. They are still being emitted at the moment (in parallel with the newer event types), but they might stop being sent at any moment, so it's recommended that you don't rely on those.
140
-
141
138
  `Skyfall::Firehose::Message` and `Skyfall::Jetstream::Message` variants of message classes should have more or less the same interface, except when a given field is not included in one of the formats.
142
139
 
143
140
  All message objects have the following shared properties:
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'cid'
2
4
  require_relative 'errors'
3
5
  require_relative 'extensions'
@@ -30,15 +32,34 @@ module Skyfall
30
32
 
31
33
  def initialize(data)
32
34
  @sections = []
35
+ @buffer = StringIO.new(data)
33
36
 
34
- buffer = StringIO.new(data)
35
- read_header(buffer)
36
- read_section(buffer) until buffer.eof?
37
+ read_header(@buffer)
37
38
  end
38
39
 
39
40
  def section_with_cid(cid)
40
- section = @sections.detect { |s| s.cid == cid }
41
- section && section.body
41
+ if section = @sections.detect { |s| s.cid == cid }
42
+ return section.body
43
+ end
44
+
45
+ if @buffer
46
+ while !@buffer.eof?
47
+ section = read_section(@buffer)
48
+ return section.body if section.cid == cid
49
+ end
50
+ end
51
+
52
+ @buffer = nil
53
+ nil
54
+ end
55
+
56
+ def sections
57
+ if @buffer
58
+ read_section(@buffer) while !@buffer.eof?
59
+ @buffer = nil
60
+ end
61
+
62
+ @sections
42
63
  end
43
64
 
44
65
  def self.convert_data(object)
@@ -75,6 +96,18 @@ module Skyfall
75
96
  { '$bytes' => Base64.encode64(data).chomp.gsub(/=+$/, '') }
76
97
  end
77
98
 
99
+ def inspect
100
+ vars = instance_variables.map { |v|
101
+ if v == :@sections && @buffer
102
+ "#{v}=[...]"
103
+ else
104
+ "#{v}=#{instance_variable_get(v).inspect}"
105
+ end
106
+ }
107
+
108
+ "#<#{self.class}:0x#{object_id} #{vars.join(", ")}>"
109
+ end
110
+
78
111
  private
79
112
 
80
113
  def read_header(buffer)
@@ -116,7 +149,10 @@ module Skyfall
116
149
  cid = CID.new(prefix + cid_data)
117
150
 
118
151
  body_data = sbuffer.read
119
- @sections << CarSection.new(cid, body_data)
152
+ new_section = CarSection.new(cid, body_data)
153
+
154
+ @sections << new_section
155
+ new_section
120
156
  end
121
157
  end
122
158
  end
data/lib/skyfall/cid.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'errors'
2
4
 
3
5
  require 'base32'
@@ -1,4 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Skyfall
4
+
5
+ #
6
+ # This module defines constants for known Bluesky record collection types, and a mapping of those
7
+ # names to symbol short codes which can be used as shorthand when processing events or in
8
+ # Jetstream filters.
9
+ #
10
+
2
11
  module Collection
3
12
  BSKY_PROFILE = "app.bsky.actor.profile"
4
13
  BSKY_ACTOR_STATUS = "app.bsky.actor.status"
@@ -20,6 +29,8 @@ module Skyfall
20
29
  BSKY_NOTIF_DECLARATION = "app.bsky.notification.declaration"
21
30
  BSKY_CHAT_DECLARATION = "chat.bsky.actor.declaration"
22
31
 
32
+ # Mapping of NSID collection names to symbol short codes
33
+
23
34
  SHORT_CODES = {
24
35
  BSKY_ACTOR_STATUS => :bsky_actor_status,
25
36
  BSKY_BLOCK => :bsky_block,
@@ -41,10 +52,19 @@ module Skyfall
41
52
  BSKY_NOTIF_DECLARATION => :bsky_notif_declaration
42
53
  }
43
54
 
55
+ # Returns a symbol short code for a given collection NSID, or `:unknown`
56
+ # if NSID is not on the list.
57
+ # @param collection [String] collection NSID
58
+ # @return [Symbol] short code or :unknown
59
+
44
60
  def self.short_code(collection)
45
61
  SHORT_CODES[collection] || :unknown
46
62
  end
47
63
 
64
+ # Returns a collection NSID assigned to a given short code symbol, if one is defined.
65
+ # @param code [Symbol] one of the symbols listed in {SHORT_CODES}
66
+ # @return [String, nil] assigned NSID string, or nil when code is not known
67
+
48
68
  def self.from_short_code(code)
49
69
  SHORT_CODES.detect { |k, v| v == code }&.first
50
70
  end
@@ -1,11 +1,36 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Skyfall
2
- class DecodeError < StandardError
4
+ #
5
+ # Wrapper base class for Skyfall error classes.
6
+ #
7
+ class Error < StandardError
8
+ end
9
+
10
+ #
11
+ # Raised when some code is not configured or configured incorrectly.
12
+ #
13
+ class ConfigError < Error
3
14
  end
4
15
 
5
- class UnsupportedError < StandardError
16
+ #
17
+ # Raised when some part of the message being decoded has invalid format.
18
+ #
19
+ class DecodeError < Error
6
20
  end
7
21
 
8
- class ReactorActiveError < StandardError
22
+ #
23
+ # Raised when {Stream#connect} is called and there's already another instance of {Stream} or its
24
+ # subclass like {Firehose} that's connected to another websocket.
25
+ #
26
+ # This is currently not supported in Skyfall, because it uses EventMachine behind the scenes, which
27
+ # runs everything on a single "reactor" thread, and there can be only one such reactor thread in
28
+ # a given process. In theory, it should be possible for two connections to run inside a single
29
+ # shared EventMachine event loop, but it would require some more coordination and it might have
30
+ # unexpected side effects - e.g. synchronous work (including I/O and network requests) done during
31
+ # processing of an event from one connection would be blocking the other connection.
32
+ #
33
+ class ReactorActiveError < Error
9
34
  def initialize
10
35
  super(
11
36
  "An EventMachine reactor thread is already running, but it seems to have been launched by another Stream. " +
@@ -14,9 +39,22 @@ module Skyfall
14
39
  end
15
40
  end
16
41
 
17
- class SubscriptionError < StandardError
18
- attr_reader :error_type, :error_message
42
+ #
43
+ # Raised when the server sends a message which is formatted correctly, but describes some kind of
44
+ # error condition that the server has detected.
45
+ #
46
+ class SubscriptionError < Error
47
+
48
+ # @return [String] a short machine-readable error code
49
+ attr_reader :error_type
19
50
 
51
+ # @return [String] a human-readable error message
52
+ attr_reader :error_message
53
+
54
+ #
55
+ # @param error_type [String] a short machine-readable error code
56
+ # @param error_message [String, nil] a human-readable error message
57
+ #
20
58
  def initialize(error_type, error_message = nil)
21
59
  @error_type = error_type
22
60
  @error_message = error_message
@@ -24,4 +62,11 @@ module Skyfall
24
62
  super("Subscription error: #{error_type}" + (error_message ? " (#{error_message})" : ""))
25
63
  end
26
64
  end
65
+
66
+ #
67
+ # Raised when the server sends a message which is formatted correctly, but written in a version
68
+ # that's not supported by this library.
69
+ #
70
+ class UnsupportedError < Error
71
+ end
27
72
  end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Skyfall
4
+
5
+ # @private
6
+ module Events
7
+ protected
8
+
9
+ def event_handler(name)
10
+ define_method("on_#{name}") do |&block|
11
+ @handlers[name.to_sym] = block
12
+ end
13
+
14
+ define_method("on_#{name}=") do |block|
15
+ @handlers[name.to_sym] = block
16
+ end
17
+ end
18
+ end
19
+ end
@@ -1,7 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'cbor'
2
4
  require 'stringio'
3
5
 
4
6
  module Skyfall
7
+
8
+ # @private
5
9
  module Extensions
6
10
 
7
11
  refine StringIO do
@@ -1,13 +1,41 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative '../firehose'
4
+ require_relative 'message'
2
5
 
3
6
  module Skyfall
7
+
8
+ #
9
+ # Firehose message sent when the status of an account changes. This can be:
10
+ #
11
+ # - an account being created, sending its initial state (should be active)
12
+ # - an account being deactivated or suspended
13
+ # - an account being restored back to an active state from deactivation/suspension
14
+ # - an account being deleted (the status returning `:deleted`)
15
+ #
16
+
4
17
  class Firehose::AccountMessage < Firehose::Message
5
- def active?
6
- @data_object['active']
18
+
19
+ #
20
+ # @private
21
+ # @param type_object [Hash] first decoded CBOR frame with metadata
22
+ # @param data_object [Hash] second decoded CBOR frame with payload
23
+ # @raise [DecodeError] if the message doesn't include required data
24
+ #
25
+ def initialize(type_object, data_object)
26
+ super
27
+ check_if_not_nil 'seq', 'did', 'time', 'active'
28
+
29
+ @active = @data_object['active']
30
+ @status = @data_object['status']&.to_sym
7
31
  end
8
32
 
9
- def status
10
- @data_object['status']&.to_sym
33
+ # @return [Boolean] true if the account is active, false if it's deactivated/suspended etc.
34
+ def active?
35
+ @active
11
36
  end
37
+
38
+ # @return [Symbol, nil] for inactive accounts, specifies the exact state; nil for active accounts
39
+ attr_reader :status
12
40
  end
13
41
  end
@@ -1,27 +1,67 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative '../car_archive'
2
4
  require_relative '../cid'
3
5
  require_relative '../firehose'
6
+ require_relative 'message'
4
7
  require_relative 'operation'
5
8
 
6
9
  module Skyfall
10
+
11
+ #
12
+ # Firehose message which includes one or more operations on records in the repo (a record was
13
+ # created, updated or deleted). In most cases this is a single record operation.
14
+ #
15
+ # Most of the messages received from the firehose are of this type, and this is the type you
16
+ # will usually be most interested in.
17
+ #
18
+
7
19
  class Firehose::CommitMessage < Firehose::Message
8
- def commit
9
- @commit ||= @data_object['commit'] && CID.from_cbor_tag(@data_object['commit'])
20
+
21
+ #
22
+ # @private
23
+ # @param type_object [Hash] first decoded CBOR frame with metadata
24
+ # @param data_object [Hash] second decoded CBOR frame with payload
25
+ # @raise [DecodeError] if the message doesn't include required data
26
+ #
27
+ def initialize(type_object, data_object)
28
+ super
29
+ check_if_not_nil 'seq', 'repo', 'commit', 'blocks', 'ops', 'time', 'rev'
30
+ end
31
+
32
+ # @return [String] current revision of the repo
33
+ def rev
34
+ @data_object['rev']
35
+ end
36
+
37
+ # @return [String, nil] revision of the previous commit in the repo
38
+ def since
39
+ @data_object['since']
10
40
  end
11
41
 
12
- def prev
13
- STDERR.puts "Warning: `prev` property has been deprecated and will be removed in a future version."
14
- @prev ||= @data_object['prev'] && CID.from_cbor_tag(@data_object['prev'])
42
+ # @return [CID, nil] CID (Content Identifier) of data of the previous commit in the repo
43
+ def prev_data
44
+ @prev_data ||= CID.from_cbor_tag(@data_object['prevData'])
45
+ end
46
+
47
+ # @return [CID] CID (Content Identifier) of the commit
48
+ def commit
49
+ @commit ||= CID.from_cbor_tag(@data_object['commit'])
15
50
  end
16
51
 
52
+ # @return [Skyfall::CarArchive] commit data in the form of a parsed CAR archive
17
53
  def blocks
18
54
  @blocks ||= CarArchive.new(@data_object['blocks'])
19
55
  end
20
56
 
57
+ # @return [Array<Firehose::Operation>] record operations (usually one) included in the commit
21
58
  def operations
22
59
  @operations ||= @data_object['ops'].map { |op| Firehose::Operation.new(self, op) }
23
60
  end
24
61
 
62
+ # Looks up record data assigned to a given operation in the commit's CAR archive.
63
+ # @param op [Firehose::Operation]
64
+ # @return [Hash, nil]
25
65
  def raw_record_for_operation(op)
26
66
  op.cid && blocks.section_with_cid(op.cid)
27
67
  end
@@ -1,9 +1,37 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative '../firehose'
4
+ require_relative 'message'
2
5
 
3
6
  module Skyfall
7
+
8
+ #
9
+ # Firehose message sent when a new DID is created or when the details of someone's DID document
10
+ # are changed (usually either a handle change or a migration to a different PDS). The message
11
+ # may include currently assigned handle, though it's not required that this field is set.
12
+ #
13
+ # Note: the message is originally emitted from the account's PDS and is passed as is by relays,
14
+ # which means you can't fully trust that the handle is actually correctly assigned to the DID
15
+ # and verified by DNS or well-known. To confirm that, use `DID.resolve_handle` from
16
+ # [DIDKit](https://ruby.sdk.blue/didkit/).
17
+ #
18
+
4
19
  class Firehose::IdentityMessage < Firehose::Message
5
- def handle
6
- @data_object['handle']
20
+
21
+ #
22
+ # @private
23
+ # @param type_object [Hash] first decoded CBOR frame with metadata
24
+ # @param data_object [Hash] second decoded CBOR frame with payload
25
+ # @raise [DecodeError] if the message doesn't include required data
26
+ #
27
+ def initialize(type_object, data_object)
28
+ super
29
+ check_if_not_nil 'seq', 'did', 'time'
30
+
31
+ @handle = @data_object['handle']
7
32
  end
33
+
34
+ # @return [String, nil] current handle assigned to the DID
35
+ attr_reader :handle
8
36
  end
9
37
  end
@@ -1,22 +1,56 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative '../firehose'
4
+ require_relative 'message'
2
5
 
3
6
  module Skyfall
7
+
8
+ #
9
+ # An informational firehose message from the websocket service itself, unrelated to any repos.
10
+ #
11
+ # Currently there is only one type of message defined, `"OutdatedCursor"`, which is sent when
12
+ # the client connects with a cursor that is older than the oldest event currently kept in the
13
+ # backfill buffer. This message means that you're likely missing some events that were sent
14
+ # since the last time the client was connected but which were already deleted from the buffer.
15
+ #
16
+ # Note: the {#did}, {#seq} and {#time} properties are always `nil` for `#info` messages.
17
+ #
18
+
4
19
  class Firehose::InfoMessage < Firehose::Message
5
- attr_reader :name, :message
6
20
 
21
+ # @return [String] short machine-readable code of the info message
22
+ attr_reader :name
23
+
24
+ # @return [String, nil] a human-readable description
25
+ attr_reader :message
26
+
27
+ # Message which means that the cursor passed when connecting is older than the oldest event
28
+ # currently kept in the backfill buffer, and that you've likely missed some events that have
29
+ # already been deleted
7
30
  OUTDATED_CURSOR = "OutdatedCursor"
8
31
 
32
+ #
33
+ # @private
34
+ # @param type_object [Hash] first decoded CBOR frame with metadata
35
+ # @param data_object [Hash] second decoded CBOR frame with payload
36
+ # @raise [DecodeError] if the message doesn't include required data
37
+ #
9
38
  def initialize(type_object, data_object)
10
39
  super
40
+ check_if_not_nil 'name'
11
41
 
12
42
  @name = @data_object['name']
13
43
  @message = @data_object['message']
14
44
  end
15
45
 
46
+ # @return [String] a formatted summary
16
47
  def to_s
17
48
  (@name || "InfoMessage") + (@message ? ": #{@message}" : "")
18
49
  end
19
50
 
51
+ protected
52
+
53
+ # @return [Array<Symbol>] list of instance variables to be printed in the {#inspect} output
20
54
  def inspectable_variables
21
55
  super - [:@did, :@seq]
22
56
  end
@@ -1,23 +1,41 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative '../firehose'
2
4
  require_relative '../label'
5
+ require_relative 'message'
3
6
 
4
7
  module Skyfall
5
- class Firehose::LabelsMessage
6
- using Skyfall::Extensions
7
8
 
8
- attr_reader :type_object, :data_object
9
- attr_reader :type, :seq
9
+ #
10
+ # A message which includes one or more labels (as {Skyfall::Label}). This type of message
11
+ # is only sent from a `:subscribe_labels` firehose from a labeller service.
12
+ #
13
+ # Note: the {#did} and {#time} properties are always `nil` for `#labels` messages.
14
+ #
15
+
16
+ class Firehose::LabelsMessage < Firehose::Message
10
17
 
18
+ # @return [Array<Skyfall::Label>] labels included in the batch
19
+ attr_reader :labels
20
+
21
+ #
22
+ # @private
23
+ # @param type_object [Hash] first decoded CBOR frame with metadata
24
+ # @param data_object [Hash] second decoded CBOR frame with payload
25
+ # @raise [DecodeError] if the message doesn't include required data
26
+ #
11
27
  def initialize(type_object, data_object)
12
- @type_object = type_object
13
- @data_object = data_object
28
+ super
29
+ check_if_not_nil 'seq', 'labels'
14
30
 
15
- @type = @type_object['t'][1..-1].to_sym
16
- @seq = @data_object['seq']
31
+ @labels = @data_object['labels'].map { |x| Label.new(x) }
17
32
  end
18
33
 
19
- def labels
20
- @labels ||= @data_object['labels'].map { |x| Label.new(x) }
34
+ protected
35
+
36
+ # @return [Array<Symbol>] list of instance variables to be printed in the {#inspect} output
37
+ def inspectable_variables
38
+ super - [:@did]
21
39
  end
22
40
  end
23
41
  end