proc 0.4.0 → 0.8.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: 63d146f97fd1dc28e5ff40ae924ac80e5f34838da4a3bb626b51023c2e23efbc
4
- data.tar.gz: ebbab25f52bc3344c9fee6e10a00af6ed5022808d05f8516c41dc914987178d6
3
+ metadata.gz: e066afa0667795307f8627a3220f8bc3887c644b2679a45b9e044d7843ca4ed3
4
+ data.tar.gz: a5775e58b9a2c7730242b9971d44f1d31d02eca4b5e6bc36ee2e5a712dc63537
5
5
  SHA512:
6
- metadata.gz: 06f06ba059619e117f86021bfeda3b5520d6842664d5fb284c77e7920cae38b66d4e82874329243ee0e456216034a07111e04f8b49ffaf6828470eb8a0e7f2fc
7
- data.tar.gz: d6b1423b158de5320e963c48a988db2936c5c576eb3e02b2ec9d2d675ff54ca6c428e270baaf566935bf8df2fd18b9b59e67449c5ed661d5c57d7a4b75a8f41b
6
+ metadata.gz: 1c41c56fdfb839226790e7ad63c2fce4724b25b8fd61d79ac47adf2f4e9e9e673dea272a1ebc3e9ee1c1960a71a31a048f133efcc6544fcab92759716b7605bf
7
+ data.tar.gz: 1c72579ebf19b7ac9a8f85641a4ced7637829e44f3259242d0cec76ced0daaac4180a1334d1711784c459bf9e21f0cecddda67b11fd08742fb63427188c184f4
data/lib/proc.rb CHANGED
@@ -8,7 +8,7 @@ class Proc
8
8
  end
9
9
 
10
10
  def self.undefined
11
- @_undefined ||= Object.new
11
+ @_undefined ||= ::Object.new
12
12
  end
13
13
 
14
14
  def self.undefined?(value)
data/lib/proc/argument.rb CHANGED
@@ -8,7 +8,7 @@ class Proc
8
8
  end
9
9
 
10
10
  def serialize
11
- {"::" => {"name" => @name.to_s}.merge(serialized_options)}
11
+ ["@@", @name.to_s, serialized_options]
12
12
  end
13
13
 
14
14
  def serialized_options
@@ -21,7 +21,7 @@ class Proc
21
21
  if value.respond_to?(:serialize)
22
22
  value.serialize
23
23
  else
24
- value
24
+ ["%%", value]
25
25
  end
26
26
  end
27
27
  end
data/lib/proc/callable.rb CHANGED
@@ -16,7 +16,7 @@ class Proc
16
16
  @arguments = arguments.dup
17
17
  end
18
18
 
19
- def call(input = input_omitted = true, **arguments)
19
+ def call(input = input_omitted = true, **arguments, &block)
20
20
  callable = self.class.new(
21
21
  @proc,
22
22
  client: @client,
@@ -24,7 +24,7 @@ class Proc
24
24
  arguments: @arguments.merge(arguments)
25
25
  )
26
26
 
27
- @client.call(@proc, callable.serialized_input, **callable.serialized_arguments)
27
+ @client.call(@proc, callable.input, **callable.arguments, &block)
28
28
  end
29
29
 
30
30
  def with(input = input_omitted = true, **arguments)
@@ -43,14 +43,20 @@ class Proc
43
43
  composed
44
44
  end
45
45
 
46
- def serialize
47
- wrapped = {"[]" => [[@proc, serialized_arguments]]}
46
+ def serialize(unwrapped: false)
47
+ serialized = ["()", @proc]
48
48
 
49
49
  unless Proc.undefined?(@input)
50
- wrapped["<<"] = serialized_input
50
+ serialized << [">>", serialized_input]
51
51
  end
52
52
 
53
- {"{}" => wrapped}
53
+ serialized.concat(serialized_arguments)
54
+
55
+ if unwrapped
56
+ serialized
57
+ else
58
+ ["{}", serialized]
59
+ end
54
60
  end
55
61
 
56
62
  def serialized_input
