ration 0.2.1 → 0.2.2
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/lib/ration/backends/memory.rb +3 -4
- data/lib/ration/backends/postgres.rb +11 -11
- data/lib/ration/backends/redis.rb +12 -12
- data/lib/ration/subscription.rb +2 -3
- data/lib/ration/version.rb +1 -1
- data/lib/ration.rb +5 -8
- data/sig/external.rbs +19 -0
- data/sig/ration/backends/base.rbs +19 -0
- data/sig/ration/backends/memory.rbs +16 -0
- data/sig/ration/backends/postgres.rbs +42 -0
- data/sig/ration/backends/redis.rbs +44 -0
- data/sig/ration/configuration.rbs +8 -0
- data/sig/ration/errors.rbs +10 -0
- data/sig/ration/hub.rbs +22 -0
- data/sig/ration/rails.rbs +22 -0
- data/sig/ration/sse.rbs +27 -0
- data/sig/ration/subscription.rbs +26 -0
- data/sig/ration/version.rbs +3 -0
- data/sig/ration.rbs +19 -0
- metadata +14 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 06d085f3d4d3bd600254eb694a8e3052e231166adfa65c4af78b0447c7f1bd7e
|
|
4
|
+
data.tar.gz: bb65889b2ba23c9817f30a46de4e1eef18342684e05d6c404ffd6e26fb2ff9d1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a6607e53d4fcc195b113dc6a31f30789ced563d9ebfba9958b5a685c9a239eb1c2ed9a7dcf196c4c21b2f41169ac3cb109bf9b48e84a079883d8caf8f9500916
|
|
7
|
+
data.tar.gz: 619058a038310db757089ddb2c54373f1d4fa8d3dfbb3ad75e48422bf329f85c6984f1b8180afc2cbf85aaec876e5f697a5b47c4f4d513dee3ed979785e05fd9
|
|
@@ -9,7 +9,7 @@ module Ration
|
|
|
9
9
|
@max_payload_bytes = max_payload_bytes
|
|
10
10
|
@sync = sync
|
|
11
11
|
@logger = logger || Logger.new($stderr)
|
|
12
|
-
@queue =
|
|
12
|
+
@queue = Queue.new
|
|
13
13
|
@thread = nil
|
|
14
14
|
end
|
|
15
15
|
|
|
@@ -27,7 +27,6 @@ module Ration
|
|
|
27
27
|
return if @sync
|
|
28
28
|
return if @thread
|
|
29
29
|
|
|
30
|
-
@queue = Queue.new
|
|
31
30
|
@thread = Thread.new {
|
|
32
31
|
while (event = @queue.pop)
|
|
33
32
|
begin
|
|
@@ -42,9 +41,9 @@ module Ration
|
|
|
42
41
|
def stop
|
|
43
42
|
return if @sync
|
|
44
43
|
|
|
45
|
-
@queue
|
|
44
|
+
@queue.close
|
|
46
45
|
@thread&.join
|
|
47
|
-
@queue =
|
|
46
|
+
@queue = Queue.new
|
|
48
47
|
@thread = nil
|
|
49
48
|
end
|
|
50
49
|
end
|
|
@@ -23,7 +23,7 @@ module Ration
|
|
|
23
23
|
@channel = channel
|
|
24
24
|
@max_payload_bytes = max_payload_bytes
|
|
25
25
|
@poll_interval = poll_interval
|
|
26
|
-
@publish_with = publish_with
|
|
26
|
+
@publish_with = publish_with || method(:publish_direct)
|
|
27
27
|
@logger = logger || Logger.new($stderr)
|
|
28
28
|
@thread = nil
|
|
29
29
|
@stop = false
|
|
@@ -33,16 +33,7 @@ module Ration
|
|
|
33
33
|
payload = event.to_json
|
|
34
34
|
check_payload_size!(payload, @max_payload_bytes)
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
@publish_with.call(@channel, payload)
|
|
38
|
-
else
|
|
39
|
-
conn = PG.connect(@url)
|
|
40
|
-
begin
|
|
41
|
-
conn.exec_params('SELECT pg_notify($1, $2)', [@channel, payload])
|
|
42
|
-
ensure
|
|
43
|
-
conn.close
|
|
44
|
-
end
|
|
45
|
-
end
|
|
36
|
+
@publish_with.call(@channel, payload)
|
|
46
37
|
end
|
|
47
38
|
|
|
48
39
|
def start
|
|
@@ -61,6 +52,15 @@ module Ration
|
|
|
61
52
|
|
|
62
53
|
private
|
|
63
54
|
|
|
55
|
+
def publish_direct(channel, payload)
|
|
56
|
+
conn = PG.connect(@url)
|
|
57
|
+
begin
|
|
58
|
+
conn.exec_params('SELECT pg_notify($1, $2)', [channel, payload])
|
|
59
|
+
ensure
|
|
60
|
+
conn.close
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
64
|
def connect_and_listen
|
|
65
65
|
conn = PG.connect(@url)
|
|
66
66
|
conn.exec("LISTEN #{conn.escape_identifier(@channel)}")
|
|
@@ -23,9 +23,9 @@ module Ration
|
|
|
23
23
|
@channel = channel
|
|
24
24
|
@max_payload_bytes = max_payload_bytes
|
|
25
25
|
@poll_interval = poll_interval
|
|
26
|
-
@publish_with = publish_with
|
|
27
|
-
@logger = logger || Logger.new($stderr)
|
|
28
26
|
@config = RedisClient.config(url: url)
|
|
27
|
+
@publish_with = publish_with || method(:publish_direct)
|
|
28
|
+
@logger = logger || Logger.new($stderr)
|
|
29
29
|
@thread = nil
|
|
30
30
|
@stop = false
|
|
31
31
|
end
|
|
@@ -34,16 +34,7 @@ module Ration
|
|
|
34
34
|
payload = event.to_json
|
|
35
35
|
check_payload_size!(payload, @max_payload_bytes)
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
@publish_with.call(@channel, payload)
|
|
39
|
-
else
|
|
40
|
-
client = @config.new_client
|
|
41
|
-
begin
|
|
42
|
-
client.call('PUBLISH', @channel, payload)
|
|
43
|
-
ensure
|
|
44
|
-
client.close
|
|
45
|
-
end
|
|
46
|
-
end
|
|
37
|
+
@publish_with.call(@channel, payload)
|
|
47
38
|
end
|
|
48
39
|
|
|
49
40
|
def start
|
|
@@ -62,6 +53,15 @@ module Ration
|
|
|
62
53
|
|
|
63
54
|
private
|
|
64
55
|
|
|
56
|
+
def publish_direct(channel, payload)
|
|
57
|
+
client = @config.new_client
|
|
58
|
+
begin
|
|
59
|
+
client.call('PUBLISH', channel, payload)
|
|
60
|
+
ensure
|
|
61
|
+
client.close
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
65
|
def subscribe_client
|
|
66
66
|
client = @config.new_client
|
|
67
67
|
pubsub = client.pubsub
|
data/lib/ration/subscription.rb
CHANGED
|
@@ -3,6 +3,7 @@ require 'securerandom'
|
|
|
3
3
|
module Ration
|
|
4
4
|
class Subscription
|
|
5
5
|
OVERFLOW_POLICIES = %i[close drop_oldest].freeze
|
|
6
|
+
DEFAULT_FILTER = ->(_event) { true }
|
|
6
7
|
|
|
7
8
|
attr_reader :id
|
|
8
9
|
|
|
@@ -13,7 +14,7 @@ module Ration
|
|
|
13
14
|
|
|
14
15
|
@id = SecureRandom.uuid
|
|
15
16
|
@queue = SizedQueue.new(max)
|
|
16
|
-
@filter = filter
|
|
17
|
+
@filter = filter || DEFAULT_FILTER
|
|
17
18
|
@on_overflow = on_overflow
|
|
18
19
|
@logger = logger
|
|
19
20
|
end
|
|
@@ -59,8 +60,6 @@ module Ration
|
|
|
59
60
|
private
|
|
60
61
|
|
|
61
62
|
def passes_filter?(event)
|
|
62
|
-
return true if @filter.nil?
|
|
63
|
-
|
|
64
63
|
@filter.call(event)
|
|
65
64
|
rescue => e
|
|
66
65
|
@logger.error("Ration filter raised, closing subscription #{@id}: #{e.class}: #{e.message}")
|
data/lib/ration/version.rb
CHANGED
data/lib/ration.rb
CHANGED
|
@@ -11,12 +11,11 @@ module Ration
|
|
|
11
11
|
def configure
|
|
12
12
|
yield config
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
backend = config.backend or
|
|
15
15
|
raise NotConfigured, 'No backend configured. Set config.backend to a Ration::Backends::* instance.'
|
|
16
|
-
end
|
|
17
16
|
|
|
18
17
|
@hub&.stop
|
|
19
|
-
@hub = Hub.new(backend:
|
|
18
|
+
@hub = Hub.new(backend: backend, logger: config.logger)
|
|
20
19
|
end
|
|
21
20
|
|
|
22
21
|
def config
|
|
@@ -27,8 +26,8 @@ module Ration
|
|
|
27
26
|
hub.publish(event)
|
|
28
27
|
end
|
|
29
28
|
|
|
30
|
-
def subscribe(
|
|
31
|
-
hub.subscribe(
|
|
29
|
+
def subscribe(...)
|
|
30
|
+
hub.subscribe(...) # steep:ignore UnresolvedOverloading
|
|
32
31
|
end
|
|
33
32
|
|
|
34
33
|
def unsubscribe(sub)
|
|
@@ -44,9 +43,7 @@ module Ration
|
|
|
44
43
|
private
|
|
45
44
|
|
|
46
45
|
def hub
|
|
47
|
-
raise NotConfigured, 'Ration is not configured. Call Ration.configure first.'
|
|
48
|
-
|
|
49
|
-
@hub
|
|
46
|
+
@hub or raise NotConfigured, 'Ration is not configured. Call Ration.configure first.'
|
|
50
47
|
end
|
|
51
48
|
end
|
|
52
49
|
end
|
data/sig/external.rbs
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module PG
|
|
2
|
+
class Error < StandardError
|
|
3
|
+
end
|
|
4
|
+
|
|
5
|
+
def self.connect: (String) -> untyped
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
module RedisClient
|
|
9
|
+
class Error < StandardError
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def self.config: (**untyped) -> untyped
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
module Concurrent
|
|
16
|
+
class Map[unchecked out K, unchecked out V]
|
|
17
|
+
def clear: () -> self
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Ration
|
|
2
|
+
module Backends
|
|
3
|
+
class Base
|
|
4
|
+
DEFAULT_MAX_PAYLOAD_BYTES: Integer
|
|
5
|
+
|
|
6
|
+
@on_event: ^(Ration::event) -> void | nil
|
|
7
|
+
|
|
8
|
+
def publish: (Ration::event) -> void
|
|
9
|
+
def on_event: () { (Ration::event) -> void } -> (^(Ration::event) -> void)
|
|
10
|
+
def start: () -> void
|
|
11
|
+
def stop: () -> void
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
def emit: (Ration::event) -> void
|
|
16
|
+
def check_payload_size!: (String, Integer) -> void
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Ration
|
|
2
|
+
module Backends
|
|
3
|
+
class Memory < Base
|
|
4
|
+
@max_payload_bytes: Integer
|
|
5
|
+
@sync: bool
|
|
6
|
+
@logger: Logger
|
|
7
|
+
@queue: Thread::Queue
|
|
8
|
+
@thread: Thread?
|
|
9
|
+
|
|
10
|
+
def initialize: (?max_payload_bytes: Integer, ?sync: bool, ?logger: Logger?) -> void
|
|
11
|
+
def publish: (Ration::event) -> void
|
|
12
|
+
def start: () -> void
|
|
13
|
+
def stop: () -> void
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
module Ration
|
|
2
|
+
module Backends
|
|
3
|
+
class Postgres < Base
|
|
4
|
+
DEFAULT_CHANNEL: String
|
|
5
|
+
INITIAL_BACKOFF_SECONDS: Integer
|
|
6
|
+
MAX_BACKOFF_SECONDS: Integer
|
|
7
|
+
DEFAULT_POLL_INTERVAL: Float
|
|
8
|
+
|
|
9
|
+
type publish_with = ^(String, String) -> void
|
|
10
|
+
|
|
11
|
+
@url: String
|
|
12
|
+
@channel: String
|
|
13
|
+
@max_payload_bytes: Integer
|
|
14
|
+
@poll_interval: Numeric
|
|
15
|
+
@publish_with: publish_with
|
|
16
|
+
@logger: Logger
|
|
17
|
+
@thread: Thread?
|
|
18
|
+
@stop: bool
|
|
19
|
+
|
|
20
|
+
def initialize: (
|
|
21
|
+
url: String,
|
|
22
|
+
?channel: String,
|
|
23
|
+
?max_payload_bytes: Integer,
|
|
24
|
+
?poll_interval: Numeric,
|
|
25
|
+
?publish_with: publish_with?,
|
|
26
|
+
?logger: Logger?
|
|
27
|
+
) -> void
|
|
28
|
+
|
|
29
|
+
def publish: (Ration::event) -> void
|
|
30
|
+
def start: () -> void
|
|
31
|
+
def stop: () -> void
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def publish_direct: (String, String) -> void
|
|
36
|
+
def connect_and_listen: () -> untyped
|
|
37
|
+
def run_loop: (untyped) -> void
|
|
38
|
+
def reconnect_with_backoff: () -> untyped
|
|
39
|
+
def listen_loop: (untyped) -> void
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
module Ration
|
|
2
|
+
module Backends
|
|
3
|
+
class Redis < Base
|
|
4
|
+
DEFAULT_CHANNEL: String
|
|
5
|
+
INITIAL_BACKOFF_SECONDS: Integer
|
|
6
|
+
MAX_BACKOFF_SECONDS: Integer
|
|
7
|
+
DEFAULT_POLL_INTERVAL: Float
|
|
8
|
+
|
|
9
|
+
type publish_with = ^(String, String) -> void
|
|
10
|
+
|
|
11
|
+
@url: String
|
|
12
|
+
@channel: String
|
|
13
|
+
@max_payload_bytes: Integer
|
|
14
|
+
@poll_interval: Numeric
|
|
15
|
+
@publish_with: publish_with
|
|
16
|
+
@logger: Logger
|
|
17
|
+
@config: untyped
|
|
18
|
+
@thread: Thread?
|
|
19
|
+
@stop: bool
|
|
20
|
+
|
|
21
|
+
def initialize: (
|
|
22
|
+
url: String,
|
|
23
|
+
?channel: String,
|
|
24
|
+
?max_payload_bytes: Integer,
|
|
25
|
+
?poll_interval: Numeric,
|
|
26
|
+
?publish_with: publish_with?,
|
|
27
|
+
?logger: Logger?
|
|
28
|
+
) -> void
|
|
29
|
+
|
|
30
|
+
def publish: (Ration::event) -> void
|
|
31
|
+
def start: () -> void
|
|
32
|
+
def stop: () -> void
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
def publish_direct: (String, String) -> void
|
|
37
|
+
def subscribe_client: () -> untyped
|
|
38
|
+
def run_loop: (untyped) -> void
|
|
39
|
+
def reconnect_with_backoff: () -> untyped
|
|
40
|
+
def listen_loop: (untyped) -> void
|
|
41
|
+
def close_quietly: (untyped) -> void
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
data/sig/ration/hub.rbs
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module Ration
|
|
2
|
+
class Hub
|
|
3
|
+
@backend: Backends::Base
|
|
4
|
+
@logger: Logger
|
|
5
|
+
@subscriptions: Concurrent::Map[String, Subscription]
|
|
6
|
+
@started: bool
|
|
7
|
+
@start_mutex: Thread::Mutex
|
|
8
|
+
|
|
9
|
+
def initialize: (backend: Backends::Base, logger: Logger) -> void
|
|
10
|
+
def publish: (Ration::event) -> void
|
|
11
|
+
def subscribe: (max: Integer, ?filter: Ration::filter?, ?on_overflow: Symbol) -> Subscription
|
|
12
|
+
| [T] (max: Integer, ?filter: Ration::filter?, ?on_overflow: Symbol) { (Subscription) -> T } -> T
|
|
13
|
+
def unsubscribe: (Subscription) -> void
|
|
14
|
+
def stop: () -> void
|
|
15
|
+
def subscription_count: () -> Integer
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
def ensure_started: () -> void
|
|
20
|
+
def deliver: (Ration::event) -> void
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module Ration
|
|
2
|
+
module Rails
|
|
3
|
+
interface _Response
|
|
4
|
+
def headers: () -> Hash[String, String]
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
interface _Request
|
|
8
|
+
def headers: () -> Hash[String, untyped]
|
|
9
|
+
def env: () -> Hash[String, untyped]
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
interface _Controller
|
|
13
|
+
def response: () -> _Response
|
|
14
|
+
def request: () -> _Request
|
|
15
|
+
def response_body=: (untyped) -> void
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
module SSE : _Controller
|
|
19
|
+
def sse_stream: () { (Enumerator::Yielder, String?) -> void } -> void
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
data/sig/ration/sse.rbs
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module Ration
|
|
2
|
+
module SSE
|
|
3
|
+
interface _Output
|
|
4
|
+
def <<: (String) -> void
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
type id_from = ^(Ration::event) -> untyped
|
|
8
|
+
|
|
9
|
+
DEFAULT_ID_FROM: id_from
|
|
10
|
+
|
|
11
|
+
def self.event: (data: untyped, ?event: String?, ?id: untyped, ?retry_ms: Integer?) -> String
|
|
12
|
+
def self.comment: (?String) -> String
|
|
13
|
+
def self.ping: () -> String
|
|
14
|
+
def self.stream: (
|
|
15
|
+
Subscription,
|
|
16
|
+
_Output,
|
|
17
|
+
?heartbeat: _ToF?,
|
|
18
|
+
?since: untyped,
|
|
19
|
+
?id_from: id_from
|
|
20
|
+
) { (Ration::event) -> String? } -> untyped
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def self.ensure_field_value_safe!: (String, String) -> void
|
|
25
|
+
def self.ensure_no_newline!: (String, String) -> void
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module Ration
|
|
2
|
+
class Subscription
|
|
3
|
+
OVERFLOW_POLICIES: Array[Symbol]
|
|
4
|
+
DEFAULT_FILTER: Ration::filter
|
|
5
|
+
|
|
6
|
+
attr_reader id: String
|
|
7
|
+
|
|
8
|
+
@queue: Thread::SizedQueue
|
|
9
|
+
@filter: Ration::filter
|
|
10
|
+
@on_overflow: Symbol
|
|
11
|
+
@logger: Logger
|
|
12
|
+
|
|
13
|
+
def initialize: (max: Integer, ?filter: Ration::filter?, ?on_overflow: Symbol, logger: Logger) -> void
|
|
14
|
+
def pop: (?timeout: _ToF?) -> Ration::event?
|
|
15
|
+
def each_event: (?timeout: _ToF?) -> Enumerator[Ration::event?, self]
|
|
16
|
+
| (?timeout: _ToF?) { (Ration::event?) -> void } -> self
|
|
17
|
+
def closed?: () -> bool
|
|
18
|
+
def close: () -> void
|
|
19
|
+
def deliver: (Ration::event) -> void
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def passes_filter?: (Ration::event) -> boolish
|
|
24
|
+
def handle_overflow: (Ration::event) -> void
|
|
25
|
+
end
|
|
26
|
+
end
|
data/sig/ration.rbs
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Ration
|
|
2
|
+
type event = Hash[Symbol, untyped]
|
|
3
|
+
type filter = ^(event) -> boolish
|
|
4
|
+
|
|
5
|
+
self.@config: Configuration?
|
|
6
|
+
self.@hub: Hub?
|
|
7
|
+
|
|
8
|
+
def self.configure: () { (Configuration) -> void } -> void
|
|
9
|
+
def self.config: () -> Configuration
|
|
10
|
+
def self.publish: (event) -> void
|
|
11
|
+
def self.subscribe: (max: Integer, ?filter: filter?, ?on_overflow: Symbol) -> Subscription
|
|
12
|
+
| [T] (max: Integer, ?filter: filter?, ?on_overflow: Symbol) { (Subscription) -> T } -> T
|
|
13
|
+
def self.unsubscribe: (Subscription) -> void
|
|
14
|
+
def self.reset!: () -> void
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
|
|
18
|
+
def self.hub: () -> Hub
|
|
19
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ration
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Keita Urashima
|
|
@@ -58,6 +58,19 @@ files:
|
|
|
58
58
|
- lib/ration/sse.rb
|
|
59
59
|
- lib/ration/subscription.rb
|
|
60
60
|
- lib/ration/version.rb
|
|
61
|
+
- sig/external.rbs
|
|
62
|
+
- sig/ration.rbs
|
|
63
|
+
- sig/ration/backends/base.rbs
|
|
64
|
+
- sig/ration/backends/memory.rbs
|
|
65
|
+
- sig/ration/backends/postgres.rbs
|
|
66
|
+
- sig/ration/backends/redis.rbs
|
|
67
|
+
- sig/ration/configuration.rbs
|
|
68
|
+
- sig/ration/errors.rbs
|
|
69
|
+
- sig/ration/hub.rbs
|
|
70
|
+
- sig/ration/rails.rbs
|
|
71
|
+
- sig/ration/sse.rbs
|
|
72
|
+
- sig/ration/subscription.rbs
|
|
73
|
+
- sig/ration/version.rbs
|
|
61
74
|
homepage: https://github.com/ursm/ration
|
|
62
75
|
licenses:
|
|
63
76
|
- MIT
|