mayak 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/README.md +5 -52
- data/lib/bundled_rbi/mayak.rbi +20 -0
- data/lib/mayak/encoder.rb +2 -3
- data/lib/mayak/json_codec/from_hash_serializable.rb +38 -0
- data/lib/mayak/json_codec.rb +29 -0
- data/lib/mayak.rb +2 -0
- data/mayak.gemspec +2 -1
- metadata +19 -7
- data/lib/mayak/caching/README.md +0 -100
- data/lib/mayak/http/README.md +0 -105
- data/lib/mayak/json/encoder.rb +0 -21
- data/lib/mayak/lazy/README.md +0 -226
- data/lib/mayak/monads/README.md +0 -1364
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b4924104fc85c9c38df43b25f1902b6c58e3310014229f7a2c8ad728c3af497f
|
4
|
+
data.tar.gz: 249044e065aaa1617531d158bf3a7e2a2d100189550c94f5423501297e60b8e5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eb3bbe732669a8a56af42fda964d789baacdabfd225ca5f681cff02e6df26ed23f1c70a2cf001dfe4f2b66e66667e06331b5be7659a57fc6d2b0e52a994f1841
|
7
|
+
data.tar.gz: b03e54bfc4cf520db93e38ea02cadd8f6bd7e3cf81eb5da39c71545013e4d9005fbcc70c7778da35be2ef4bbba94ed9f883298998ce33b8240c9eacad2353d7e
|
data/README.md
CHANGED
@@ -29,61 +29,14 @@ require "mayak"
|
|
29
29
|
|
30
30
|
Mayak consists from separate classes and interfaces as well as separate modules for specific domains.
|
31
31
|
|
32
|
-
|
33
|
-
|
34
|
-
[
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
[Documentation](./lib/mayak/monads/README.md)
|
39
|
-
|
40
|
-
#### HTTP
|
41
|
-
|
42
|
-
[Documentation](./lib/mayak/http/README.md)
|
43
|
-
|
44
|
-
#### Lazy
|
45
|
-
|
46
|
-
[Documentation](./lib/mayak/lazy/README.md)
|
32
|
+
* [Caching](./docs/caching.md)
|
33
|
+
* [Monads](./docs/monads.md)
|
34
|
+
* [HTTP](./docs/http.md)
|
35
|
+
* [Lazy](./docs/lazy.md)
|
36
|
+
* [Functions](./docs/function.md)
|
47
37
|
|
48
38
|
#### Miscellaneous
|
49
39
|
|
50
|
-
##### Function
|
51
|
-
In some situations Sorbet can not infer a type of proc passed:
|
52
|
-
|
53
|
-
```ruby
|
54
|
-
sig {
|
55
|
-
type_parameters(:A)
|
56
|
-
.params(blk: T.proc.params(arg0: T.type_parameter(:A)).returns(T.type_parameter(:A)))
|
57
|
-
.returns(T.proc.params(arg0: T.type_parameter(:A)).returns(T.type_parameter(:A)))
|
58
|
-
}
|
59
|
-
def proc_identity(&blk)
|
60
|
-
blk
|
61
|
-
end
|
62
|
-
|
63
|
-
T.reveal_type(proc_identity { |a| 10 })
|
64
|
-
# This code is unreachable https://srb.help/7006
|
65
|
-
# proc_identity { |a| 10 }
|
66
|
-
```
|
67
|
-
|
68
|
-
`Mayak::Fuction` allows explicitly define input and output types to help sorbet infer types:
|
69
|
-
|
70
|
-
```ruby
|
71
|
-
sig {
|
72
|
-
type_parameters(:A)
|
73
|
-
.params(
|
74
|
-
fn: Mayak::Function[T.type_parameter(:A), T.type_parameter(:A)])
|
75
|
-
.returns(Mayak::Function[T.type_parameter(:A), T.type_parameter(:A)])
|
76
|
-
}
|
77
|
-
def fn_identity(fn)
|
78
|
-
fn
|
79
|
-
end
|
80
|
-
|
81
|
-
T.reveal_type(
|
82
|
-
fn_identity(Mayak::Function[Integer, Integer].new { |a| a })
|
83
|
-
)
|
84
|
-
# Revealed type: Mayak::Function[Integer, Integer]
|
85
|
-
```
|
86
|
-
|
87
40
|
##### JSON
|
88
41
|
|
89
42
|
`JSON` module provides a type alias to encode JSON type:
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# typed: true
|
2
|
+
|
3
|
+
|
4
|
+
module Mayak
|
5
|
+
class JsonCodec::FromHashSerializable
|
6
|
+
extend T::Sig
|
7
|
+
extend T::Generic
|
8
|
+
|
9
|
+
include ::Mayak::Codec
|
10
|
+
|
11
|
+
Entity = type_member {{ upper: ::Mayak::HashSerializable }}
|
12
|
+
Protocol = type_member {{ fixed: String }}
|
13
|
+
|
14
|
+
sig { override.params(entity: Entity).returns(Protocol) }
|
15
|
+
def encode(entity); end
|
16
|
+
|
17
|
+
sig { override.params(response: Protocol).returns(::Mayak::Monads::Try[Entity]) }
|
18
|
+
def decode(response); end
|
19
|
+
end
|
20
|
+
end
|
data/lib/mayak/encoder.rb
CHANGED
@@ -26,7 +26,6 @@ module Mayak
|
|
26
26
|
blk.call(encode(entity))
|
27
27
|
end
|
28
28
|
end
|
29
|
-
|
30
29
|
class Implementation
|
31
30
|
extend T::Sig
|
32
31
|
extend T::Generic
|
@@ -34,8 +33,8 @@ module Mayak
|
|
34
33
|
|
35
34
|
include ::Mayak::Encoder
|
36
35
|
|
37
|
-
In
|
38
|
-
Out
|
36
|
+
In = type_member
|
37
|
+
Out = type_member
|
39
38
|
|
40
39
|
sig { params(function: T.proc.params(in: In).returns(Out)).void }
|
41
40
|
def initialize(&function)
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# typed: ignore
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require_relative "../monads/try"
|
5
|
+
require "sorbet-coerce"
|
6
|
+
|
7
|
+
module Mayak
|
8
|
+
module JsonCodec
|
9
|
+
class FromHashSerializable
|
10
|
+
include ::Mayak::Monads::Try::Mixin
|
11
|
+
|
12
|
+
include ::Mayak::Codec
|
13
|
+
|
14
|
+
def initialize(type)
|
15
|
+
@type = type
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.[](type)
|
19
|
+
::Mayak::JsonCodec::FromHashSerializable.new(type)
|
20
|
+
end
|
21
|
+
|
22
|
+
def new
|
23
|
+
self
|
24
|
+
end
|
25
|
+
|
26
|
+
def encode(entity)
|
27
|
+
JSON.dump(entity.serialize)
|
28
|
+
end
|
29
|
+
|
30
|
+
def decode(response)
|
31
|
+
Try do
|
32
|
+
parsed = JSON.parse(response)
|
33
|
+
::TypeCoerce::Converter.new(@type).from(parsed)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Mayak
|
5
|
+
module JsonCodec
|
6
|
+
extend T::Sig
|
7
|
+
extend T::Generic
|
8
|
+
extend T::Helpers
|
9
|
+
|
10
|
+
include ::Mayak::Codec
|
11
|
+
|
12
|
+
abstract!
|
13
|
+
|
14
|
+
Entity = type_member
|
15
|
+
Protocol = type_member {{ fixed: String }}
|
16
|
+
|
17
|
+
sig { abstract.params(entity: Entity).returns(Protocol) }
|
18
|
+
def encode(entity)
|
19
|
+
end
|
20
|
+
|
21
|
+
sig {
|
22
|
+
abstract
|
23
|
+
.params(response: Protocol)
|
24
|
+
.returns(Mayak::Monads::Try[Entity])
|
25
|
+
}
|
26
|
+
def decode(response)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/mayak.rb
CHANGED
@@ -19,6 +19,8 @@ require_relative 'mayak/codec'
|
|
19
19
|
require_relative 'mayak/hash_serializable'
|
20
20
|
require_relative 'mayak/lazy'
|
21
21
|
|
22
|
+
require_relative 'mayak/json_codec/from_hash_serializable'
|
23
|
+
|
22
24
|
require_relative 'mayak/caching/unbounded_cache'
|
23
25
|
require_relative 'mayak/caching/lru_cache'
|
24
26
|
|
data/mayak.gemspec
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
6
|
spec.name = "mayak"
|
7
|
-
spec.version = "0.2.
|
7
|
+
spec.version = "0.2.2"
|
8
8
|
spec.summary = "Set of fully typed utility classes and interfaces integrated with Sorbet."
|
9
9
|
spec.description = spec.summary
|
10
10
|
spec.authors = ["Daniil Bober"]
|
@@ -15,6 +15,7 @@ Gem::Specification.new do |spec|
|
|
15
15
|
|
16
16
|
spec.add_dependency 'sorbet-runtime'
|
17
17
|
spec.add_dependency 'sorbet'
|
18
|
+
spec.add_dependency 'sorbet-coerce'
|
18
19
|
|
19
20
|
spec.add_development_dependency "bundler"
|
20
21
|
spec.add_development_dependency "rspec"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mayak
|
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
|
- Daniil Bober
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-07-
|
11
|
+
date: 2025-07-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sorbet-runtime
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: sorbet-coerce
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: bundler
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -88,9 +102,9 @@ extra_rdoc_files: []
|
|
88
102
|
files:
|
89
103
|
- LICENSE
|
90
104
|
- README.md
|
105
|
+
- lib/bundled_rbi/mayak.rbi
|
91
106
|
- lib/mayak.rb
|
92
107
|
- lib/mayak/cache.rb
|
93
|
-
- lib/mayak/caching/README.md
|
94
108
|
- lib/mayak/caching/lru_cache.rb
|
95
109
|
- lib/mayak/caching/unbounded_cache.rb
|
96
110
|
- lib/mayak/codec.rb
|
@@ -111,7 +125,6 @@ files:
|
|
111
125
|
- lib/mayak/failable_function.rb
|
112
126
|
- lib/mayak/function.rb
|
113
127
|
- lib/mayak/hash_serializable.rb
|
114
|
-
- lib/mayak/http/README.md
|
115
128
|
- lib/mayak/http/client.rb
|
116
129
|
- lib/mayak/http/decoder.rb
|
117
130
|
- lib/mayak/http/encoder.rb
|
@@ -119,10 +132,9 @@ files:
|
|
119
132
|
- lib/mayak/http/response.rb
|
120
133
|
- lib/mayak/http/verb.rb
|
121
134
|
- lib/mayak/json.rb
|
122
|
-
- lib/mayak/
|
135
|
+
- lib/mayak/json_codec.rb
|
136
|
+
- lib/mayak/json_codec/from_hash_serializable.rb
|
123
137
|
- lib/mayak/lazy.rb
|
124
|
-
- lib/mayak/lazy/README.md
|
125
|
-
- lib/mayak/monads/README.md
|
126
138
|
- lib/mayak/monads/maybe.rb
|
127
139
|
- lib/mayak/monads/result.rb
|
128
140
|
- lib/mayak/monads/try.rb
|
data/lib/mayak/caching/README.md
DELETED
@@ -1,100 +0,0 @@
|
|
1
|
-
# Caching
|
2
|
-
|
3
|
-
Caching modules constist from `Mayak::Cache` and several implementations in `Mayak::Caching` module. `Mayak::Caching` provides in-memory caches using regular ruby hashes: an unbounded cache and a cache using LRU eviction policy.
|
4
|
-
|
5
|
-
Usage of unbounded cache:
|
6
|
-
```ruby
|
7
|
-
unbounded_cache = Mayak::Caching::UnboundedCache[String, Integer].new
|
8
|
-
unbounded_cache.write("foo", 10)
|
9
|
-
unbounded_cache.write("bar", 20)
|
10
|
-
|
11
|
-
unbounded_cache.read("foo") # 10
|
12
|
-
unbounded_cache.read("bar") # 20
|
13
|
-
unbounded_cache.read("baz") # nil
|
14
|
-
|
15
|
-
unbounded_cache.delete("bar")
|
16
|
-
unbounded_cache.read("bar") # nil
|
17
|
-
|
18
|
-
unbounded_cache.fetch("foo") { 100 } # 10
|
19
|
-
unbounded_cache.fetch("bar") { 100 } # 100
|
20
|
-
unbounded_cache.fetch("bar") { 200 } # 100
|
21
|
-
|
22
|
-
unbounded_cache.clear # 100
|
23
|
-
unbounded_cache.read("foo") # nil
|
24
|
-
unbounded_cache.read("bar") # nil
|
25
|
-
```
|
26
|
-
|
27
|
-
LRU cache has limited size: when the cache is full and a new element is added, some element is evicted using least recently used policy:
|
28
|
-
|
29
|
-
```ruby
|
30
|
-
lru_cache = Mayak::Caching::LRUCache[String, Integer].new(max_size: 3)
|
31
|
-
|
32
|
-
lru_cache.write("key1", 1)
|
33
|
-
lru_cache.write("key2", 2)
|
34
|
-
lru_cache.write("key3", 3)
|
35
|
-
|
36
|
-
lru_cache.read("key1") # 1
|
37
|
-
lru_cache.read("key2") # 2
|
38
|
-
lru_cache.read("key3") # 3
|
39
|
-
|
40
|
-
lru_cache.write("key4", 4)
|
41
|
-
lru_cache.read("key4") # 4
|
42
|
-
lru_cache.read("key1") # nil
|
43
|
-
```
|
44
|
-
|
45
|
-
You can implement `Mayak::Cache` interface using a different store (for example default Rails cache) and use different implementations interchangeably:
|
46
|
-
|
47
|
-
```ruby
|
48
|
-
class RailsCache < T::Struct
|
49
|
-
extend T::Sig
|
50
|
-
extend T::Generic
|
51
|
-
extend T::Helpers
|
52
|
-
|
53
|
-
include Mayak::Cache
|
54
|
-
|
55
|
-
Key = type_member
|
56
|
-
Value = type_member
|
57
|
-
|
58
|
-
const :converter, T.proc.params(value: T.untyped).returns(Value)
|
59
|
-
|
60
|
-
sig { override.params(key: Key).returns(T.nilable(Value)) }
|
61
|
-
def read(key)
|
62
|
-
converter.call(Rails.cache.read(key))
|
63
|
-
end
|
64
|
-
|
65
|
-
sig { override.params(key: Key, value: Value).void }
|
66
|
-
def write(key, value)
|
67
|
-
Rails.cache.write(key, value)
|
68
|
-
end
|
69
|
-
|
70
|
-
sig { override.params(key: Key, blk: T.proc.returns(Value)).returns(Value) }
|
71
|
-
def fetch(key, &blk)
|
72
|
-
converter.call(Rails.cache.fetch(key, &blk))
|
73
|
-
end
|
74
|
-
|
75
|
-
sig { override.void }
|
76
|
-
def clear
|
77
|
-
Rails.cache.clear
|
78
|
-
end
|
79
|
-
|
80
|
-
sig { override.params(key: Key).void }
|
81
|
-
def delete(key)
|
82
|
-
Rails.cache.delete(key)
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
class Service < T::Struct
|
87
|
-
extend T::Sig
|
88
|
-
|
89
|
-
const :cache, Mayak::Cache[String, String]
|
90
|
-
end
|
91
|
-
|
92
|
-
in_memory = Service.new(
|
93
|
-
cache: Mayak::Caching::UnboundedCache[String, String].new
|
94
|
-
)
|
95
|
-
rails_cache = Service.new(
|
96
|
-
cache: RailsCache[String, String].new(
|
97
|
-
converter: -> (value) { value.to_s }
|
98
|
-
)
|
99
|
-
)
|
100
|
-
```
|
data/lib/mayak/http/README.md
DELETED
@@ -1,105 +0,0 @@
|
|
1
|
-
# Http
|
2
|
-
|
3
|
-
This module contains abstraction for HTTP interactions. It provides data classes that models HTTP requests and response as well interfaces for http client and codecs.
|
4
|
-
|
5
|
-
#### Verb
|
6
|
-
|
7
|
-
Enumaration that encodes an HTTP verb.
|
8
|
-
|
9
|
-
```ruby
|
10
|
-
get_verb = Mayak::Http::Verb::Get
|
11
|
-
post_verb = Mayak::Http::Verb::Post
|
12
|
-
head_verb = Mayak::Http::Verb::Head
|
13
|
-
put_verb = Mayak::Http::Verb::Put
|
14
|
-
patch_verb = Mayak::Http::Verb::Patch
|
15
|
-
delete_verb = Mayak::Http::Verb::Delete
|
16
|
-
connect_verb = Mayak::Http::Verb::Connect
|
17
|
-
options_verb = Mayak::Http::Verb::Options
|
18
|
-
trace_verb = Mayak::Http::Verb::Trace
|
19
|
-
```
|
20
|
-
|
21
|
-
#### Request
|
22
|
-
|
23
|
-
`Mayak::Http::Request` is a datastructure that encodes an HTTP request.
|
24
|
-
```ruby
|
25
|
-
# to build an HTTP request verb and URI should be provided, as well as optional headers hash and body
|
26
|
-
request = Mayak::Http::Request.new(
|
27
|
-
verb: Mayak::Http::Verb::Put,
|
28
|
-
url: URI.parse("https://www.foobar.com/users/update"),
|
29
|
-
headers: { "content-type" => "application/json" },
|
30
|
-
body: """{ id: 100, name: "Daniil" })"""
|
31
|
-
)
|
32
|
-
|
33
|
-
# to build request helper constructor methods can be used
|
34
|
-
get_request = Mayak::Http::Request.get(url: URI.parse("https://www.foobar.com"))
|
35
|
-
```
|
36
|
-
|
37
|
-
#### Response
|
38
|
-
|
39
|
-
`Mayak::Http::Response` is a datastructure that encodes an HTTP request. It contains status, and optional headers and body:
|
40
|
-
|
41
|
-
```ruby
|
42
|
-
response = Mayak::Http::Response.new(
|
43
|
-
status: 200
|
44
|
-
headers: { "content-type" => "application/json" },
|
45
|
-
body: """{ id: 100, name: "Daniil" }"""
|
46
|
-
)
|
47
|
-
```
|
48
|
-
|
49
|
-
#### Client
|
50
|
-
|
51
|
-
Interface that encodes an HTTP client. The interface is very simple and consists from one method that receives a request and returns a `Try` monad containg response:
|
52
|
-
```ruby
|
53
|
-
module Mayak
|
54
|
-
module Http
|
55
|
-
module Client
|
56
|
-
extend T::Sig
|
57
|
-
extend T::Generic
|
58
|
-
|
59
|
-
interface!
|
60
|
-
|
61
|
-
sig { abstract.params(request: Http::Request).returns(Mayak::Monads::Try[Mayak::Http::Response]) }
|
62
|
-
def send_request(request)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
```
|
68
|
-
|
69
|
-
You can implement this interface using a specific library:
|
70
|
-
|
71
|
-
```ruby
|
72
|
-
class FaradayClient
|
73
|
-
extend T::Sig
|
74
|
-
|
75
|
-
include Mayak::Http::Client
|
76
|
-
|
77
|
-
include Mayak::Monads::Try::Mixin
|
78
|
-
|
79
|
-
sig { params(config_blk: T.nilable(T.proc.params(connection: Faraday::Connection).void)).void }
|
80
|
-
def initialize(&config_blk)
|
81
|
-
@faraday_instance = T.let(
|
82
|
-
config_blk.nil? ? Faraday.new : Faraday.new(&@config_blk),
|
83
|
-
Faraday
|
84
|
-
)
|
85
|
-
end
|
86
|
-
|
87
|
-
sig { override.params(request: Mayak::Http::Request).returns(Mayak::Monads::Try[Mayak::Http::Response]) }
|
88
|
-
def send_request(request)
|
89
|
-
Try do
|
90
|
-
faraday_response = @faraday_instance.run_request(
|
91
|
-
verb.serialize.downcase.to_sym,
|
92
|
-
request.url,
|
93
|
-
request.body,
|
94
|
-
request.headers
|
95
|
-
)
|
96
|
-
|
97
|
-
Mayak::Http::Response.new(
|
98
|
-
status: T.must(faraday_response.status.to_i),
|
99
|
-
headers: faraday_response.headers || {},
|
100
|
-
body: faraday_response.body || ""
|
101
|
-
)
|
102
|
-
end
|
103
|
-
end
|
104
|
-
end
|
105
|
-
```
|
data/lib/mayak/json/encoder.rb
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
# typed: strict
|
3
|
-
|
4
|
-
require "json"
|
5
|
-
|
6
|
-
module Mayak
|
7
|
-
module Json
|
8
|
-
module Encoder
|
9
|
-
extend T::Sig
|
10
|
-
extend T::Generic
|
11
|
-
extend T::Helpers
|
12
|
-
|
13
|
-
abstract!
|
14
|
-
|
15
|
-
include ::Mayak::Encoder
|
16
|
-
|
17
|
-
In = type_member
|
18
|
-
Out = type_member {{ fixed: ::Mayak::Json::JsonType }}
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|