module Trailblazer::Activity::Path::DSL

Functions that help creating a path-specific sequence.

Constants

Linear
Normalizers

This is slow and should be done only once at compile-time, DISCUSS: maybe make this a function? These are the normalizers for an {Activity}, to be injected into a State.

Public Class Methods

OptionsForState(normalizers: Normalizers, track_name: :success, end_task: Activity::End.new(semantic: :success), end_id: "End.success", **options) click to toggle source

pp Normalizers

# File lib/trailblazer/activity/path.rb, line 169
def self.OptionsForState(normalizers: Normalizers, track_name: :success, end_task: Activity::End.new(semantic: :success), end_id: "End.success", **options)
  initial_sequence = Path::DSL.initial_sequence(track_name: track_name, end_task: end_task, end_id: end_id) # DISCUSS: the standard initial_seq could be cached.

  {
    normalizers:      normalizers,
    initial_sequence: initial_sequence,

    track_name:             track_name,
    end_id:                 end_id,
    step_interface_builder: Activity::TaskBuilder.method(:Binary), # DISCUSS: this is currently the only option we want to pass on in Path() ?
    adds:                   [],
    **options
  }
end

Public Instance Methods

append_end(sequence, **options) click to toggle source
# File lib/trailblazer/activity/path.rb, line 138
def append_end(sequence, **options)
  sequence = Linear::DSL.insert_task(sequence, **append_end_options(**options))
end
append_end_options(task:, magnetic_to:, id:, append_to: "End.success") click to toggle source
# File lib/trailblazer/activity/path.rb, line 142
def append_end_options(task:, magnetic_to:, id:, append_to: "End.success")
  end_args = {sequence_insert: [Linear::Insert.method(:Append), append_to], stop_event: true}

  {
    task:         task,
    magnetic_to:  magnetic_to,
    id:           id,
    wirings:      [
      Linear::Search::Noop(
        Activity::Output.new(task, task.to_h[:semantic]), # DISCUSS: do we really want to transport the semantic "in" the object?
        # magnetic_to
      )],
    # outputs:      {magnetic_to => },
    # connections:  {magnetic_to => [Linear::Search.method(:Noop)]},
    **end_args
   }
end
clone_duplicate_activity((ctx, flow_options), *) click to toggle source
# File lib/trailblazer/activity/path.rb, line 100
def clone_duplicate_activity((ctx, flow_options), *)
  return Right, [ctx, flow_options] unless ctx[:task].is_a?(Class)

  task, sequence = ctx[:task], ctx[:sequence]
  ctx = ctx.merge(task: task.clone) if sequence.find { |row| row[1] == task }

  return Right, [ctx, flow_options]
end
initial_sequence(track_name:, end_task:, end_id:) click to toggle source

Returns an initial two-step sequence with {Start.default > End.success}.

# File lib/trailblazer/activity/path.rb, line 132
def initial_sequence(track_name:, end_task:, end_id:)
  # TODO: this could be an Activity itself but maybe a bit too much for now.
  sequence = start_sequence(track_name: track_name)
  sequence = append_end(sequence, task: end_task, magnetic_to: track_name, id: end_id, append_to: "Start.default")
end
merge_path_connections((ctx, flow_options), *) click to toggle source
# File lib/trailblazer/activity/path.rb, line 52
def merge_path_connections((ctx, flow_options), *)
  raise unless track_name = ctx[:track_name]# TODO: make track_name required kw.
  ctx = {connections: unary_connections(track_name: track_name)}.merge(ctx)

  return Right, [ctx, flow_options]
end
merge_path_outputs((ctx, flow_options), *) click to toggle source
# File lib/trailblazer/activity/path.rb, line 46
def merge_path_outputs((ctx, flow_options), *)
  ctx = {outputs: unary_outputs}.merge(ctx)

  return Right, [ctx, flow_options]
end
normalize_duplications((ctx, flow_options), *) click to toggle source
# File lib/trailblazer/activity/path.rb, line 84
def normalize_duplications((ctx, flow_options), *)
  return Right, [ctx, flow_options] if ctx[:replace]

  signal, (ctx, flow_options) = raise_on_duplicate_id([ctx, flow_options])
  signal, (ctx, flow_options) = clone_duplicate_activity([ctx, flow_options])

  return signal, [ctx, flow_options]