@@ -58,8 +64,8 @@ class Proc
58
64
  end
59
65
 
60
66
  def serialized_arguments
61
- @arguments.each_pair.each_with_object({}) { |(key, value), hash|
62
- hash[key.to_s] = serialize_value(value)
67
+ @arguments.map { |key, value|
68
+ ["$$", key.to_s, serialize_value(value)]
63
69
  }
64
70
  end
65
71
 
@@ -99,7 +105,7 @@ class Proc
99
105
  if value.respond_to?(:serialize)
100
106
  value.serialize
101
107
  else
102
- value
108
+ ["%%", value]
103
109
  end
104
110
  end
105
111
  end
data/lib/proc/client.rb CHANGED
@@ -6,11 +6,19 @@ require "oj"
6
6
  require_relative "argument"
7
7
  require_relative "callable"
8
8
  require_relative "composition"
9
+ require_relative "enumerator"
9
10
 
10
11
  require_relative "http/client"
11
12
 
12
13
  Console.logger.off!
13
14
 
15
+ Oj.default_options = {
16
+ mode: :custom,
17
+ bigdecimal_load: :auto,
18
+ float_precision: 0,
19
+ second_precision: 6
20
+ }.freeze
21
+
14
22
  class Proc
15
23
  class Error < StandardError
16
24
  end
@@ -37,6 +45,8 @@ class Proc
37
45
  end
38
46
 
39
47
  class Client
48
+ attr_reader :authorization, :scheme, :host
49
+
40
50
  def initialize(authorization, scheme: "https", host: "proc.dev")
41
51
  @authorization = authorization
42
52
  @scheme = scheme
@@ -65,46 +75,67 @@ class Proc
65
75
  end
66
76
 
67
77
  DEFAULT_HEADERS = {
68
- "accept" => "application/json",
69
- "content-type" => "application/json"
78
+ "accept" => "application/vnd.proc+json",
79
+ "content-type" => "application/vnd.proc+json"
70
80
  }.freeze
71
81
 
72
- def call(proc = nil, input = nil, **arguments)
73
- body = {"<>" => true}
82
+ def call(proc = nil, input = Proc.undefined, **arguments, &block)
83
+ body = []
74
84
 
75
85
  unless Proc.undefined?(input)
76
- body["<<"] = serialize_value(input)
86
+ body << [">>", serialize_value(input)]
77
87
  end
78
88
 
79
89
  arguments.each_pair do |key, value|
80
- body[key.to_s] = serialize_value(value)
90
+ body << ["$$", key.to_s, serialize_value(value)]
81
91
  end
82
92
 
83
93
  headers = {
84
94
  "authorization" => "bearer #{@authorization}"
85
95
  }.merge(DEFAULT_HEADERS)
86
96
 
87
- payload = get_payload(proc: proc, headers: headers, body: body)
97
+ status, headers, payload = get_payload(proc: proc, headers: headers, body: body)
88
98
 
89
- case payload["status"]
99
+ case status
90
100
  when 200
91
- payload[">>"]
101
+ result = extract_output(payload)
102
+
103
+ if (cursor = headers["x-cursor"])
104
+ enumerator = if cursor.empty?
105
+ Enumerator.new(result)
106
+ else
107
+ Enumerator.new(result) {
108
+ arguments[:cursor] = cursor.to_s
109
+ call(proc, input, **arguments)
110
+ }
111
+ end
112
+
113
+ if block
114
+ enumerator.each(&block)
115
+ else
116
+ enumerator
117
+ end
118
+ else
119
+ result
120
+ end
92
121
  when 400
93
- raise Proc::Invalid, payload.dig("error", "message")
122
+ raise Proc::Invalid, extract_error_message(payload)
94
123
  when 401
95
- raise Proc::Unauthorized, payload.dig("error", "message")
124
+ raise Proc::Unauthorized, extract_error_message(payload)
96
125
  when 403
97
- raise Proc::Forbidden, payload.dig("error", "message")
126
+ raise Proc::Forbidden, extract_error_message(payload)
98
127
  when 404
99
- raise Proc::Undefined, payload.dig("error", "message")
128
+ raise Proc::Undefined, extract_error_message(payload)
100
129
  when 408
101
- raise Proc::Timeout, payload.dig("error", "message")
130
+ raise Proc::Timeout, extract_error_message(payload)
131
+ when 413
132
+ raise Proc::Invalid, extract_error_message(payload)
102
133
  when 429
103
- raise Proc::Limited, payload.dig("error", "message")
134
+ raise Proc::Limited, extract_error_message(payload)
104
135
  when 500
105
- raise Proc::Error, payload.dig("error", "message")
136
+ raise Proc::Error, extract_error_message(payload)
106
137
  when 508
107
- raise Proc::Error, payload.dig("error", "message")
138
+ raise Proc::Error, extract_error_message(payload)
108
139
  else
109
140
  raise Proc::Error, "unhandled"
110
141
  end
@@ -141,21 +172,44 @@ class Proc
141
172
  if value.respond_to?(:serialize)
142
173
  value.serialize
143
174
  else
144
- value
175
+ ["%%", value]
145
176
  end
146
177
  end
147
178
 
148
179
  private def get_payload(proc:, headers:, body:)
149
- @internal.call(:post, build_uri(proc), headers: headers, body: Oj.dump(body, mode: :custom)) { |response|
180
+ @internal.call(:post, build_uri(proc), headers: headers, body: Oj.dump(body)) do |response|
150
181
  @remaining = response.headers["x-rate-limit-remaining"].to_s.to_i
151
182
  @resets_at = Time.at(response.headers["x-rate-limit-reset"].to_s.to_i)
152
-
153
- payload = Oj.load(response.read, mode: :compat, compat_bigdecimal: true)
154
- payload["status"] = response.status
155
- payload
156
- }
183
+ [response.status, response.headers, Oj.load(response.read)]
184
+ end
157
185
  rescue
158
186
  raise Proc::Unavailable
159
187
  end
188
+
189
+ private def extract_output(payload)
190
+ payload.each do |tuple|
191
+ case tuple[0]
192
+ when "<<"
193
+ return tuple[1]
194
+ end
195
+ end
196
+
197
+ nil
198
+ end
199
+
200
+ private def extract_error(payload)
201
+ payload.each do |tuple|
202
+ case tuple[0]
203
+ when "!!"
204
+ return tuple[1]
205
+ end
206
+ end
207
+
208
+ nil
209
+ end
210
+
211
+ private def extract_error_message(payload)
212
+ extract_error(payload)&.dig("message")
213
+ end
160
214
  end
161
215
  end
@@ -15,7 +15,7 @@ class Proc
15
15
  @callables = @callables.dup
16
16
  end
17
17
 
18
- def call(input = input_omitted = true, **arguments)
18
+ def call(input = input_omitted = true, **arguments, &block)
19
19
  callable = self.class.new(
20
20
  client: @client,
21
21
  input: input_omitted ? @input : input,
@@ -23,7 +23,7 @@ class Proc
23
23
  arguments: @arguments.merge(arguments)
24
24
  )
25
25
 
26
- @client.call("proc.exec", nil, proc: callable.serialize)
26
+ @client.call("exec", Proc.undefined, proc: callable, &block)
27
27
  end
28
28
 
29
29
  def with(input = input_omitted = true, **arguments)
@@ -51,25 +51,13 @@ class Proc
51
51
  end
52
52
 
53
53
  def serialize
54
- wrapped = {"[]" => serialized_calls}
54
+ serialized = ["{}"]
55
55
 
56
56
  unless Proc.undefined?(@input)
57
- wrapped["<<"] = serialized_input
57
+ serialized << [">>", serialized_input]
58
58
  end
59
59
 
60
- {"{}" => wrapped.merge(serialized_arguments)}
61
- end
62
-
63
- def serialized_calls
64
- @callables.map { |callable|
65
- arguments = callable.serialized_arguments
66
-
67
- unless Proc.undefined?(callable.input)
68
- arguments["<<"] = callable.serialized_input
69
- end
70
-
71
- [callable.proc, arguments]
72
- }
60
+ serialized + serialized_arguments + @callables.map { |callable| callable.serialize(unwrapped: true) }
73
61
  end
74
62
 
75
63
  def serialized_input
@@ -77,8 +65,8 @@ class Proc
77
65
  end
78
66
 
79
67
  def serialized_arguments
80
- @arguments.each_pair.each_with_object({}) { |(key, value), hash|
81
- hash[key.to_s] = serialize_value(value)
68
+ @arguments.map { |key, value|
69
+ ["$$", key.to_s, serialize_value(value)]
82
70
  }
83
71
  end
84
72
 
@@ -93,7 +81,7 @@ class Proc
93
81
  if value.respond_to?(:serialize)
94
82
  value.serialize
95
83
  else
96
- value
84
+ ["%%", value]
97
85
  end
98
86
  end
99
87
  end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Proc
4
+ class Enumerator
5
+ include Enumerable
6
+
7
+ def initialize(values, &next_block)
8
+ @values = values
9
+ @next_block = next_block
10
+ end
11
+
12
+ def each(&block)
13
+ return to_enum(:each) unless block
14
+
15
+ @values.each(&block)
16
+
17
+ if @next_block
18
+ @next_block.call.each(&block)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -3,8 +3,6 @@
3
3
  require "async"
4
4
  require "async/http/internet"
5
5
 
6
- require "protocol/http/body/streamable"
7
-
8
6
  require "core/async"
9
7
 
10
8
  require_relative "request"
@@ -15,30 +13,24 @@ class Proc
15
13
  class Client
16
14
  include Is::Async
17
15
 
18
- def initialize
19
- @internet = Async::HTTP::Internet.new
20
- end
21
-
22
16
  def call(method, uri, params: {}, headers: {}, body: nil)
17
+ internet = Async::HTTP::Internet.new
23
18
  request = Request.new(method: method, uri: uri, params: params, headers: headers, body: body)
24
19
 
25
20
  await {
26
21
  begin
27
- response = make_request(request)
22
+ response = make_request(internet, request)
28
23
 
29
24
  yield response
30
25
  ensure
31
26
  response&.close
27
+ internet&.close
32
28
  end
33
29
  }
34
30
  end
35
31
 
36
- def close
37
- @internet.close
38
- end
39
-
40
- private def make_request(request)
41
- async_response = @internet.call(*request.callable)
32
+ private def make_request(internet, request)
33
+ async_response = internet.call(*request.callable)
42
34
  wrap_async_response_for_request(async_response, request)
43
35
  end
44
36
 
data/lib/proc/version.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Proc
4
- VERSION = "0.4.0"
4
+ VERSION = "0.8.1"
5
5
 
6
6
  def self.version
7
7
  VERSION
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: proc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bryan Powell
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-01-20 00:00:00.000000000 Z
11
+ date: 2021-03-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: async-http
@@ -16,42 +16,42 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.52.5
19
+ version: 0.54.1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.52.5
26
+ version: 0.54.1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: core-async
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.0.0
33
+ version: 0.1.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 0.0.0
40
+ version: 0.1.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: oj
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '3.10'
47
+ version: '3.11'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '3.10'
54
+ version: '3.11'
55
55
  description: Proc client library.
56
56
  email: bryan@metabahn.com
57
57
  executables: []
@@ -65,6 +65,7 @@ files:
65
65
  - lib/proc/callable.rb
66
66
  - lib/proc/client.rb
67
67
  - lib/proc/composition.rb
68
+ - lib/proc/enumerator.rb
68
69
  - lib/proc/http/client.rb
69
70
  - lib/proc/http/request.rb
70
71
  - lib/proc/http/response.rb
@@ -88,7 +89,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
88
89
  - !ruby/object:Gem::Version
89
90
  version: '0'
90
91
  requirements: []
91
- rubygems_version: 3.1.4
92
+ rubygems_version: 3.2.4
92
93
  signing_key:
93
94
  specification_version: 4
94
95
  summary: Proc client library.