Coder Social home page Coder Social logo

trailblazer-activity-dsl-linear's Introduction

Trailblazer

Battle-tested Ruby framework to help structuring your business logic.

Gem Version

What's Trailblazer?

Trailblazer introduces new abstraction layers into Ruby applications to help you structure your business logic.

It ships with our canonical "service object" implementation called operation, many conventions, gems for testing, Rails support, optional form objects and much more.

Should I use Trailblazer?

Give us a chance if you say "yes" to this!

  • You hate messy controller code but don't know where to put it?
  • Moving business code into the "fat model" gives you nightmares?
  • "Service objects" are great?
  • Anyhow, you're tired of 12 different "service object" implementations throughout your app?
  • You keep asking for additional layers such as forms, policies, decorators?

Yes? Then we got a well-seasoned framework for you: Trailblazer.

Here are the main concepts.

Operation

The operation encapsulates business logic and is the heart of the Trailblazer architecture.

An operation is not just a monolithic replacement for your business code. It's a simple orchestrator between the form objects, models, your business code and all other layers needed to get the job done.

# app/concepts/song/operation/create.rb
module Song::Operation
  class Create < Trailblazer::Operation
    step :create_model
    step :validate
    left :handle_errors
    step :notify

    def create_model(ctx, **)
      # do whatever you feel like.
      ctx[:model] = Song.new
    end

    def validate(ctx, params:, **)
      # ..
    end
    # ...
  end
end

The step DSL takes away the pain of flow control and error handling. You focus on what happens: creating models, validating data, sending out notifications.

Control flow

The operation takes care when things happen: the flow control. Internally, this works as depicted in this beautiful diagram.

Flow diagram of a typical operation.

The best part: the only way to invoke this operation is Operation.call. The single entry-point saves programmers from shenanigans with instances and internal state - it's proven to be an almost bullet-proof concept in the past 10 years.

result = Song::Operation::Create.(params: {title: "Hear Us Out", band: "Rancid"})

result.success? #=> true
result[:model]  #=> #<Song title="Hear Us Out" ...>

Data, computed values, statuses or models from within the operation run are exposed through the result object.

Operations can be nested, use composition and inheritance patterns, provide variable mapping around each step, support dependency injection, and save you from reinventing the wheel - over and over, again.

Leveraging those functional mechanics, operations encourage a high degree of encapsulation while giving you all the conventions and tools for free (except for a bit of a learning curve).

Tracing

In the past years, we learnt from some old mistakes and improved developer experience. As a starter, check out our built-in tracing!

result = Song::Operation::Create.wtf?(params: {title: "", band: "Rancid"})

Tracing the internal flow of an operation.

Within a second you know which step failed - a thing that might seem trivial, but when things grow and a deeply nested step in an iteration fails, you will start loving #wtf?! It has saved us days of debugging.

We even provide a visual debugger to inspect traces on the webs.

There's a lot more

All our abstraction layers such as operations, form objects, view components, test gems and much more are used in hundreds of OSS projects and commercial applications in the Ruby world.

We provide a visual debugger, a BPMN editor for long-running business processes, thorough documentation and a growing list of onboarding videos (TRAILBLAZER TALES).

Trailblazer is both used for refactoring legacy apps (we support Ruby 2.5+) and helps big teams organizing, structuring and debugging modern, growing (Rails) applications.

Documentation

Make sure to check out the new beginner's guide to learning Trailblazer. The new book discusses all aspects in a step-wise approach you need to understand Trailblazer's mechanics and design ideas.

The new begginer's guide.

trailblazer-activity-dsl-linear's People

Contributors

apotonick avatar emaglio avatar kamilmilewski avatar mcrip avatar richardboehme avatar seuros avatar yogeshjain999 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

trailblazer-activity-dsl-linear's Issues

`Path()` doesn't preprend its `End()` to `End.success`

Usually, termini are added with append: End.success, however, with the "hack" that Path uses to insert itself into Sequence, this doesn't apply, causing Path() termini to sit much higher in the sequence, e.g.

Start
step a
step b (has a Path output)
path end (should be lower, here * !)
step c
End.success
*

Inserting step into a Path() with `:after` doesn't work