end
normalize_magnetic_to((ctx, flow_options), *) click to toggle source
# File lib/trailblazer/activity/path.rb, line 109
def normalize_magnetic_to((ctx, flow_options), *) # TODO: merge with Railway.merge_magnetic_to
  raise unless track_name = ctx[:track_name]# TODO: make track_name required kw.

  ctx = {magnetic_to: track_name}.merge(ctx)

  return Right, [ctx, flow_options]
end
normalize_sequence_insert((ctx, flow_options), *) click to toggle source

Processes {:before,:after,:replace,:delete} options and defaults to {before: “End.success”} which, yeah.

# File lib/trailblazer/activity/path.rb, line 61
def normalize_sequence_insert((ctx, flow_options), *)
  insertion = ctx.keys & sequence_insert_options.keys
  insertion = insertion[0]   || :before
  raise if ctx[:end_id].nil? # FIXME
  target    = ctx[insertion] || ctx[:end_id]

  insertion_method = sequence_insert_options[insertion]

  ctx = ctx.merge(sequence_insert: [Linear::Insert.method(insertion_method), target])

  return Right, [ctx, flow_options]
end
normalizer() click to toggle source
# File lib/trailblazer/activity/path.rb, line 11
def normalizer
  prepend_step_options(
    initial_sequence(track_name: :success, end_task: Activity::End.new(semantic: :success), end_id: "End.success")
  )
end
prepend_step_options(sequence) click to toggle source

Return {Path::Normalizer} sequence.

# File lib/trailblazer/activity/path.rb, line 118
def prepend_step_options(sequence)
  prepend_to_path(
    sequence,

    "path.outputs"                => method(:merge_path_outputs),
    "path.connections"            => method(:merge_path_connections),
    "path.sequence_insert"        => method(:normalize_sequence_insert),
    "path.normalize_duplications" => method(:normalize_duplications),
    "path.magnetic_to"            => method(:normalize_magnetic_to),
    "path.wirings"                => Linear::Normalizer.method(:compile_wirings),
  )
end
prepend_to_path(sequence, steps, insertion_method=Linear::Insert.method(:Prepend), insert_id="End.success") click to toggle source

DISCUSS: still not sure this should sit here. Pseudo-DSL that prepends {steps} to {sequence}.

# File lib/trailblazer/activity/path.rb, line 25
def prepend_to_path(sequence, steps, insertion_method=Linear::Insert.method(:Prepend), insert_id="End.success")
  new_rows = steps.collect do |id, task|
    Linear::Sequence.create_row(
      task:         task,
      magnetic_to:  :success,
      wirings:      [Linear::Search::Forward(unary_outputs[:success], :success)],
      id:           id,
    )
  end

  insertion_method.(sequence, new_rows, insert_id)
end
raise_on_duplicate_id((ctx, flow_options), *) click to toggle source
# File lib/trailblazer/activity/path.rb, line 93
def raise_on_duplicate_id((ctx, flow_options), *)
  id, sequence = ctx[:id], ctx[:sequence]
  raise "ID #{id} is already taken. Please specify an `:id`." if sequence.find { |row| row[3][:id] == id }

  return Right, [ctx, flow_options]
end
sequence_insert_options() click to toggle source

@private

# File lib/trailblazer/activity/path.rb, line 75
def sequence_insert_options
  {
    :before  => :Prepend,
    :after   => :Append,
    :replace => :Replace,
    :delete  => :Delete,
  }
end
start_sequence(track_name:) click to toggle source
# File lib/trailblazer/activity/path.rb, line 17
def start_sequence(track_name:)
  start_default = Activity::Start.new(semantic: :default)
  start_event   = Linear::Sequence.create_row(task: start_default, id: "Start.default", magnetic_to: nil, wirings: [Linear::Search::Forward(unary_outputs[:success], track_name)])
  _sequence      = Linear::Sequence[start_event]
end
unary_connections(track_name: :success) click to toggle source
# File lib/trailblazer/activity/path.rb, line 42
def unary_connections(track_name: :success)
  {success: [Linear::Search.method(:Forward), track_name]}
end
unary_outputs() click to toggle source
# File lib/trailblazer/activity/path.rb, line 38
def unary_outputs
  {success: Activity::Output(Activity::Right, :success)}
end