search-engine-for-typesense 30.1.6.5 → 30.1.6.6
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/search_engine/logging/live_renderer.rb +74 -2
- data/lib/search_engine/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 685951054b6b65954ff6517a08176c8bec124c197980dec5fcfc0ebbd19f6691
|
|
4
|
+
data.tar.gz: 12e290d5e45325cb031b06f87d158b33300fdc8682d3a417ba7191940e35211e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f7e7e8ab135067d43fd2cffed2dfc0fdeac7f3861c267dc47d5131c2600a7e5adee5b9267d5b326517cfe32c526a0e67d13d614312183c59ff0e496def671990
|
|
7
|
+
data.tar.gz: dcb0366fa3ddd2dbe03bc50dec6032093761eba588ae2e88116e2b939cbc8f62ea442c0857448b3d69d20cdf7eccc98b0f5d9d1ee2b2d6ce593453539d889b97
|
|
@@ -30,6 +30,7 @@ module SearchEngine
|
|
|
30
30
|
FRAMES = %w[⠋ ⠙ ⠹ ⠸ ⠼ ⠴ ⠦ ⠧ ⠇ ⠏].freeze
|
|
31
31
|
INTERVAL = 0.1 # seconds per render tick
|
|
32
32
|
BAR_WIDTH = 20
|
|
33
|
+
VIEWPORT_MARGIN = 3
|
|
33
34
|
|
|
34
35
|
# @param labels [Array<String>] display label for each slot (partition key)
|
|
35
36
|
# @param partitions [Array, nil] raw partition values for non-TTY output (defaults to labels)
|
|
@@ -48,6 +49,7 @@ module SearchEngine
|
|
|
48
49
|
@slots = labels.each_with_index.map do |label, idx|
|
|
49
50
|
Slot.new(label: label, partition: raw[idx], estimate: per_partition_estimate, on_done: nontty_cb)
|
|
50
51
|
end
|
|
52
|
+
@viewport = resolve_viewport
|
|
51
53
|
end
|
|
52
54
|
|
|
53
55
|
# Start the background render thread. Hides the cursor on TTY.
|
|
@@ -107,7 +109,7 @@ module SearchEngine
|
|
|
107
109
|
@stop_signal.wait(@mutex, INTERVAL)
|
|
108
110
|
break unless @running
|
|
109
111
|
|
|
110
|
-
@slots.map { |slot| slot.render(frame_idx) }
|
|
112
|
+
compact? ? build_viewport_lines(frame_idx) : @slots.map { |slot| slot.render(frame_idx) }
|
|
111
113
|
end
|
|
112
114
|
break if lines.nil?
|
|
113
115
|
|
|
@@ -128,11 +130,81 @@ module SearchEngine
|
|
|
128
130
|
def render_final_frame
|
|
129
131
|
return if @slots.empty?
|
|
130
132
|
|
|
131
|
-
@io.write("\e[#{@slots.size}A") if @rendered_once
|
|
133
|
+
@io.write("\e[#{compact? ? @viewport : @slots.size}A") if @rendered_once
|
|
132
134
|
@slots.each { |slot| @io.write("\r\e[K#{slot.render_final}\n") }
|
|
133
135
|
@io.flush
|
|
134
136
|
end
|
|
135
137
|
|
|
138
|
+
def resolve_viewport
|
|
139
|
+
return @slots.size unless @tty
|
|
140
|
+
|
|
141
|
+
max = terminal_height - VIEWPORT_MARGIN
|
|
142
|
+
return @slots.size if max < 1 || @slots.size <= max
|
|
143
|
+
|
|
144
|
+
max
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def terminal_height
|
|
148
|
+
require 'io/console'
|
|
149
|
+
IO.console&.winsize&.first || 24
|
|
150
|
+
rescue StandardError
|
|
151
|
+
24
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def compact?
|
|
155
|
+
@viewport < @slots.size
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
# Build a fixed-size frame showing a summary header, active slots, and
|
|
159
|
+
# recent completions — capped to @viewport lines so cursor-up stays
|
|
160
|
+
# within terminal bounds.
|
|
161
|
+
def build_viewport_lines(frame_idx)
|
|
162
|
+
available = @viewport - 1
|
|
163
|
+
lines = [viewport_header]
|
|
164
|
+
|
|
165
|
+
active = []
|
|
166
|
+
done = []
|
|
167
|
+
@slots.each do |slot|
|
|
168
|
+
case slot.state
|
|
169
|
+
when :in_progress then active << slot
|
|
170
|
+
when :done, :error then done << slot
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
shown_active = active.first(available)
|
|
175
|
+
shown_active.each { |s| lines << s.render(frame_idx) }
|
|
176
|
+
available -= shown_active.size
|
|
177
|
+
|
|
178
|
+
if available.positive?
|
|
179
|
+
shown_done = done.last(available)
|
|
180
|
+
shown_done.each { |s| lines << s.render_final }
|
|
181
|
+
available -= shown_done.size
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
available.times { lines << '' }
|
|
185
|
+
lines
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def viewport_header
|
|
189
|
+
done_count = 0
|
|
190
|
+
active_count = 0
|
|
191
|
+
error_count = 0
|
|
192
|
+
@slots.each do |s|
|
|
193
|
+
case s.state
|
|
194
|
+
when :done then done_count += 1
|
|
195
|
+
when :error then error_count += 1
|
|
196
|
+
when :in_progress then active_count += 1
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
pending_count = @slots.size - done_count - error_count - active_count
|
|
200
|
+
|
|
201
|
+
parts = +" #{done_count}/#{@slots.size} done"
|
|
202
|
+
parts << " | #{active_count} active" if active_count.positive?
|
|
203
|
+
parts << " | #{pending_count} pending" if pending_count.positive?
|
|
204
|
+
parts << " | #{Color.apply("#{error_count} failed", :red)}" if error_count.positive?
|
|
205
|
+
parts
|
|
206
|
+
end
|
|
207
|
+
|
|
136
208
|
def flush_nontty_slot(slot)
|
|
137
209
|
@mutex.synchronize do
|
|
138
210
|
return if slot.flushed?
|