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 +4 -4
- data/CHANGELOG.md +53 -10
- data/README.md +1 -4
- data/lib/skyfall/car_archive.rb +42 -6
- data/lib/skyfall/cid.rb +2 -0
- data/lib/skyfall/collection.rb +20 -0
- data/lib/skyfall/errors.rb +50 -5
- data/lib/skyfall/events.rb +19 -0
- data/lib/skyfall/extensions.rb +4 -0
- data/lib/skyfall/firehose/account_message.rb +32 -4
- data/lib/skyfall/firehose/commit_message.rb +45 -5
- data/lib/skyfall/firehose/identity_message.rb +30 -2
- data/lib/skyfall/firehose/info_message.rb +35 -1
- data/lib/skyfall/firehose/labels_message.rb +28 -10
- data/lib/skyfall/firehose/message.rb +133 -24
- data/lib/skyfall/firehose/operation.rb +57 -5
- data/lib/skyfall/firehose/sync_message.rb +31 -0
- data/lib/skyfall/firehose/unknown_message.rb +8 -0
- data/lib/skyfall/firehose.rb +103 -5
- data/lib/skyfall/jetstream/account_message.rb +21 -1
- data/lib/skyfall/jetstream/commit_message.rb +35 -2
- data/lib/skyfall/jetstream/identity_message.rb +22 -1
- data/lib/skyfall/jetstream/message.rb +94 -7
- data/lib/skyfall/jetstream/operation.rb +56 -4
- data/lib/skyfall/jetstream/unknown_message.rb +8 -0
- data/lib/skyfall/jetstream.rb +94 -7
- data/lib/skyfall/label.rb +33 -0
- data/lib/skyfall/stream.rb +264 -47
- data/lib/skyfall/version.rb +1 -1
- metadata +2 -3
- data/lib/skyfall/firehose/handle_message.rb +0 -14
- data/lib/skyfall/firehose/tombstone_message.rb +0 -11
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a3e987d12df25109508c0f673894e9a334a81d60d02f57c118e699de5e68dc4d
|
|
4
|
+
data.tar.gz: 152dfdced7c5fc6414f8cbf04d7cff6d184c592a0ed42463f0b156b373c8c8ac
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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`)
|
|
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`
|
|
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
|
|
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
|
|
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`
|
|
59
|
-
- added Ruby stdlib dependencies explicitly to the gemspec
|
|
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
|
|
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)
|
|
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
|
|
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
|
|
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
|
-
- `
|
|
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:
|
data/lib/skyfall/car_archive.rb
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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
|
-
|
|
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
data/lib/skyfall/collection.rb
CHANGED
|
@@ -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
|
data/lib/skyfall/errors.rb
CHANGED
|
@@ -1,11 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Skyfall
|
|
2
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
18
|
-
|
|
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
|
data/lib/skyfall/extensions.rb
CHANGED
|
@@ -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
|
-
|
|
6
|
-
|
|
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
|
-
|
|
10
|
-
|
|
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
|
-
|
|
9
|
-
|
|
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
|
-
|
|
13
|
-
|
|
14
|
-
@
|
|
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
|
-
|
|
6
|
-
|
|
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
|
-
|
|
9
|
-
|
|
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
|
-
|
|
13
|
-
|
|
28
|
+
super
|
|
29
|
+
check_if_not_nil 'seq', 'labels'
|
|
14
30
|
|
|
15
|
-
@
|
|
16
|
-
@seq = @data_object['seq']
|
|
31
|
+
@labels = @data_object['labels'].map { |x| Label.new(x) }
|
|
17
32
|
end
|
|
18
33
|
|
|
19
|
-
|
|
20
|
-
|
|
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
|