muxi 0.20260324.0 → 0.20260408.0
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/muxi/formation_client.rb +83 -18
- data/lib/muxi/version.rb +1 -1
- metadata +2 -3
- data/CHANGELOG.md +0 -14
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1741eb77395142b7aa929981ed4d43ebc2a82cbd67b2ededb3ab12a20692290d
|
|
4
|
+
data.tar.gz: a7457ec97f4bea234c3a27be22ff4f5f0f83d582027c5792472555608af26273
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5f8d7fa638ae3ef2eb16accacda65ff417f1f241980069d626f4e08a3b2f0aea47654957b07b4dd1e1b058bd6c3dc1d71f03663d884437c813d792b4a0094cff
|
|
7
|
+
data.tar.gz: dcaf114006f7deb58db5de30e48ea2dc631220b953bef9a07964ed70bbdbe70c3cd9cac9fc31ec071f97cb02d1a6396777dd4f2509e211e06d9cb9639639a894
|
|
@@ -98,34 +98,99 @@ module Muxi
|
|
|
98
98
|
|
|
99
99
|
event = nil
|
|
100
100
|
data_parts = []
|
|
101
|
+
buffer = +""
|
|
101
102
|
|
|
102
103
|
http.request(request) do |response|
|
|
103
104
|
response.read_body do |chunk|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
if line.start_with?("event:")
|
|
118
|
-
event = line[6..].strip
|
|
119
|
-
elsif line.start_with?("data:")
|
|
120
|
-
data_parts << line[5..].strip
|
|
121
|
-
end
|
|
105
|
+
buffer << chunk
|
|
106
|
+
while (newline = buffer.index("\n"))
|
|
107
|
+
raw_line = buffer.slice!(0..newline)
|
|
108
|
+
line = raw_line.delete_suffix("\n").delete_suffix("\r")
|
|
109
|
+
parsed = consume_sse_line(line, event, data_parts)
|
|
110
|
+
event = parsed[:event]
|
|
111
|
+
data_parts = parsed[:data_parts]
|
|
112
|
+
next unless parsed[:emitted]
|
|
113
|
+
|
|
114
|
+
throw_if_route_error(parsed[:emitted])
|
|
115
|
+
yield(parsed[:emitted])
|
|
122
116
|
end
|
|
123
117
|
end
|
|
124
118
|
end
|
|
119
|
+
|
|
120
|
+
unless buffer.empty?
|
|
121
|
+
parsed = consume_sse_line(buffer.delete_suffix("\r"), event, data_parts)
|
|
122
|
+
event = parsed[:event]
|
|
123
|
+
data_parts = parsed[:data_parts]
|
|
124
|
+
if parsed[:emitted]
|
|
125
|
+
throw_if_route_error(parsed[:emitted])
|
|
126
|
+
yield(parsed[:emitted])
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
emitted = flush_sse_event(event, data_parts)
|
|
131
|
+
if emitted
|
|
132
|
+
throw_if_route_error(emitted)
|
|
133
|
+
yield(emitted)
|
|
134
|
+
end
|
|
125
135
|
end
|
|
126
136
|
|
|
127
137
|
private
|
|
128
138
|
|
|
139
|
+
def consume_sse_line(line, event, data_parts)
|
|
140
|
+
return { event: event, data_parts: data_parts, emitted: nil } if line.start_with?(":")
|
|
141
|
+
|
|
142
|
+
if line.empty?
|
|
143
|
+
return {
|
|
144
|
+
event: nil,
|
|
145
|
+
data_parts: [],
|
|
146
|
+
emitted: flush_sse_event(event, data_parts)
|
|
147
|
+
}
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
field, value = split_sse_field(line)
|
|
151
|
+
if field == "event"
|
|
152
|
+
event = value
|
|
153
|
+
elsif field == "data"
|
|
154
|
+
data_parts = data_parts + [value]
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
{ event: event, data_parts: data_parts, emitted: nil }
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def flush_sse_event(event, data_parts)
|
|
161
|
+
return nil if event.nil? && data_parts.empty?
|
|
162
|
+
|
|
163
|
+
{ "event" => event || "message", "data" => data_parts.join("\n") }
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def throw_if_route_error(event)
|
|
167
|
+
return unless event["event"] == "error"
|
|
168
|
+
|
|
169
|
+
code = "STREAM_ERROR"
|
|
170
|
+
message = event["data"].to_s.empty? ? "stream error" : event["data"].to_s
|
|
171
|
+
details = nil
|
|
172
|
+
|
|
173
|
+
begin
|
|
174
|
+
parsed = JSON.parse(event["data"].to_s)
|
|
175
|
+
if parsed.is_a?(Hash)
|
|
176
|
+
details = parsed
|
|
177
|
+
code = parsed["type"] || parsed["code"] || parsed["error"] || code
|
|
178
|
+
message = parsed["error"] || parsed["message"] || message
|
|
179
|
+
end
|
|
180
|
+
rescue JSON::ParserError
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
raise MuxiError.new(code, message, 0, details)
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def split_sse_field(line)
|
|
187
|
+
field, value = line.split(":", 2)
|
|
188
|
+
value ||= ""
|
|
189
|
+
value = value[1..] if value.start_with?(" ")
|
|
190
|
+
[field, value]
|
|
191
|
+
end
|
|
192
|
+
private
|
|
193
|
+
|
|
129
194
|
def build_url(path, params)
|
|
130
195
|
rel_path = path.start_with?("/") ? path : "/#{path}"
|
|
131
196
|
query = params&.compact&.map { |k, v| "#{k}=#{URI.encode_www_form_component(v.to_s)}" }&.join("&")
|
data/lib/muxi/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: muxi
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.20260408.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- MUXI AI
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-04-08 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: base64
|
|
@@ -103,7 +103,6 @@ extensions: []
|
|
|
103
103
|
extra_rdoc_files: []
|
|
104
104
|
files:
|
|
105
105
|
- ".rubocop.yml"
|
|
106
|
-
- CHANGELOG.md
|
|
107
106
|
- README.md
|
|
108
107
|
- Rakefile
|
|
109
108
|
- SECURITY.md
|
data/CHANGELOG.md
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
|
|
3
|
-
All notable changes to this project will be documented in this file.
|
|
4
|
-
|
|
5
|
-
## [Unreleased]
|
|
6
|
-
|
|
7
|
-
### Added
|
|
8
|
-
- `mode` parameter in `FormationConfig` for draft/live URL routing
|
|
9
|
-
- `mode="live"` (default): Uses `/api/{id}/v1` prefix
|
|
10
|
-
- `mode="draft"`: Uses `/draft/{id}/v1` prefix for local development with `muxi up`
|
|
11
|
-
- SDK version update notifications (via `X-Muxi-SDK-Latest` response header)
|
|
12
|
-
- Notifies when newer SDK version available (max once per 12 hours)
|
|
13
|
-
- Disable with `MUXI_SDK_VERSION_NOTIFICATION=0`
|
|
14
|
-
- Console telemetry support via internal `_app` parameter
|