Class: Textus::Projection

Inherits:
Object
  • Object
show all
Defined in:
lib/textus/projection.rb

Constant Summary collapse

MAX_LIMIT =
1000
REDUCER_TIMEOUT_SECONDS =
2

Instance Method Summary collapse

Constructor Details

#initialize(reader:, spec:, lister:, transform_resolver:, transform_context:) ⇒ Projection

‘reader` — a callable `->(key) { envelope_or_nil }`. Caller picks

semantics: pure read (`ops.reads.get`) for materialization paths;
`ops.reads.get_or_refresh` if you want refresh-on-stale.

‘lister` — a callable `->(prefix:) { [ { “key” => … }, … ] }`. `transform_resolver` — a callable `->(name) { callable_or_raise }`. `transform_context` — `Application::Context` handed to the transform reducer.

Raises:



15
16
17
18
19
20
21
22
23
# File 'lib/textus/projection.rb', line 15

def initialize(reader:, spec:, lister:, transform_resolver:, transform_context:)
  @reader             = reader
  @spec               = spec || {}
  @lister             = lister
  @transform_resolver = transform_resolver
  @transform_context  = transform_context
  @limit = (@spec["limit"] || MAX_LIMIT).to_i
  raise InvalidProjection.new("limit #{@limit} exceeds max #{MAX_LIMIT}") if @limit > MAX_LIMIT
end

Instance Method Details

#runObject



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/textus/projection.rb', line 25

def run
  keys = collect_keys
  explicit_pluck = !@spec["pluck"].nil? && @spec["pluck"] != "*"
  rows = keys.map do |key|
    env = @reader.call(key)
    row = pluck(env.meta, env.body)
    explicit_pluck ? row : row.merge("_key" => key)
  end
  reduced = apply_reducer(rows)
  # Reducers may return either an Array of rows (legacy / templated builds)
  # or a Hash that becomes the structured-format payload base. In the Hash
  # case, downstream sort/limit/position markers don't apply, and the
  # builder owns `_meta.generated_at` so we don't stamp it here.
  return reduced if reduced.is_a?(Hash)

  rows = reduced
  rows = sort(rows)
  rows = rows.first(@limit)
  mark_positions(rows)
  { "entries" => rows, "count" => rows.length, "generated_at" => Time.now.utc.iso8601 }
end