anycable-core 1.5.1 โ†’ 1.6.0.rc.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: e580fb7244e7eb0d8ad4d749ec3eaec19e5490152c39c1f30f42b53249185536
4
- data.tar.gz: 7da10692cea6e5d1d9ced38075c649077eed8ed5a5c49cdaac446cb7dbe686ff
3
+ metadata.gz: 5a1e141540dbc11a56633dda1ba555de70900a37e3510f2c6404e50cc1375cfc
4
+ data.tar.gz: f51a96aa3b101fbd9a3dbfa66ec51109b3ff81897796a9e9a8d3fa2ba29ef0eb
5
5
  SHA512:
6
- metadata.gz: 196239a321ae0f634b2cbe61b81d83e454b3be116b0748ca80b07405ecc1e333258735b9195f7e6b927c30dc0677101805f0dbad267b15beb96b17ca20823b7a
7
- data.tar.gz: 6430837a566150c68611488d82ccf1e0955953f1ef4ecf32df3b00ace5c255dc5755f051e4ee3fb3ab18d0c286e1e214ec759b6fc4fea6a698e34a51e80ad03c
6
+ metadata.gz: 9d021b6d6036e6d6d425ead93557688cb99d119f36276acae4474abb12b0aa58ada3bd380c48d8d154978449299dd23bb36e629a148be5b5a62831b51049c6ec
7
+ data.tar.gz: 7bd8f7d0abc547f8b61bab521d8ff96f4d58a5e5887982f597c7e71472bd8abb9179611bb28c29e236f5f4a89ac6c6f8f0a91f540b44f13785e4dcc8ccf8032f
data/CHANGELOG.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 1.5.2 (2024-12-27)
6
+
7
+ - Update google-protobuf to version 4 (support Ruby 3.4). ([@le0pard][])
8
+
5
9
  ## 1.5.1 (2024-06-14) ๐Ÿ‡ช๐Ÿ‡บ โšฝ๏ธ
6
10
 
7
11
  - Fixed compatibility with Rack 3.1 ([@earlopain][])