The following code fails because the last step of the "original" Path() is hard-codedly pointing to its end.

step :a, Output(:not_authenticated)  => Path(track_color: :_401, connect_to: Id("End.fail_fast")) do       
  step :_401_pointing_to_end
end

step :_401____, after: :_401_pointing_to_end, # :before works! 
  magnetic_to: :_401, Output(:success) => Track(:_401), Output(:failure) => Track(:_401)

Warn when wiring a track that is not existing

Given that the :skip track doesn't exist, this will be wired to :success.

step :_destroy?,
              Output(:success) => Track(:skip)

We need the ability to reference a track before it "got created" due to the way Ruby and DSLs (usually) work. However, if we only somehow could warn the user they're referencing a track that's nonexistent, that'd be cool. I wouldn't know how, though, unless we switch to a block-style DSL where we know when exactly a DSL use is finished and can "finalize" the data structure created from it.

Variable mapping: Allow In(:strict)

When using In() => {:model => :internal_name} there's no implicit check if ctx[:model] was actually set for the incoming ctx.

Maybe a strict mode like

In(strict: true) => {:model => :internal_name}

would make :model a required keyword in the automatically created filter proc (although I don't know how to do this without meta-programming :brrrr:).

Introduce Strategy#patch

Instead of having to use step Subprocess(...., patch: ...) while repeating or manually inheriting options, it'd be much cooler to have a #patch method for this.

step Subprocess(Property,
          patch: -> { pass :default_for_populator, id: :default_for_populator, replace: :default_for_populator }
        ), id: "options", replace: "options" , inherit: [:variable_mapping]

# becomes


patch ["options"],
  -> { pass :default_for_populator, id: :default_for_populator, replace: :default_for_populator }

Variable mapping: implement `Outject()`

Even though this is not an English word, Outject() would be nice to have, basically exposing the following behavior:

Activity::Railway.Out() => ->(ctx, **) { ctx.key?(:model) ? {model: ctx[:model]} : {} }

Ruby 2.7 -> warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call

Hi guys,

I know it's warnings, but it's disturbing a lot... Any action for that (Rails 6.0.3.2)?

/usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/path.rb:124: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call /usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/path.rb:127: warning: The called method append_end_options' is defined here
/usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/path.rb:183: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call
/usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/dsl/linear/state.rb:16: warning: The called method initialize' is defined here /usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/railway.rb:138: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call /usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/path.rb:154: warning: The called method OptionsForState' is defined here
/usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/railway.rb:164: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call
/usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/dsl/linear/state.rb:16: warning: The called method initialize' is defined here /usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/fast_track.rb:135: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call /usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/railway.rb:137: warning: The called method OptionsForState' is defined here
/usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/fast_track.rb:160: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call
/usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/dsl/linear/state.rb:16: warning: The called method initialize' is defined here /usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/fast_track.rb:5: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call /usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/fast_track.rb:134: warning: The called method OptionsForState' is defined here
/usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/fast_track.rb:5: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call
/usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/dsl/linear/state.rb:16: warning: The called method initialize' is defined here [Declarative] Defaults#merge! and #call still accept arrays and automatically prepend those. This is now deprecated, you should replace arywithDeclarative::Variables::Append(ary). /usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/dsl/linear/state.rb:33: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call /usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/dsl/linear/strategy.rb:30: warning: The called method false' is defined here
/usr/local/bundle/gems/trailblazer-activity-0.10.1/lib/trailblazer/activity/circuit.rb:45: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call
/usr/local/bundle/gems/trailblazer-activity-0.10.1/lib/trailblazer/activity/circuit.rb:27: warning: The called method call' is defined here /usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/dsl/linear/strategy.rb:34: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call /usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/dsl/linear.rb:175: warning: The called method apply_adds_from_dsl' is defined here
/usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/dsl/linear.rb:177: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call
/usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/dsl/linear.rb:15: warning: The called method create_row' is defined here /usr/local/bundle/gems/active_hash-3.1.0/lib/associations/associations.rb:22: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call /usr/local/bundle/gems/activerecord-6.0.3.2/lib/active_record/associations.rb:1657: warning: The called method belongs_to' is defined here
/usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/railway.rb:170: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call
/usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/railway.rb:137: warning: The called method OptionsForState' is defined here /usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/railway.rb:170: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call /usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/dsl/linear/state.rb:16: warning: The called method initialize' is defined here
/usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/dsl/linear/normalizer.rb:194: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call
/usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/dsl/linear.rb:15: warning: The called method create_row' is defined here /usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/path.rb:124: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call /usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/path.rb:127: warning: The called method append_end_options' is defined here
/usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/path.rb:183: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call
/usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/dsl/linear/state.rb:16: warning: The called method initialize' is defined here /usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/railway.rb:138: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call /usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/path.rb:154: warning: The called method OptionsForState' is defined here
/usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/railway.rb:164: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call
/usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/dsl/linear/state.rb:16: warning: The called method initialize' is defined here /usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/fast_track.rb:135: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call /usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/railway.rb:137: warning: The called method OptionsForState' is defined here
/usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/fast_track.rb:160: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call
/usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/dsl/linear/state.rb:16: warning: The called method initialize' is defined here /usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/fast_track.rb:5: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call /usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/fast_track.rb:134: warning: The called method OptionsForState' is defined here
/usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/fast_track.rb:5: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call
/usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/dsl/linear/state.rb:16: warning: The called method initialize' is defined here [Declarative] Defaults#merge! and #call still accept arrays and automatically prepend those. This is now deprecated, you should replace arywithDeclarative::Variables::Append(ary). /usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/dsl/linear/state.rb:33: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call /usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/dsl/linear/strategy.rb:30: warning: The called method false' is defined here
/usr/local/bundle/gems/trailblazer-activity-0.10.1/lib/trailblazer/activity/circuit.rb:45: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call
/usr/local/bundle/gems/trailblazer-activity-0.10.1/lib/trailblazer/activity/circuit.rb:27: warning: The called method call' is defined here /usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/dsl/linear/strategy.rb:34: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call /usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/dsl/linear.rb:175: warning: The called method apply_adds_from_dsl' is defined here
/usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/dsl/linear.rb:177: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call
/usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/dsl/linear.rb:15: warning: The called method create_row' is defined here /usr/local/bundle/gems/active_hash-3.1.0/lib/associations/associations.rb:22: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call /usr/local/bundle/gems/activerecord-6.0.3.2/lib/active_record/associations.rb:1657: warning: The called method belongs_to' is defined here
/usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/railway.rb:170: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call
/usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/railway.rb:137: warning: The called method OptionsForState' is defined here /usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/railway.rb:170: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call /usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/dsl/linear/state.rb:16: warning: The called method initialize' is defined here
/usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/dsl/linear/normalizer.rb:194: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call
/usr/local/bundle/gems/trailblazer-activity-dsl-linear-0.2.8/lib/trailblazer/activity/dsl/linear.rb:15: warning: The called method create_row' is defined here

wrap_static grows with :replace

If you'd call a million times step ..., replace: :a, and add something to its static wrap via :extensions, the internal config[:wrap_static] field would grow, too.

Not sure this needs to be addressed urgently, though.

Improve cryptic exception

When using Subprocess with an object that exposes to_hash an exception is thrown.

NoMethodError: undefined method `collect' for nil:NilClass
    /home/nick/.rvm/gems/ruby-2.5.0/gems/trailblazer-activity-dsl-linear-0.3.4/lib/trailblazer/activity/dsl/linear/helper.rb:102:in `Subprocess'

change :id with :replace

replace: :advance, id: :new_name, inherit: true

I want to replace the original :advance step with a new :new_name step. It is not possible to rename the element using :id.

Allow Subprocess() with macro hash

It would be great to be able to chugg an options hash (e.g. from a macro) into Subprocess().

options = {task: ..., ....}
step Subprocess(**options)

Variable mapping: In() variable cannot override Inject()

Often, macros may have injections set

Macro
  step :params, Inject() => [:params]

When using this macro, and adding In() we cannot override :params, it will always use inject as it is being executed later.

step Macro, In() => ->{ |ctx, **| {params: {id: 1}}  } # this will not win 

As Inject() => [:params] is being executed after the In() filter, the original params will always be used in the macro.

Feature: Speed up compilation with `finalize!`

We could avoid having to compile the activity with every invocation of step by "marking" the activity as final in the end, which then could trigger compilation (and much better error handling).

class Create < Trailblazer::Operation(finalize: true)
  step :a
  step :b
end.finalize!

When using an extendable loader such as dry-system (or maybe even zeitwerk supports that?) you could add a "loaded" callback that calls activity_class.finalize! automatically.

Receiving a RuntimeError in the face of Rails' reloading

(This may not be the correct repository for this issue, but this is where the code that's throwing the error lives)

I'm using these gems:

$ bundle show | grep trailblazer
  * trailblazer (2.1.0.rc1)
  * trailblazer-activity (0.8.2)
  * trailblazer-activity-dsl-linear (0.1.5)
  * trailblazer-cells (0.0.3)
  * trailblazer-context (0.1.2)
  * trailblazer-loader (0.1.2)
  * trailblazer-macro (2.1.0.rc11)
  * trailblazer-macro-contract (2.1.0.rc11)
  * trailblazer-operation (0.5.1)
  * trailblazer-rails (2.1.7)

I've got this (toy!) operation:

module Argh
  class Alpha < Trailblazer::Operation
    pass :step_alpha
    def step_alpha(ctx, **); end
  end
end

…and Things Go Wrong in the face of Rails' code reloading.
Here's a copy of the output from the rails console, but I can also see this backtrace in a browser pointed at rails s running in the development environment:

$ rails c
Loading development environment (Rails 5.2.3)
irb(main):001:0> reload!
Reloading...
Traceback (most recent call last):
       16: from app/concepts/argh/operation/alpha.rb:1:in `<main>'
       15: from app/concepts/argh/operation/alpha.rb:3:in `<module:Argh>'
       14: from app/concepts/argh/operation/alpha.rb:5:in `<class:Alpha>'
       13: from trailblazer-activity-dsl-linear (0.1.5) lib/trailblazer/activity/fast_track.rb:153:in `pass'
       12: from trailblazer-activity-dsl-linear (0.1.5) lib/trailblazer/activity/dsl/linear/strategy.rb:48:in `recompile_activity_for'
       11: from trailblazer-activity-dsl-linear (0.1.5) lib/trailblazer/activity/railway.rb:125:in `pass'
       10: from trailblazer-activity-dsl-linear (0.1.5) lib/trailblazer/activity/dsl/linear/strategy.rb:32:in `task_for!'
        9: from trailblazer-activity-dsl-linear (0.1.5) lib/trailblazer/activity/dsl/linear/state.rb:25:in `update_sequence'
        8: from trailblazer-activity-dsl-linear (0.1.5) lib/trailblazer/activity/dsl/linear/strategy.rb:34:in `block in task_for!'
        7: from trailblazer-activity-dsl-linear (0.1.5) lib/trailblazer/activity/dsl/linear/state.rb:49:in `call'
        6: from trailblazer-activity (0.8.2) lib/trailblazer/activity/circuit.rb:44:in `call'
        5: from trailblazer-activity (0.8.2) lib/trailblazer/activity/circuit.rb:44:in `loop'
        4: from trailblazer-activity (0.8.2) lib/trailblazer/activity/circuit.rb:45:in `block in call'
        3: from trailblazer-activity (0.8.2) lib/trailblazer/activity/circuit.rb:27:in `block in <class:Circuit>'
        2: from trailblazer-activity (0.8.2) lib/trailblazer/activity/circuit.rb:27:in `call'
        1: from trailblazer-activity-dsl-linear (0.1.5) lib/trailblazer/activity/path.rb:88:in `raise_on_duplicate_id'
RuntimeError (ID step_alpha is already taken. Please specify an `:id`.)

As you might expect, changing the code to

pass :step_alpha, id: 'whatever'

just gives:

RuntimeError (ID whatever is already taken. Please specify an `:id`.)

after a reload!.


If it's any help, I've recently updated all of the Trailblazer gems in my project, and this behaviour didn't occur with this set:

$ bundle show | grep trailblazer
  * trailblazer (2.1.0.rc1)
  * trailblazer-activity (0.7.1)
  * trailblazer-cells (0.0.3)
  * trailblazer-context (0.1.2)
  * trailblazer-loader (0.1.2)
  * trailblazer-macro (2.1.0.rc1)
  * trailblazer-macro-contract (2.1.0.rc1)
  * trailblazer-operation (0.4.1)
  * trailblazer-rails (2.1.7)

Warn when referencing nonexistent Track()

Given that the :skip track doesn't exist, this will be wired to :success.

step :_destroy?,
              Output(:success) => Track(:skip)

We need the ability to reference a track before it "got created" due to the way Ruby and DSLs (usually) work. However, if we only somehow could warn the user they're referencing a track that's nonexistent, that'd be cool. I wouldn't know how, though, unless we switch to a block-style DSL where we know when exactly a DSL use is finished and can "finalize" the data structure created from it.

`Strategy.invoke` accepts wrong argument set

This works correctly.

Trailblazer::Pro::Generate.invoke([{json_document: collaboration_json}, {}])

This "works", but breaks in VariableMapping .

Trailblazer::Pro::Generate.invoke([{json_document: collaboration_json}])

The latter version should either default flow_options to an empty hash, or break right away.

Returning false in Path step

When using Activity::Path returning false from a step will result in the OP crashing.

We need to wire failure outputs to success per default.

Better way to add Ends

Currently, you need to do this

@state.update_sequence do |sequence:, **|
        sequence = Activity::Path::DSL.append_end(sequence, task: Failure.new(semantic: :not_found), magnetic_to: :not_found, id: "End.not_found")


        recompile_activity!(sequence)

        sequence
      end

Alble to use the same method on different tracks

Scenario:

  • using dry-validation and dry-struct to validate and render a form

Activity example:

class MyActivity < Trailblazer::Activity::Railway
  def self.model(ctx, id:, account:, **)
    ctx[:model] = account.model
  end

  def self.form(ctx, contract:, attributes:, **)
    ctx[:form] =FormObject.new(contract.output.merge(...))
  end

  def self.set_model_attributes(ctx, form:, **)
    ctx[:model_attributes] = {....}
  end

  def self.update(ctx, model:, model_attributes:, **)
    model.update(model_attributes)
  end

  step Input::Validate(constant: Schema, key: :attributes)
  step method(:model)
  step method(:form)
  pass method(:set_model_attributes)
  step method(:update)
  fail method(:form)
end

Input::Validate set the results for the Schema.call() in ctx[:contract] which needs to build a form object after that validation step either when validation fails or passes, thefore we call form in both step and fail.

At the moment this fails even though validation passes because the Activity calls the fail :form instead of step :form (if I use the same code but using 2 different methods it works as expected)

Increase compile performance by removing Intermediate/Implementation

Currently, every time you call #step the entire Sequence is recompiled into Intermediate and Implementation, and then passed to Activity::Schema::Compiler.

If Activity::Schema had a simplified build interface that receives something that's almost a Circuit plus the required data such as start_task, we could throw away a lot of code in dsl, speed up compilation by probably factor 2-3 and move Intermediate code to trailblazer-workflow, as that's why this intermediate layer got invented for.

Once this is done, move old "snippet/activity/low_level" docs to wherever this layer ends up.

Cryptic exception for inherit: true

When using replace: :a, inherit: true, given that :a is non-existent, the error message is hard to debug.

TypeError: no implicit conversion from nil to integer
    /home/nick/.rvm/gems/ruby-2.5.0/gems/trailblazer-activity-dsl-linear-0.3.2/lib/trailblazer/activity/dsl/linear/normalizer.rb:247:in `[]'
    /home/nick/.rvm/gems/ruby-2.5.0/gems/trailblazer-activity-dsl-linear-0.3.2/lib/trailblazer/activity/dsl/linear/normalizer.rb:247:in `inherit_option'

Variable mapping: shortcut for In()

Maybe we could extend In() and Out(), so instead of

step Policy::Pundit(MyPolicy, :create?),
     In() => {:repository => :model}, In() => [:current_user]

you could write the short-hand version

step Policy::Pundit(MyPolicy, :create?),
     In() => [:current_user, :repository => :model]

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.