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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 933b8b58a98c81e8e6b72f3083cfcf2ee1de5ea9f709d4c10aea5d09dba59d99
4
- data.tar.gz: 626111c57bc0ee533d21938d7a218c13b80cc23aa27827731994a968f97de672
3
+ metadata.gz: 685951054b6b65954ff6517a08176c8bec124c197980dec5fcfc0ebbd19f6691
4
+ data.tar.gz: 12e290d5e45325cb031b06f87d158b33300fdc8682d3a417ba7191940e35211e
5
5
  SHA512:
6
- metadata.gz: 3e4456f56ddd18865793f0d61890967ba53e50eac9d2b573362800ed0f509aad397bc9233b4f4a0d308e5a9dadfc0a0aac9e9ca946516b638f5eee0a4728fa3b
7
- data.tar.gz: 80133e73075e0047968ed9afb3d7756eb5cf47aadeb1c1bbb73d332ee2d44c61e0cc6e6fb5b8932f23ab280f8259319c36d16c288e7d3817a0fdc3844fcde24a
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?
@@ -3,5 +3,5 @@
3
3
  module SearchEngine
4
4
  # Current gem version.
5
5
  # @return [String]
6
- VERSION = '30.1.6.5'
6
+ VERSION = '30.1.6.6'
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: search-engine-for-typesense
3
3
  version: !ruby/object:Gem::Version
4
- version: 30.1.6.5
4
+ version: 30.1.6.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nikita Shkoda