@@ -209,10 +213,11 @@ See [#71](https://github.com/anycable/anycable/pull/71).
209
213
 
210
214
  ---
211
215
 
212
- See [Changelog](https://github.com/anycable/anycable/blob/0-6-stable/CHANGELOG.md) for versions <1.0.0.
216
+ See [Changelog](https://github.com/anycable/anycable-rb/blob/0-6-stable/CHANGELOG.md) for versions <1.0.0.
213
217
 
214
218
  [@palkan]: https://github.com/palkan
215
219
  [@smasry]: https://github.com/smasry
216
220
  [@Envek]: https://github.com/Envek
217
221
  [@cylon-v]: https://github.com/cylon-v
218
222
  [@earlopain]: https://github.com/earlopain
223
+ [@le0pard]: https://github.com/le0pard
data/README.md CHANGED
@@ -1,77 +1,29 @@
1
1
  [![Gem Version](https://badge.fury.io/rb/anycable.svg)](https://rubygems.org/gems/anycable)
2
- [![Build](https://github.com/anycable/anycable/workflows/Build/badge.svg)](https://github.com/anycable/anycable/actions)
3
- [![Coverage Status](https://coveralls.io/repos/github/anycable/anycable/badge.svg?branch=master)](https://coveralls.io/github/anycable/anycable?branch=master)
4
- [![Documentation](https://img.shields.io/badge/docs-link-brightgreen.svg)](https://docs.anycable.io/v1)
2
+ [![Build](https://github.com/anycable/anycable-rb/workflows/Build/badge.svg)](https://github.com/anycable/anycable-rb/actions)
3
+ [![Documentation](https://img.shields.io/badge/docs-link-brightgreen.svg)](https://docs.anycable.io)
5
4
 
6
- # AnyCable
5
+ # AnyCable Ruby SDK
7
6
 
8
7
  <img align="right" height="150" width="129"
9
8
  title="AnyCable logo" src="https://docs.anycable.io/assets/images/logo.svg">
10
9
 
11
- AnyCable allows you to use any WebSocket server (written in any language) as a replacement for your Ruby server (such as Faye, Action Cable, etc).
10
+ [AnyCable](https://anycable.io) is an open-source language-agnostic realtime server for reliable two-way communication. This repository contains the Ruby SDK for AnyCable including RPC server implementations, broadcasting adapters and other utilities that could help you to integrate AnyCable into any Ruby application. For Rails integration, check out a dedicated gem: [anycable-rails](https://github.com/anycable/anycable-rails).
12
11
 
13
- AnyCable uses the same protocol as ActionCable, so you can use its [JavaScript client](https://www.npmjs.com/package/actioncable) without any monkey-patching.
14
-
15
- > [AnyCable Pro](https://docs.anycable.io/pro) has been launched ๐Ÿš€
16
-
17
- <a href="https://evilmartians.com/">
18
- <img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg" alt="Sponsored by Evil Martians" width="236" height="54"></a>
12
+ ๐ŸŒ [Website](https://anycable.io) ยท ๐Ÿ“š [Documentation](https://docs.anycable.io/ruby/non_rails)
19
13
 
20
14
  ## Requirements
21
15
 
22
- - Ruby >= 2.7
23
- - Redis or NATS (for broadcasting **in production**, [discuss other options](https://github.com/anycable/anycable/issues/2) with us!)
24
-
25
- ## Usage
16
+ - Ruby 3.0+.
26
17
 
27
- Check out our ๐Ÿ“‘ [Documentation](https://docs.anycable.io/v1).
28
-
29
- ## Links
18
+ ## Resources
30
19
 
31
20
  - [AnyCable off Rails: connecting Twilio streams with Hanami](https://evilmartians.com/chronicles/anycable-goes-off-rails-connecting-twilio-streams-with-hanami)
32
21
 
33
- - [AnyCable 1.0: Four years of real-time web with Ruby and Go](https://evilmartians.com/chronicles/anycable-1-0-four-years-of-real-time-web-with-ruby-and-go)
34
-
35
- - [AnyCable: Action Cable on steroids!](https://evilmartians.com/chronicles/anycable-actioncable-on-steroids)
36
-
37
- - [Connecting LiteCable to Hanami](http://gabrielmalakias.com.br/ruby/hanami/iot/2017/05/26/websockets-connecting-litecable-to-hanami.html) by [@GabrielMalakias](https://github.com/GabrielMalakias)
38
-
39
- - [From Action to Any](https://medium.com/@leshchuk/from-action-to-any-1e8d863dd4cf) by [@alekseyl](https://github.com/alekseyl)
40
-
41
- ## Talks
42
-
43
- - High-speed cables for Ruby, RubyConf 2018, [slides](https://speakerdeck.com/palkan/rubyconf-2018-high-speed-cables-for-ruby) and [video](https://www.youtube.com/watch?v=8XRcOZXOzV4) (EN)
44
-
45
- - One cable to rule them all, RubyKaigi 2018, [slides](https://speakerdeck.com/palkan/rubykaigi-2018-anycable-one-cable-to-rule-them-all) and [video](https://www.youtube.com/watch?v=jXCPuNICT8s) (EN)
46
-
47
- - Wroc_Love.rb 2018 [slides](https://speakerdeck.com/palkan/wroc-love-dot-rb-2018-cables-cables-cables) and [video](https://www.youtube.com/watch?v=AUxFFOehiy0) (EN)
48
-
49
- - RubyConfMY 2017 [slides](https://speakerdeck.com/palkan/rubyconf-malaysia-2017-anycable) and [video](https://www.youtube.com/watch?v=j5oFx525zNw) (EN)
50
-
51
- - RailsClub Moscow 2016 [slides](https://speakerdeck.com/palkan/railsclub-moscow-2016-anycable) and [video](https://www.youtube.com/watch?v=-k7GQKuBevY&list=PLiWUIs1hSNeOXZhotgDX7Y7qBsr24cu7o&index=4) (RU)
52
-
53
- ## Building
54
-
55
- ### Generating gRPC files from `.proto`
56
-
57
- - Install required GRPC gems:
58
-
59
- ```sh
60
- gem install grpc
61
- gem install grpc-tools
62
- ```
63
-
64
- - Re-generate GRPC files (if necessary):
65
-
66
- ```sh
67
- make
68
- ```
69
-
70
22
  ## Contributing
71
23
 
72
- Bug reports and pull requests are welcome on GitHub at [https://github.com/anycable/anycable](https://github.com/anycable/anycable).
24
+ Bug reports and pull requests are welcome on GitHub at [https://github.com/anycable/anycable-rb](https://github.com/anycable/anycable-rb).
73
25
 
74
- Please, provide reproduction script (using [this template](https://github.com/anycable/anycable/blob/master/etc/bug_report_template.rb)) when submitting bugs if possible.
26
+ Please, provide reproduction script (using [this template](https://github.com/anycable/anycable-rb/blob/master/etc/bug_report_template.rb)) when submitting bugs if possible.
75
27
 
76
28
  ## License
77
29
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Generated by the protocol buffer compiler. DO NOT EDIT!
4
- # Source: rpc.proto for package 'anycable'
4
+ # Source: rpc.proto for package 'AnyCable'
5
5
 
6
6
  require "grpc"
7
7
 
@@ -5,19 +5,10 @@
5
5
 
6
6
  require 'google/protobuf'
7
7
 
8
- Google::Protobuf::DescriptorPool.generated_pool.build do
9
- add_message "grpc.health.v1.HealthCheckRequest" do
10
- optional :service, :string, 1
11
- end
12
- add_message "grpc.health.v1.HealthCheckResponse" do
13
- optional :status, :enum, 1, "grpc.health.v1.HealthCheckResponse.ServingStatus"
14
- end
15
- add_enum "grpc.health.v1.HealthCheckResponse.ServingStatus" do
16
- value :UNKNOWN, 0
17
- value :SERVING, 1
18
- value :NOT_SERVING, 2
19
- end
20
- end
8
+ descriptor_data = "\n\x1bgrpc/health/v1/health.proto\x12\x0egrpc.health.v1\"%\n\x12HealthCheckRequest\x12\x0f\n\x07service\x18\x01 \x01(\t\"\xa9\x01\n\x13HealthCheckResponse\x12\x41\n\x06status\x18\x01 \x01(\x0e\x32\x31.grpc.health.v1.HealthCheckResponse.ServingStatus\"O\n\rServingStatus\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x0b\n\x07SERVING\x10\x01\x12\x0f\n\x0bNOT_SERVING\x10\x02\x12\x13\n\x0fSERVICE_UNKNOWN\x10\x03\x32\xae\x01\n\x06Health\x12P\n\x05\x43heck\x12\".grpc.health.v1.HealthCheckRequest\x1a#.grpc.health.v1.HealthCheckResponse\x12R\n\x05Watch\x12\".grpc.health.v1.HealthCheckRequest\x1a#.grpc.health.v1.HealthCheckResponse0\x01\x42\x61\n\x11io.grpc.health.v1B\x0bHealthProtoP\x01Z,google.golang.org/grpc/health/grpc_health_v1\xaa\x02\x0eGrpc.Health.V1b\x06proto3"
9
+
10
+ pool = Google::Protobuf::DescriptorPool.generated_pool
11
+ pool.add_serialized_file(descriptor_data)
21
12
 
22
13
  module Grpc
23
14
  module Health
@@ -46,6 +46,7 @@ module AnyCable
46
46
 
47
47
  @tls_credentials = options.delete(:tls_credentials)
48
48
  @grpc_server = build_server(**options)
49
+ @sock = nil
49
50
  end
50
51
 
51
52
  # Start gRPC server in background and
@@ -63,6 +64,8 @@ module AnyCable
63
64
 
64
65
  @start_thread = Thread.new do
65
66
  loop do
67
+ break unless @sock
68
+
66
69
  conn = @sock.accept
67
70
  server.run(conn)
68
71
  rescue IOError
@@ -118,6 +121,8 @@ module AnyCable
118
121
  grpc_server.graceful_shutdown
119
122
  sock.close
120
123
 
124
+ @sock = nil
125
+
121
126
  logger.info "RPC server stopped"
122
127
  end
123
128
 
data/lib/anycable/jwt.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "base64"
3
4
  require "json"
4
5
  require "openssl"
5
6
 
@@ -5,65 +5,15 @@
5
5
 
6
6
  require "google/protobuf"
7
7
 
8
- Google::Protobuf::DescriptorPool.generated_pool.build do
9
- add_file("rpc.proto", syntax: :proto3) do
10
- add_message "anycable.Env" do
11
- optional :url, :string, 1
12
- map :headers, :string, :string, 2
13
- map :cstate, :string, :string, 3
14
- map :istate, :string, :string, 4
15
- end
16
- add_message "anycable.EnvResponse" do
17
- map :cstate, :string, :string, 1
18
- map :istate, :string, :string, 2
19
- end
20
- add_message "anycable.ConnectionRequest" do
21
- optional :env, :message, 3, "anycable.Env"
22
- end
23
- add_message "anycable.ConnectionResponse" do
24
- optional :status, :enum, 1, "anycable.Status"
25
- optional :identifiers, :string, 2
26
- repeated :transmissions, :string, 3
27
- optional :error_msg, :string, 4
28
- optional :env, :message, 5, "anycable.EnvResponse"
29
- end
30
- add_message "anycable.CommandMessage" do
31
- optional :command, :string, 1
32
- optional :identifier, :string, 2
33
- optional :connection_identifiers, :string, 3
34
- optional :data, :string, 4
35
- optional :env, :message, 5, "anycable.Env"
36
- end
37
- add_message "anycable.CommandResponse" do
38
- optional :status, :enum, 1, "anycable.Status"
39
- optional :disconnect, :bool, 2
40
- optional :stop_streams, :bool, 3
41
- repeated :streams, :string, 4
42
- repeated :transmissions, :string, 5
43
- optional :error_msg, :string, 6
44
- optional :env, :message, 7, "anycable.EnvResponse"
45
- repeated :stopped_streams, :string, 8
46
- end
47
- add_message "anycable.DisconnectRequest" do
48
- optional :identifiers, :string, 1
49
- repeated :subscriptions, :string, 2
50
- optional :env, :message, 5, "anycable.Env"
51
- end
52
- add_message "anycable.DisconnectResponse" do
53
- optional :status, :enum, 1, "anycable.Status"
54
- optional :error_msg, :string, 2
55
- end
56
- add_enum "anycable.Status" do
57
- value :ERROR, 0
58
- value :SUCCESS, 1
59
- value :FAILURE, 2
60
- end
61
- end
62
- end
8
+ descriptor_data = "\n\trpc.proto\x12\x08\x61nycable\"\xa3\x02\n\x03\x45nv\x12\x0b\n\x03url\x18\x01 \x01(\t\x12+\n\x07headers\x18\x02 \x03(\x0b\x32\x1a.anycable.Env.HeadersEntry\x12)\n\x06\x63state\x18\x03 \x03(\x0b\x32\x19.anycable.Env.CstateEntry\x12)\n\x06istate\x18\x04 \x03(\x0b\x32\x19.anycable.Env.IstateEntry\x1a.\n\x0cHeadersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a-\n\x0b\x43stateEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a-\n\x0bIstateEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xd1\x01\n\x0b\x45nvResponse\x12\x31\n\x06\x63state\x18\x01 \x03(\x0b\x32!.anycable.EnvResponse.CstateEntry\x12\x31\n\x06istate\x18\x02 \x03(\x0b\x32!.anycable.EnvResponse.IstateEntry\x1a-\n\x0b\x43stateEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a-\n\x0bIstateEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"G\n\x10PresenceResponse\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\n\n\x02id\x18\x02 \x01(\t\x12\x0c\n\x04info\x18\x03 \x01(\t\x12\x0b\n\x03ttl\x18\x04 \x01(\r\"/\n\x11\x43onnectionRequest\x12\x1a\n\x03\x65nv\x18\x03 \x01(\x0b\x32\r.anycable.Env\"\x99\x01\n\x12\x43onnectionResponse\x12 \n\x06status\x18\x01 \x01(\x0e\x32\x10.anycable.Status\x12\x13\n\x0bidentifiers\x18\x02 \x01(\t\x12\x15\n\rtransmissions\x18\x03 \x03(\t\x12\x11\n\terror_msg\x18\x04 \x01(\t\x12\"\n\x03\x65nv\x18\x05 \x01(\x0b\x32\x15.anycable.EnvResponse\"\x7f\n\x0e\x43ommandMessage\x12\x0f\n\x07\x63ommand\x18\x01 \x01(\t\x12\x12\n\nidentifier\x18\x02 \x01(\t\x12\x1e\n\x16\x63onnection_identifiers\x18\x03 \x01(\t\x12\x0c\n\x04\x64\x61ta\x18\x04 \x01(\t\x12\x1a\n\x03\x65nv\x18\x05 \x01(\x0b\x32\r.anycable.Env\"\x83\x02\n\x0f\x43ommandResponse\x12 \n\x06status\x18\x01 \x01(\x0e\x32\x10.anycable.Status\x12\x12\n\ndisconnect\x18\x02 \x01(\x08\x12\x14\n\x0cstop_streams\x18\x03 \x01(\x08\x12\x0f\n\x07streams\x18\x04 \x03(\t\x12\x15\n\rtransmissions\x18\x05 \x03(\t\x12\x11\n\terror_msg\x18\x06 \x01(\t\x12\"\n\x03\x65nv\x18\x07 \x01(\x0b\x32\x15.anycable.EnvResponse\x12\x17\n\x0fstopped_streams\x18\x08 \x03(\t\x12,\n\x08presence\x18\t \x01(\x0b\x32\x1a.anycable.PresenceResponse\"[\n\x11\x44isconnectRequest\x12\x13\n\x0bidentifiers\x18\x01 \x01(\t\x12\x15\n\rsubscriptions\x18\x02 \x03(\t\x12\x1a\n\x03\x65nv\x18\x05 \x01(\x0b\x32\r.anycable.Env\"I\n\x12\x44isconnectResponse\x12 \n\x06status\x18\x01 \x01(\x0e\x32\x10.anycable.Status\x12\x11\n\terror_msg\x18\x02 \x01(\t*-\n\x06Status\x12\t\n\x05\x45RROR\x10\x00\x12\x0b\n\x07SUCCESS\x10\x01\x12\x0b\n\x07\x46\x41ILURE\x10\x02\x32\xda\x01\n\x03RPC\x12\x46\n\x07\x43onnect\x12\x1b.anycable.ConnectionRequest\x1a\x1c.anycable.ConnectionResponse\"\x00\x12@\n\x07\x43ommand\x12\x18.anycable.CommandMessage\x1a\x19.anycable.CommandResponse\"\x00\x12I\n\nDisconnect\x12\x1b.anycable.DisconnectRequest\x1a\x1c.anycable.DisconnectResponse\"\x00\x42\x0b\xea\x02\x08\x41nyCableb\x06proto3"
9
+
10
+ pool = Google::Protobuf::DescriptorPool.generated_pool
11
+ pool.add_serialized_file(descriptor_data)
63
12
 
64
13
  module AnyCable
65
14
  Env = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("anycable.Env").msgclass
66
15
  EnvResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("anycable.EnvResponse").msgclass
16
+ PresenceResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("anycable.PresenceResponse").msgclass
67
17
  ConnectionRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("anycable.ConnectionRequest").msgclass
68
18
  ConnectionResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("anycable.ConnectionResponse").msgclass
69
19
  CommandMessage = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("anycable.CommandMessage").msgclass
@@ -42,6 +42,19 @@ module AnyCable
42
42
  )
43
43
  end
44
44
 
45
+ def build_presence_response(socket)
46
+ return unless socket.presence
47
+
48
+ info = socket.presence[:info]
49
+ info = info.to_json if info && !info.is_a?(String)
50
+
51
+ AnyCable::PresenceResponse.new(
52
+ type: socket.presence.fetch(:type),
53
+ id: socket.presence.fetch(:id),
54
+ info: info
55
+ )
56
+ end
57
+
45
58
  def logger
46
59
  AnyCable.logger
47
60
  end
@@ -27,7 +27,8 @@ module AnyCable
27
27
  streams: socket.streams[:start],
28
28
  stopped_streams: socket.streams[:stop],
29
29
  transmissions: socket.transmissions,
30
- env: build_env_response(socket)
30
+ env: build_env_response(socket),
31
+ presence: build_presence_response(socket)
31
32
  )
32
33
  end
33
34
  end
@@ -1,7 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "stringio"
4
+
3
5
  module AnyCable
4
6
  WHISPER_KEY = "$w"
7
+ PRESENCE_KEY = "$p"
5
8
 
6
9
  # Socket mock to be used with application connection
7
10
  class Socket
@@ -44,7 +47,7 @@ module AnyCable
44
47
  end
45
48
  end
46
49
 
47
- attr_reader :transmissions
50
+ attr_reader :transmissions, :presence
48
51
 
49
52
  def initialize(env:)
50
53
  @transmissions = []
@@ -56,11 +59,11 @@ module AnyCable
56
59
  end
57
60
 
58
61
  def subscribe(_channel, broadcasting)
59
- streams[:start] << broadcasting
62
+ streams[:start] << broadcasting unless streams[:start].include?(broadcasting)
60
63
  end
61
64
 
62
65
  def unsubscribe(_channel, broadcasting)
63
- streams[:stop] << broadcasting
66
+ streams[:stop] << broadcasting unless streams[:stop].include?(broadcasting)
64
67
 
65
68
  if istate.read(WHISPER_KEY) == broadcasting
66
69
  istate.write(WHISPER_KEY, "")
@@ -71,6 +74,21 @@ module AnyCable
71
74
  istate.write(WHISPER_KEY, broadcasting)
72
75
  end
73
76
 
77
+ def presence_join(broadcasting, id, info)
78
+ raise ArgumentError, "ID is required for presence tracking" unless id
79
+
80
+ subscribe("", broadcasting)
81
+ istate.write(PRESENCE_KEY, broadcasting)
82
+
83
+ @presence = {type: "join", id: id, info: info}.compact
84
+ end
85
+
86
+ def presence_leave(id)
87
+ raise ArgumentError, "ID is required for presence tracking" unless id
88
+
89
+ @presence = {type: "leave", id: id}
90
+ end
91
+
74
92
  def unsubscribe_from_all(_channel)
75
93
  @stop_all_streams = true
76
94
  if istate.read(WHISPER_KEY)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AnyCable
4
- VERSION = "1.5.1"
4
+ VERSION = "1.6.0.rc.1"
5
5
  end
@@ -4,8 +4,8 @@ module AnyCable
4
4
  def running?: () -> bool
5
5
  end
6
6
 
7
- SUCCESS_RESPONSE: Array[Integer | String]
8
- FAILURE_RESPONSE: Array[Integer | String]
7
+ SUCCESS_RESPONSE: [Integer, String]
8
+ FAILURE_RESPONSE: [Integer, String]
9
9
 
10
10
  attr_reader server: _Runnable
11
11
  attr_reader port: Integer
@@ -3,6 +3,7 @@ module AnyCable
3
3
  interface _Handler
4
4
  def build_socket: (env: Env) -> Socket
5
5
  def build_env_response: (Socket socket) -> EnvResponse
6
+ def build_presence_response: (Socket socket) -> PresenceResponse?
6
7
  def logger: () -> Logger
7
8
  def factory: () -> _ConnectionFactory
8
9
  end
data/sig/anycable/rpc.rbs CHANGED
@@ -41,6 +41,16 @@ module AnyCable
41
41
  def initialize: (?cstate: protoMap?, ?istate: protoMap?) -> void
42
42
  end
43
43
 
44
+ type presenceEvent = "join" | "leave" | "update"
45
+
46
+ class PresenceResponse
47
+ attr_accessor type: presenceEvent
48
+ attr_accessor id: String
49
+ attr_accessor info: String?
50
+
51
+ def initialize: (?type: presenceEvent, ?id: String, ?info: String) -> void
52
+ end
53
+
44
54
  interface _ProtoMessage
45
55
  def initialize: (**untyped) -> void
46
56
  end
@@ -130,6 +140,7 @@ module AnyCable
130
140
  attr_accessor error_msg: String?
131
141
  attr_accessor env: EnvResponse
132
142
  attr_accessor stopped_streams: Array[String]
143
+ attr_accessor presence: PresenceResponse
133
144
 
134
145
  %a{rbs:test:skip} def initialize: (
135
146
  status: rpcStatus,
@@ -139,7 +150,8 @@ module AnyCable
139
150
  ?stopped_streams: Array[String],
140
151
  ?transmissions: Array[String],
141
152
  ?error_msg: String,
142
- ?env: EnvResponse
153
+ ?env: EnvResponse?,
154
+ ?presence: PresenceResponse?
143
155
  ) -> void
144
156
 
145
157
  def to_h: () -> Hash[Symbol, untyped]
@@ -15,6 +15,7 @@ module AnyCable
15
15
 
16
16
  attr_reader transmissions: Array[String]
17
17
  attr_reader request_env: Env
18
+ attr_reader presence: Hash[Symbol, untyped]?
18
19
 
19
20
  def initialize: (env: Env) -> void
20
21
  def transmit: (String) -> void
@@ -30,6 +31,9 @@ module AnyCable
30
31
  def env: () -> Hash[String, untyped]
31
32
  def cstate: () -> State
32
33
  def istate: () -> State
34
+ def whisper: (String, String) -> void
35
+ def presence_join: (String, String, String | Hash[untyped, untyped]) -> void
36
+ def presence_leave: (String) -> void
33
37
 
34
38
  private
35
39
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: anycable-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.1
4
+ version: 1.6.0.rc.1
5
5
  platform: ruby
6
6
  authors:
7
- - palkan
7
+ - Vladimir Dementyev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-06-14 00:00:00.000000000 Z
11
+ date: 2025-01-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: anyway_config
@@ -24,20 +24,48 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '2.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: base64
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0.2'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0.2'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: google-protobuf
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
45
  - - "~>"
32
46
  - !ruby/object:Gem::Version
33
- version: '3.25'
47
+ version: '4'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '4'
55
+ - !ruby/object:Gem::Dependency
56
+ name: stringio
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3'
34
62
  type: :runtime
35
63
  prerelease: false
36
64
  version_requirements: !ruby/object:Gem::Requirement
37
65
  requirements:
38
66
  - - "~>"
39
67
  - !ruby/object:Gem::Version
40
- version: '3.25'
68
+ version: '3'
41
69
  - !ruby/object:Gem::Dependency
42
70
  name: redis
43
71
  requirement: !ruby/object:Gem::Requirement
@@ -108,6 +136,20 @@ dependencies:
108
136
  - - "~>"
109
137
  - !ruby/object:Gem::Version
110
138
  version: '3.0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: pry
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
111
153
  - !ruby/object:Gem::Dependency
112
154
  name: rspec
113
155
  requirement: !ruby/object:Gem::Requirement
@@ -170,16 +212,16 @@ dependencies:
170
212
  requirements:
171
213
  - - ">="
172
214
  - !ruby/object:Gem::Version
173
- version: '0'
215
+ version: 1.9.1
174
216
  type: :development
175
217
  prerelease: false
176
218
  version_requirements: !ruby/object:Gem::Requirement
177
219
  requirements:
178
220
  - - ">="
179
221
  - !ruby/object:Gem::Version
180
- version: '0'
181
- description: AnyCable core RPC implementation not depenending on a particular server
182
- type (e.g., gRPC or whatever)
222
+ version: 1.9.1
223
+ description: Ruby SDK for AnyCable, an open-source realtime server for reliable two-way
224
+ communication
183
225
  email:
184
226
  - dementiev.vm@gmail.com
185
227
  executables:
@@ -267,15 +309,15 @@ files:
267
309
  - sig/anycable/streams.rbs
268
310
  - sig/anycable/version.rbs
269
311
  - sig/manifest.yml
270
- homepage: http://github.com/anycable/anycable
312
+ homepage: http://github.com/anycable/anycable-rb
271
313
  licenses:
272
314
  - MIT
273
315
  metadata:
274
- bug_tracker_uri: http://github.com/anycable/anycable/issues
275
- changelog_uri: https://github.com/anycable/anycable/blob/master/CHANGELOG.md
316
+ bug_tracker_uri: http://github.com/anycable/anycable-rb/issues
317
+ changelog_uri: https://github.com/anycable/anycable-rb/blob/master/CHANGELOG.md
276
318
  documentation_uri: https://docs.anycable.io/
277
319
  homepage_uri: https://anycable.io/
278
- source_code_uri: http://github.com/anycable/anycable
320
+ source_code_uri: http://github.com/anycable/anycable-rb
279
321
  funding_uri: https://github.com/sponsors/anycable
280
322
  post_install_message:
281
323
  rdoc_options: []
@@ -285,15 +327,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
285
327
  requirements:
286
328
  - - ">="
287
329
  - !ruby/object:Gem::Version
288
- version: 2.7.0
330
+ version: '2.7'
289
331
  required_rubygems_version: !ruby/object:Gem::Requirement
290
332
  requirements:
291
- - - ">="
333
+ - - ">"
292
334
  - !ruby/object:Gem::Version
293
- version: '0'
335
+ version: 1.3.1
294
336
  requirements: []
295
337
  rubygems_version: 3.4.19
296
338
  signing_key:
297
339
  specification_version: 4
298
- summary: AnyCable core RPC implementation
340
+ summary: Ruby SDK for AnyCable, an open-source realtime server for reliable two-way
341
+ communication
299
342
  test_files: []