skyfall 0.2.5 → 0.3.1

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: 965eb9da488c1af0a4ea4573de3677572f6acdfab64497ce65bf0f3ba11ac015
4
- data.tar.gz: 0fa130b4da079e253de127813e245a5851eaa9c83651e955099b070a65a7396e
3
+ metadata.gz: 1002b9dbaf48b9158f4b37d314e7f72d0990bf8290a5ad5d172af5aec9c48e38
4
+ data.tar.gz: 2a7cf444f30a13135e0848cbf0ad6c1900d9210e0799117e0612d5c52a93b2a4
5
5
  SHA512:
6
- metadata.gz: c0a2f258e2a96d0fb6e9f1206df3dadcad9543bf5898fdc3702e74e097c3f5758b7a6c33d8b3dbfaa437b4718122e2a4c199b70d2e9c12ea5686645cbcd414b7
7
- data.tar.gz: 417f34ff64333390397a91e6cbc9364b858b015a000759a6beccfed3bf81b448b8261c4fdfeed7ae3ebadaa995f380837b6cc543aceec83342884e8ff8e48b11
6
+ metadata.gz: 600eaf8dd34c393b592a6490848d9e981c9ff0fa17fab629d2d640162eecda1248a49944e49d4bb679f732551e75ac209fd09bac85b7a087f81e8b13153c3446
7
+ data.tar.gz: e8d2c63b039aa7918337b67b77e8d0b511aba81b98d21862cf75a8561d42e72e71214fe16b11f884082fdd8b646e917b840b0369911d07afb32aedc42badc38a
data/CHANGELOG.md CHANGED
@@ -1,3 +1,23 @@
1
+ ## [Unreleased]
2
+
3
+ - added heartbeat timer
4
+
5
+ ## [0.3.1] - 2024-06-28
6
+
7
+ - added `app.bsky.graph.starterpack` and `chat.bsky.actor.declaration` record types
8
+ - added `#account` event type (`AccountMessage`)
9
+ - added `handle` field to `IdentityMessage`
10
+ - fixed param validation on `Stream` initialization
11
+ - 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
12
+
13
+ ## [0.3.0] - 2024-03-21
14
+
15
+ - added support for labeller firehose, served by labeller services at the `com.atproto.label.subscribeLabels` endpoint (aliased as `:subscribe_labels`)
16
+ - the `#labels` messages from the labeller firehose are parsed into a `LabelsMessage`, which includes a `labels` array of `Label` objects
17
+ - `Stream` callbacks can now also be assigned via setters, e.g. `stream.on_message = proc { ... }`
18
+ - added default error handler to `Stream` which logs the error to `$stdout` - set `stream.on_error = nil` to disable
19
+ - 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
20
+
1
21
  ## [0.2.5] - 2024-03-14
2
22
 
3
23
  - added `:bsky_labeler` record type symbol & collection constant
data/README.md CHANGED
@@ -1,6 +1,9 @@
1
1
  # Skyfall
2
2
 
