Class: Inquirex::Definition

Inherits:
Object
  • Object
show all
Defined in:
lib/inquirex/definition.rb

Overview

Immutable, versionable flow graph. Maps step ids to Node objects and defines the entry point. Carries optional metadata (id, version, title, subtitle, brand) for the JS widget. Supports JSON round-trip serialization; lambdas are stripped on serialization.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(start_step_id:, nodes:, id: nil, version: "1.0.0", meta: {}, accumulators: {}) ⇒ Definition

Returns a new instance of Definition.

Parameters:

  • start_step_id (Symbol)

    id of the initial step

  • nodes (Hash<Symbol, Node>)

    all steps keyed by id

  • id (String, nil) (defaults to: nil)

    flow identifier

  • version (String) (defaults to: "1.0.0")

    semver

  • meta (Hash) (defaults to: {})

    frontend metadata

  • accumulators (Hash<Symbol, Accumulator>) (defaults to: {})

    named running totals

Raises:



25
26
27
28
29
30
31
32
33
34
# File 'lib/inquirex/definition.rb', line 25

def initialize(start_step_id:, nodes:, id: nil, version: "1.0.0", meta: {}, accumulators: {})
  @id = id
  @version = version
  @meta = meta.freeze
  @start_step_id = start_step_id.to_sym
  @steps = nodes.freeze
  @accumulators = accumulators.freeze
  validate!
  freeze
end

Instance Attribute Details

#accumulatorsObject (readonly)

Returns the value of attribute accumulators.



16
17
18
# File 'lib/inquirex/definition.rb', line 16

def accumulators
  @accumulators
end

#idString? (readonly)

flow identifier (e.g. “tax-intake-2025”)

Returns:

  • (String, nil)

    the current value of id



15
16
17
# File 'lib/inquirex/definition.rb', line 15

def id
  @id
end

#metaHash (readonly)

title, subtitle, brand info for the frontend

Returns:

  • (Hash)

    the current value of meta



15
16
17
# File 'lib/inquirex/definition.rb', line 15

def meta
  @meta
end

#start_step_idSymbol (readonly)

id of the first step in the flow

Returns:

  • (Symbol)

    the current value of start_step_id



15
16
17
# File 'lib/inquirex/definition.rb', line 15

def start_step_id
  @start_step_id
end

#stepsHash<Symbol, Node> (readonly)

frozen map of step id => node

Returns:

  • (Hash<Symbol, Node>)

    the current value of steps



15
16
17
# File 'lib/inquirex/definition.rb', line 15

def steps
  @steps
end

#versionString (readonly)

semver string (default: “1.0.0”)

Returns:

  • (String)

    the current value of version



15
16
17
# File 'lib/inquirex/definition.rb', line 15

def version
  @version
end

Class Method Details

.from_h(hash) ⇒ Definition

Deserializes a Definition from a plain Hash.

Parameters:

  • hash (Hash)

    definition attributes (string or symbol keys)

Returns:



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/inquirex/definition.rb', line 93

def self.from_h(hash)
  id = hash["id"] || hash[:id]
  version = hash["version"] || hash[:version] || "1.0.0"
  meta = hash["meta"] || hash[:meta] || {}
  start = hash["start"] || hash[:start]
  steps_data = hash["steps"] || hash[:steps] || {}
  acc_data = hash["accumulators"] || hash[:accumulators] || {}

  nodes = steps_data.each_with_object({}) do |(step_id, step_hash), acc|
    sym_id = step_id.to_sym
    acc[sym_id] = Node.from_h(sym_id, step_hash)
  end

  accumulators = acc_data.each_with_object({}) do |(name, entry), h|
    sym = name.to_sym
    h[sym] = Accumulator.from_h(sym, entry)
  end

  new(start_step_id: start, nodes:, id:, version:, meta:, accumulators:)
end

.from_json(json) ⇒ Definition

Deserializes a Definition from a JSON string.

Parameters:

  • json (String)

    JSON representation

Returns:



83
84
85
86
87
# File 'lib/inquirex/definition.rb', line 83

def self.from_json(json)
  from_h(JSON.parse(json))
rescue JSON::ParserError => e
  raise Errors::SerializationError, "Invalid JSON: #{e.message}"
end

Instance Method Details

#start_stepNode

Returns the node for the start step.

Returns:

  • (Node)

    the node for the start step



37
38
39
# File 'lib/inquirex/definition.rb', line 37

def start_step
  step(@start_step_id)
end

#step(id) ⇒ Node

Returns the node for that step.

Parameters:

  • id (Symbol)

    step id

Returns:

  • (Node)

    the node for that step

Raises:



44
45
46
# File 'lib/inquirex/definition.rb', line 44

def step(id)
  @steps.fetch(id.to_sym) { raise Errors::UnknownStepError, "Unknown step: #{id.inspect}" }
end

#step_idsArray<Symbol>

Returns all step ids.

Returns:

  • (Array<Symbol>)

    all step ids



49
50
51
# File 'lib/inquirex/definition.rb', line 49

def step_ids
  @steps.keys
end

#to_hHash

Serializes to a plain Hash.

Returns:

  • (Hash)


64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/inquirex/definition.rb', line 64

def to_h
  hash = {}
  hash["id"] = @id if @id
  hash["version"] = @version
  hash["meta"] = @meta unless @meta.empty?
  hash["start"] = @start_step_id.to_s
  unless @accumulators.empty?
    hash["accumulators"] = @accumulators.each_with_object({}) do |(name, acc), h|
      h[name.to_s] = acc.to_h
    end
  end
  hash["steps"] = @steps.transform_keys(&:to_s).transform_values(&:to_h)
  hash
end

#to_jsonString

Serializes the definition to a JSON string. Lambdas (default procs, compute blocks) are silently stripped.

Returns:

  • (String)

    JSON representation



57
58
59
# File 'lib/inquirex/definition.rb', line 57

def to_json(*)
  JSON.generate(to_h)
end