3
- 🌤 A Ruby gem for streaming data from the Bluesky/AtProto firehose 🦋
3
+ A Ruby gem for streaming data from the Bluesky/AtProto firehose 🦋
4
+
5
+ > [!NOTE]
6
+ > ATProto Ruby gems collection: [skyfall](https://github.com/mackuba/skyfall) | [blue_factory](https://github.com/mackuba/blue_factory) | [minisky](https://github.com/mackuba/minisky) | [didkit](https://github.com/mackuba/didkit)
4
7
 
5
8
 
6
9
  ## What does it do
@@ -1,16 +1,19 @@
1
1
  module Skyfall
2
2
  module Collection
3
- BSKY_PROFILE = "app.bsky.actor.profile"
4
- BSKY_FEED = "app.bsky.feed.generator"
5
- BSKY_LIKE = "app.bsky.feed.like"
6
- BSKY_POST = "app.bsky.feed.post"
7
- BSKY_REPOST = "app.bsky.feed.repost"
8
- BSKY_THREADGATE = "app.bsky.feed.threadgate"
9
- BSKY_BLOCK = "app.bsky.graph.block"
10
- BSKY_FOLLOW = "app.bsky.graph.follow"
11
- BSKY_LIST = "app.bsky.graph.list"
12
- BSKY_LISTBLOCK = "app.bsky.graph.listblock"
13
- BSKY_LISTITEM = "app.bsky.graph.listitem"
14
- BSKY_LABELER = "app.bsky.labeler.service"
3
+ BSKY_PROFILE = "app.bsky.actor.profile"
4
+ BSKY_FEED = "app.bsky.feed.generator"
5
+ BSKY_LIKE = "app.bsky.feed.like"
6
+ BSKY_POST = "app.bsky.feed.post"
7
+ BSKY_REPOST = "app.bsky.feed.repost"
8
+ BSKY_THREADGATE = "app.bsky.feed.threadgate"
9
+ BSKY_BLOCK = "app.bsky.graph.block"
10
+ BSKY_FOLLOW = "app.bsky.graph.follow"
11
+ BSKY_LIST = "app.bsky.graph.list"
12
+ BSKY_LISTBLOCK = "app.bsky.graph.listblock"
13
+ BSKY_LISTITEM = "app.bsky.graph.listitem"
14
+ BSKY_STARTERPACK = "app.bsky.graph.starterpack"
15
+ BSKY_LABELER = "app.bsky.labeler.service"
16
+
17
+ BSKY_CHAT_DECLARATION = "chat.bsky.actor.declaration"
15
18
  end
16
19
  end
@@ -0,0 +1,63 @@
1
+ require_relative 'errors'
2
+ require 'time'
3
+
4
+ module Skyfall
5
+ class Label
6
+ attr_reader :data
7
+
8
+ def initialize(data)
9
+ @data = data
10
+
11
+ raise DecodeError.new("Missing version: #{data}") unless data.has_key?('ver')
12
+ raise DecodeError.new("Invalid version: #{ver}") unless ver.is_a?(Integer) && ver >= 1
13
+ raise UnsupportedError.new("Unsupported version: #{ver}") unless ver == 1
14
+
15
+ raise DecodeError.new("Missing source: #{data}") unless data.has_key?('src')
16
+ raise DecodeError.new("Invalid source: #{src}") unless src.is_a?(String) && src.start_with?('did:')
17
+
18
+ raise DecodeError.new("Missing uri: #{data}") unless data.has_key?('uri')
19
+ raise DecodeError.new("Invalid uri: #{uri}") unless uri.is_a?(String)
20
+ raise DecodeError.new("Invalid uri: #{uri}") unless uri.start_with?('at://') || uri.start_with?('did:')
21
+ end
22
+
23
+ def version
24
+ @data['ver']
25
+ end
26
+
27
+ def authority
28
+ @data['src']
29
+ end
30
+
31
+ def subject
32
+ @data['uri']
33
+ end
34
+
35
+ def cid
36
+ @cid ||= @data['cid'] && CID.from_json(@data['cid'])
37
+ end
38
+
39
+ def value
40
+ @data['val']
41
+ end
42
+
43
+ def negation?
44
+ !!@data['neg']
45
+ end
46
+
47
+ def created_at
48
+ @created_at ||= Time.parse(@data['cts'])
49
+ end
50
+
51
+ def expires_at
52
+ @expires_at ||= @data['exp'] && Time.parse(@data['exp'])
53
+ end
54
+
55
+ alias ver version
56
+ alias src authority
57
+ alias uri subject
58
+ alias val value
59
+ alias neg negation?
60
+ alias cts created_at
61
+ alias exp expires_at
62
+ end
63
+ end
@@ -0,0 +1,11 @@
1
+ module Skyfall
2
+ class AccountMessage < WebsocketMessage
3
+ def active?
4
+ @data_object['active']
5
+ end
6
+
7
+ def status
8
+ @data_object['status']&.to_sym
9
+ end
10
+ end
11
+ end
@@ -1,4 +1,9 @@
1
1
  module Skyfall
2
+
3
+ #
4
+ # Note: this event type is deprecated and will stop being emitted at some point.
5
+ # You should instead listen for 'identity' events (Skyfall::IdentityMessage).
6
+ #
2
7
  class HandleMessage < WebsocketMessage
3
8
  def handle
4
9
  @data_object['handle']
@@ -1,4 +1,7 @@
1
1
  module Skyfall
2
2
  class IdentityMessage < WebsocketMessage
3
+ def handle
4
+ @data_object['handle']
5
+ end
3
6
  end
4
7
  end
@@ -0,0 +1,23 @@
1
+ require_relative 'websocket_message'
2
+ require_relative '../label'
3
+
4
+ module Skyfall
5
+ class LabelsMessage
6
+ using Skyfall::Extensions
7
+
8
+ attr_reader :type_object, :data_object
9
+ attr_reader :type, :seq
10
+
11
+ def initialize(type_object, data_object)
12
+ @type_object = type_object
13
+ @data_object = data_object
14
+
15
+ @type = @type_object['t'][1..-1].to_sym
16
+ @seq = @data_object['seq']
17
+ end
18
+
19
+ def labels
20
+ @labels ||= @data_object['labels'].map { |x| Label.new(x) }
21
+ end
22
+ end
23
+ end
@@ -1,4 +1,9 @@
1
1
  module Skyfall
2
+
3
+ #
4
+ # Note: this event type is deprecated and will stop being emitted at some point.
5
+ # You should instead listen for 'account' events (Skyfall::AccountMessage).
6
+ #
2
7
  class TombstoneMessage < WebsocketMessage
3
8
  end
4
9
  end
@@ -8,10 +8,12 @@ module Skyfall
8
8
  class WebsocketMessage
9
9
  using Skyfall::Extensions
10
10
 
11
+ require_relative 'account_message'
11
12
  require_relative 'commit_message'
12
13
  require_relative 'handle_message'
13
14
  require_relative 'identity_message'
14
15
  require_relative 'info_message'
16
+ require_relative 'labels_message'
15
17
  require_relative 'tombstone_message'
16
18
  require_relative 'unknown_message'
17
19
 
@@ -24,10 +26,12 @@ module Skyfall
24
26
  type_object, data_object = decode_cbor_objects(data)
25
27
 
26
28
  message_class = case type_object['t']
29
+ when '#account' then AccountMessage
27
30
  when '#commit' then CommitMessage
28
31
  when '#handle' then HandleMessage
29
32
  when '#identity' then IdentityMessage
30
33
  when '#info' then InfoMessage
34
+ when '#labels' then LabelsMessage
31
35
  when '#tombstone' then TombstoneMessage
32
36
  else UnknownMessage
33
37
  end
@@ -43,18 +43,20 @@ module Skyfall
43
43
 
44
44
  def type
45
45
  case collection
46
- when Collection::BSKY_BLOCK then :bsky_block
47
- when Collection::BSKY_FEED then :bsky_feed
48
- when Collection::BSKY_FOLLOW then :bsky_follow
49
- when Collection::BSKY_LABELER then :bsky_labeler
50
- when Collection::BSKY_LIKE then :bsky_like
51
- when Collection::BSKY_LIST then :bsky_list
52
- when Collection::BSKY_LISTBLOCK then :bsky_listblock
53
- when Collection::BSKY_LISTITEM then :bsky_listitem
54
- when Collection::BSKY_POST then :bsky_post
55
- when Collection::BSKY_PROFILE then :bsky_profile
56
- when Collection::BSKY_REPOST then :bsky_repost
57
- when Collection::BSKY_THREADGATE then :bsky_threadgate
46
+ when Collection::BSKY_BLOCK then :bsky_block
47
+ when Collection::BSKY_FEED then :bsky_feed
48
+ when Collection::BSKY_FOLLOW then :bsky_follow
49
+ when Collection::BSKY_LABELER then :bsky_labeler
50
+ when Collection::BSKY_LIKE then :bsky_like
51
+ when Collection::BSKY_LIST then :bsky_list
52
+ when Collection::BSKY_LISTBLOCK then :bsky_listblock
53
+ when Collection::BSKY_LISTITEM then :bsky_listitem
54
+ when Collection::BSKY_POST then :bsky_post
55
+ when Collection::BSKY_PROFILE then :bsky_profile
56
+ when Collection::BSKY_REPOST then :bsky_repost
57
+ when Collection::BSKY_STARTERPACK then :bsky_starterpack
58
+ when Collection::BSKY_THREADGATE then :bsky_threadgate
59
+ when Collection::BSKY_CHAT_DECLARATION then :bsky_chat_declaration
58
60
  else :unknown
59
61
  end
60
62
  end
@@ -7,11 +7,15 @@ require 'uri'
7
7
  module Skyfall
8
8
  class Stream
9
9
  SUBSCRIBE_REPOS = "com.atproto.sync.subscribeRepos"
10
+ SUBSCRIBE_LABELS = "com.atproto.label.subscribeLabels"
10
11
 
11
12
  NAMED_ENDPOINTS = {
12
- :subscribe_repos => SUBSCRIBE_REPOS
13
+ :subscribe_repos => SUBSCRIBE_REPOS,
14
+ :subscribe_labels => SUBSCRIBE_LABELS
13
15
  }
14
16
 
17
+ EVENTS = %w(message raw_message connecting connect disconnect reconnect error)
18
+
15
19
  MAX_RECONNECT_INTERVAL = 300
16
20
 
17
21
  attr_accessor :heartbeat_timeout, :heartbeat_interval, :cursor, :auto_reconnect
@@ -23,6 +27,8 @@ module Skyfall
23
27
  @handlers = {}
24
28
  @auto_reconnect = true
25
29
  @connection_attempts = 0
30
+
31
+ @handlers[:error] = proc { |e| puts "ERROR: #{e}" }
26
32
  end
27
33
 
28
34
  def connect
@@ -104,32 +110,14 @@ module Skyfall
104
110
 
105
111
  alias close disconnect
106
112
 
107
- def on_message(&block)
108
- @handlers[:message] = block
109
- end
110
-
111
- def on_raw_message(&block)
112
- @handlers[:raw_message] = block
113
- end
114
-
115
- def on_connecting(&block)
116
- @handlers[:connecting] = block
117
- end
118
-
119
- def on_connect(&block)
120
- @handlers[:connect] = block
121
- end
122
-
123
- def on_disconnect(&block)
124
- @handlers[:disconnect] = block
125
- end
126
-
127
- def on_error(&block)
128
- @handlers[:error] = block
129
- end
113
+ EVENTS.each do |event|
114
+ define_method "on_#{event}" do |&block|
115
+ @handlers[event.to_sym] = block
116
+ end
130
117
 
131
- def on_reconnect(&block)
132
- @handlers[:reconnect] = block
118
+ define_method "on_#{event}=" do |block|
119
+ @handlers[event.to_sym] = block
120
+ end
133
121
  end
134
122
 
135
123
  def inspectable_variables
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Skyfall
4
- VERSION = "0.2.5"
4
+ VERSION = "0.3.1"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: skyfall
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kuba Suder
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-03-14 00:00:00.000000000 Z
11
+ date: 2024-06-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: base32
@@ -30,6 +30,20 @@ dependencies:
30
30
  - - ">="
31
31
  - !ruby/object:Gem::Version
32
32
  version: 0.3.4
33
+ - !ruby/object:Gem::Dependency
34
+ name: base64
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '0.1'
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '0.1'
33
47
  - !ruby/object:Gem::Dependency
34
48
  name: cbor
35
49
  requirement: !ruby/object:Gem::Requirement
@@ -50,20 +64,40 @@ dependencies:
50
64
  - - ">="
51
65
  - !ruby/object:Gem::Version
52
66
  version: 0.5.9.6
67
+ - !ruby/object:Gem::Dependency
68
+ name: eventmachine
69
+ requirement: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - "~>"
72
+ - !ruby/object:Gem::Version
73
+ version: '1.2'
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: 1.2.7
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: '1.2'
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: 1.2.7
53
87
  - !ruby/object:Gem::Dependency
54
88
  name: faye-websocket
55
89
  requirement: !ruby/object:Gem::Requirement
56
90
  requirements:
57
91
  - - "~>"
58
92
  - !ruby/object:Gem::Version
59
- version: 0.11.2
93
+ version: '0.11'
60
94
  type: :runtime
61
95
  prerelease: false
62
96
  version_requirements: !ruby/object:Gem::Requirement
63
97
  requirements:
64
98
  - - "~>"
65
99
  - !ruby/object:Gem::Version
66
- version: 0.11.2
100
+ version: '0.11'
67
101
  description: "\n Skyfall is a Ruby library for connecting to the \"firehose\" of
68
102
  the Bluesky social network, i.e. a websocket which\n streams all new posts and
69
103
  everything else happening on the Bluesky network in real time. The code connects
@@ -89,10 +123,13 @@ files:
89
123
  - lib/skyfall/collection.rb
90
124
  - lib/skyfall/errors.rb
91
125
  - lib/skyfall/extensions.rb
126
+ - lib/skyfall/label.rb
127
+ - lib/skyfall/messages/account_message.rb
92
128
  - lib/skyfall/messages/commit_message.rb
93
129
  - lib/skyfall/messages/handle_message.rb
94
130
  - lib/skyfall/messages/identity_message.rb
95
131
  - lib/skyfall/messages/info_message.rb
132
+ - lib/skyfall/messages/labels_message.rb
96
133
  - lib/skyfall/messages/tombstone_message.rb
97
134
  - lib/skyfall/messages/unknown_message.rb
98
135
  - lib/skyfall/messages/websocket_message.rb