easy_flow 0.16.0 → 0.18.0
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 +4 -4
- data/app/assets/builds/easy_flow/canvas.js +1 -1
- data/app/controllers/easy_flow/flows_controller.rb +18 -4
- data/app/javascript/easy_flow/canvas/Canvas.jsx +1 -0
- data/app/javascript/easy_flow/canvas/Inspector.jsx +3 -1
- data/app/javascript/easy_flow/canvas/Records.jsx +8 -2
- data/app/models/easy_flow/all_or_any.rb +33 -0
- data/app/models/easy_flow/canvas.rb +17 -2
- data/app/models/easy_flow/compare.rb +2 -4
- data/app/models/easy_flow/compare_two_values.rb +32 -0
- data/app/models/easy_flow/completed_at.rb +34 -0
- data/app/models/easy_flow/condition.rb +3 -1
- data/app/models/easy_flow/count.rb +30 -0
- data/app/models/easy_flow/digest.rb +19 -11
- data/app/models/easy_flow/progress/kept.rb +4 -0
- data/app/models/easy_flow/progress/loose.rb +12 -4
- data/app/models/easy_flow/progress.rb +2 -2
- data/app/models/easy_flow/run.rb +19 -6
- data/app/models/easy_flow/runner.rb +11 -11
- data/app/models/easy_flow/settings.rb +5 -2
- data/app/models/easy_flow/step.rb +6 -2
- data/app/models/easy_flow/step_type/declaration.rb +13 -3
- data/app/models/easy_flow/step_type.rb +18 -5
- data/app/models/easy_flow/validator.rb +12 -1
- data/app/models/easy_flow/wait.rb +38 -0
- data/app/views/easy_flow/flows/step.html.erb +6 -0
- data/db/migrate/20261011130000_keep_step_visits_whole_in_easy_flow_runs.rb +23 -0
- data/lib/easy_flow/engine.rb +4 -0
- data/lib/easy_flow/version.rb +1 -1
- data/the_local/agents/easy_flow-develop.md +100 -20
- data/the_local/agents/easy_flow-info.md +25 -11
- data/the_local/agents/easy_flow-install.md +19 -5
- data/the_local/interface.yml +6 -0
- metadata +7 -1
data/app/models/easy_flow/run.rb
CHANGED
|
@@ -15,11 +15,15 @@ module EasyFlow
|
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
def record(step_id, value)
|
|
18
|
-
update!(recorded:
|
|
18
|
+
update!(recorded: visits.merge(step_id.to_s => { "value" => value, "completed_at" => Time.current.utc.iso8601 }))
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
def recorded
|
|
22
|
-
|
|
22
|
+
visits.to_h { |step_id, visit| [ step_id.to_sym, visit["value"] ] }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def completed_at
|
|
26
|
+
visits.select { |_step_id, visit| visit["completed_at"] }.to_h { |step_id, visit| [ step_id.to_sym, Time.zone.parse(visit["completed_at"]) ] }
|
|
23
27
|
end
|
|
24
28
|
|
|
25
29
|
def advance
|
|
@@ -31,11 +35,16 @@ module EasyFlow
|
|
|
31
35
|
end
|
|
32
36
|
|
|
33
37
|
def next_step(state)
|
|
34
|
-
digest.next_step(state.transform_keys(&:to_s))
|
|
38
|
+
digest.next_step(state.transform_keys(&:to_s), completed_at.transform_keys(&:to_s))
|
|
35
39
|
end
|
|
36
40
|
|
|
37
41
|
def output
|
|
38
|
-
digest.output(recorded.transform_keys(&:to_s))
|
|
42
|
+
digest.output(recorded.transform_keys(&:to_s), completed_at.transform_keys(&:to_s))
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def held_until
|
|
46
|
+
stopped_at = next_step(recorded)
|
|
47
|
+
Wait.held_until(digest.step(stopped_at.id), CompletedAt.latest(completed_at)) if stopped_at&.type == "wait"
|
|
39
48
|
end
|
|
40
49
|
|
|
41
50
|
def waiting_on
|
|
@@ -44,7 +53,7 @@ module EasyFlow
|
|
|
44
53
|
end
|
|
45
54
|
|
|
46
55
|
def walked(state)
|
|
47
|
-
digest.state_on_path(state.transform_keys(&:to_s))
|
|
56
|
+
digest.state_on_path(state.transform_keys(&:to_s), completed_at.transform_keys(&:to_s))
|
|
48
57
|
end
|
|
49
58
|
|
|
50
59
|
def digest
|
|
@@ -53,7 +62,7 @@ module EasyFlow
|
|
|
53
62
|
|
|
54
63
|
def discard_last
|
|
55
64
|
last = walked(recorded).keys.map(&:to_sym).last
|
|
56
|
-
update!(recorded:
|
|
65
|
+
update!(recorded: visits.except(last.to_s)) if last
|
|
57
66
|
end
|
|
58
67
|
|
|
59
68
|
def pinned_steps
|
|
@@ -62,6 +71,10 @@ module EasyFlow
|
|
|
62
71
|
|
|
63
72
|
private
|
|
64
73
|
|
|
74
|
+
def visits
|
|
75
|
+
read_attribute(:recorded).to_h
|
|
76
|
+
end
|
|
77
|
+
|
|
65
78
|
def started_on_a_published_version
|
|
66
79
|
errors.add(:definition_version, "must be a published version of the flow") unless definition_version&.flow_id == flow_id && (definition_version.live? || definition_version.superseded?)
|
|
67
80
|
end
|
|
@@ -23,13 +23,13 @@ module EasyFlow
|
|
|
23
23
|
@digest.step(id.to_s)
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
def next_step(state, run: nil)
|
|
27
|
-
node = @digest.next_step(named(state))
|
|
26
|
+
def next_step(state, run: nil, times: {})
|
|
27
|
+
node = @digest.next_step(named(state), named(times))
|
|
28
28
|
narrowed(shown(node, run), node, state)
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
def run(progress)
|
|
32
|
-
while (node = @digest.next_step(named(progress.recorded))) && goes_on?(node, named(progress.recorded))
|
|
32
|
+
while (node = @digest.next_step(named(progress.recorded), named(progress.completed_at))) && goes_on?(node, named(progress.recorded), CompletedAt.latest(named(progress.completed_at)))
|
|
33
33
|
progress.record(node.id, result_of(@digest.step(node.id), named(progress.recorded)))
|
|
34
34
|
end
|
|
35
35
|
progress.start_inner(node) if node && starts_a_flow?(node)
|
|
@@ -41,12 +41,12 @@ module EasyFlow
|
|
|
41
41
|
node.present? && decided?(node, state)
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
-
def drawing_at(state)
|
|
45
|
-
Drawing.of(@digest.next_step(named(state)), @registry)
|
|
44
|
+
def drawing_at(state, times: {})
|
|
45
|
+
Drawing.of(@digest.next_step(named(state), named(times)), @registry)
|
|
46
46
|
end
|
|
47
47
|
|
|
48
|
-
def state_on_path(state)
|
|
49
|
-
@digest.state_on_path(named(state)).symbolize_keys
|
|
48
|
+
def state_on_path(state, times: {})
|
|
49
|
+
@digest.state_on_path(named(state), named(times)).symbolize_keys
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
def questions_left(state)
|
|
@@ -67,8 +67,8 @@ module EasyFlow
|
|
|
67
67
|
@registry.registered?(node.type) && @registry.fetch(node.type).acts?
|
|
68
68
|
end
|
|
69
69
|
|
|
70
|
-
def goes_on?(node, state)
|
|
71
|
-
acts?(node) || ready?(node, state) || decided?(node, state)
|
|
70
|
+
def goes_on?(node, state, times = {})
|
|
71
|
+
acts?(node) || ready?(node, state, times) || decided?(node, state)
|
|
72
72
|
end
|
|
73
73
|
|
|
74
74
|
def allowed(node, state)
|
|
@@ -87,8 +87,8 @@ module EasyFlow
|
|
|
87
87
|
!choices.nil? && choices.size <= 1
|
|
88
88
|
end
|
|
89
89
|
|
|
90
|
-
def ready?(node, state)
|
|
91
|
-
@registry.registered?(node.type) && @registry.fetch(node.type).waits? && @registry.fetch(node.type).ready?(node, state)
|
|
90
|
+
def ready?(node, state, times = {})
|
|
91
|
+
@registry.registered?(node.type) && @registry.fetch(node.type).waits? && @registry.fetch(node.type).ready?(node, state, times)
|
|
92
92
|
end
|
|
93
93
|
|
|
94
94
|
def result_of(node, state)
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
module EasyFlow
|
|
2
2
|
class Settings
|
|
3
|
-
attr_reader :fields, :labels, :record_fields, :record_labels, :drawn_from, :outputs_of
|
|
3
|
+
attr_reader :fields, :labels, :record_fields, :record_labels, :record_choices, :record_outputs_of, :record_required, :drawn_from, :outputs_of
|
|
4
4
|
|
|
5
|
-
def initialize(fields: {}, labels: {}, record_fields: {}, record_labels: {}, choices: {},
|
|
5
|
+
def initialize(fields: {}, labels: {}, record_fields: {}, record_labels: {}, record_choices: {}, record_outputs_of: {}, record_required: {}, choices: {},
|
|
6
6
|
limits: {}, checks: {}, required: [], drawn_from: {}, outputs_of: {}, kept: {})
|
|
7
7
|
@fields = fields
|
|
8
8
|
@labels = labels
|
|
9
9
|
@record_fields = record_fields
|
|
10
10
|
@record_labels = record_labels
|
|
11
|
+
@record_choices = record_choices
|
|
12
|
+
@record_outputs_of = record_outputs_of
|
|
13
|
+
@record_required = record_required
|
|
11
14
|
@choices = choices
|
|
12
15
|
@limits = limits
|
|
13
16
|
@checks = checks
|
|
@@ -24,8 +24,12 @@ module EasyFlow
|
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
def behaviours
|
|
27
|
-
BEHAVIOURS.select { |word| method_defined?(word) }
|
|
28
|
-
|
|
27
|
+
BEHAVIOURS.select { |word| method_defined?(word) }.map { |word| [ word, [], {}, behaviour(word) ] }
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def behaviour(word)
|
|
31
|
+
asks_for_times = instance_method(word).arity.abs >= 3
|
|
32
|
+
->(node, state, times = {}) { asks_for_times ? new.public_send(word, node, state, times) : new.public_send(word, node, state) }
|
|
29
33
|
end
|
|
30
34
|
|
|
31
35
|
def register(registry = EasyFlow.registry)
|
|
@@ -8,6 +8,9 @@ module EasyFlow
|
|
|
8
8
|
@labels = {}
|
|
9
9
|
@record_fields = {}
|
|
10
10
|
@record_labels = {}
|
|
11
|
+
@record_choices = {}
|
|
12
|
+
@record_outputs_of = {}
|
|
13
|
+
@record_required = {}
|
|
11
14
|
@choices = {}
|
|
12
15
|
@limits = {}
|
|
13
16
|
@checks = {}
|
|
@@ -26,6 +29,10 @@ module EasyFlow
|
|
|
26
29
|
@declared_outputs += [ Output.new(name: name, type: type, label: label, values: values, from: from) ]
|
|
27
30
|
end
|
|
28
31
|
|
|
32
|
+
def outputs_named_by(setting)
|
|
33
|
+
@outputs_named_by = setting
|
|
34
|
+
end
|
|
35
|
+
|
|
29
36
|
def displays_by(&display)
|
|
30
37
|
@display = display
|
|
31
38
|
end
|
|
@@ -107,7 +114,7 @@ module EasyFlow
|
|
|
107
114
|
|
|
108
115
|
protected
|
|
109
116
|
|
|
110
|
-
attr_reader :fields, :labels
|
|
117
|
+
attr_reader :fields, :labels, :choices, :outputs_of, :required
|
|
111
118
|
|
|
112
119
|
private
|
|
113
120
|
|
|
@@ -122,6 +129,9 @@ module EasyFlow
|
|
|
122
129
|
declared = Declaration.new(:entry).tap { |entry| entry.instance_eval(&entries) }
|
|
123
130
|
@record_fields[name] = declared.fields
|
|
124
131
|
@record_labels[name] = declared.labels
|
|
132
|
+
@record_choices[name] = declared.choices
|
|
133
|
+
@record_outputs_of[name] = declared.outputs_of
|
|
134
|
+
@record_required[name] = declared.required
|
|
125
135
|
end
|
|
126
136
|
|
|
127
137
|
public
|
|
@@ -130,12 +140,12 @@ module EasyFlow
|
|
|
130
140
|
StepType.new(id: @id, step_name: @step_name, settings: settings, awaits_input: @awaits_input,
|
|
131
141
|
ends_here: @ends_here, begins_here: @begins_here, starts_a_flow: @starts_a_flow, flow_chooser: @flow_chooser, run_chooser: @run_chooser, behaviour: @behaviour, routing: @routing,
|
|
132
142
|
display: @display, drawn_by: @drawn_by, naming_field: @naming_field, naming: @naming,
|
|
133
|
-
outputs: @declared_outputs, answer_check: @answer_check, answer_labelling: @answer_labelling, readiness: @readiness)
|
|
143
|
+
outputs: @declared_outputs, outputs_named_by: @outputs_named_by, answer_check: @answer_check, answer_labelling: @answer_labelling, readiness: @readiness)
|
|
134
144
|
end
|
|
135
145
|
|
|
136
146
|
def settings
|
|
137
147
|
Settings.new(fields: @fields, labels: @labels, record_fields: @record_fields,
|
|
138
|
-
record_labels: @record_labels, choices: @choices, limits: @limits, checks: @checks,
|
|
148
|
+
record_labels: @record_labels, record_choices: @record_choices, record_outputs_of: @record_outputs_of, record_required: @record_required, choices: @choices, limits: @limits, checks: @checks,
|
|
139
149
|
required: @required, drawn_from: @drawn_from, outputs_of: @outputs_of, kept: @kept)
|
|
140
150
|
end
|
|
141
151
|
end
|
|
@@ -8,7 +8,7 @@ module EasyFlow
|
|
|
8
8
|
|
|
9
9
|
def initialize(id:, step_name:, settings:, awaits_input:, behaviour:, routing:,
|
|
10
10
|
ends_here: false, begins_here: false, starts_a_flow: false, flow_chooser: nil, run_chooser: nil, display: nil, drawn_by: nil,
|
|
11
|
-
naming_field: nil, naming: nil, outputs: [], answer_check: nil, answer_labelling: nil, readiness: nil)
|
|
11
|
+
naming_field: nil, naming: nil, outputs: [], outputs_named_by: nil, answer_check: nil, answer_labelling: nil, readiness: nil)
|
|
12
12
|
@id = id
|
|
13
13
|
@step_name = step_name
|
|
14
14
|
@settings = settings
|
|
@@ -25,6 +25,7 @@ module EasyFlow
|
|
|
25
25
|
@naming_field = naming_field
|
|
26
26
|
@naming = naming
|
|
27
27
|
@outputs = outputs
|
|
28
|
+
@outputs_named_by = outputs_named_by
|
|
28
29
|
@answer_check = answer_check
|
|
29
30
|
@answer_labelling = answer_labelling
|
|
30
31
|
@readiness = readiness
|
|
@@ -40,8 +41,8 @@ module EasyFlow
|
|
|
40
41
|
@behaviour&.call(node, state)
|
|
41
42
|
end
|
|
42
43
|
|
|
43
|
-
def route(node, state)
|
|
44
|
-
@routing&.call(node, state)
|
|
44
|
+
def route(node, state, times = {})
|
|
45
|
+
@routing&.call(node, state, times)
|
|
45
46
|
end
|
|
46
47
|
|
|
47
48
|
def answer_problem(node, value)
|
|
@@ -56,8 +57,8 @@ module EasyFlow
|
|
|
56
57
|
@readiness.present?
|
|
57
58
|
end
|
|
58
59
|
|
|
59
|
-
def ready?(node, state)
|
|
60
|
-
@readiness.call(node, state)
|
|
60
|
+
def ready?(node, state, times = {})
|
|
61
|
+
@readiness.call(node, state, times)
|
|
61
62
|
end
|
|
62
63
|
|
|
63
64
|
def name_of(node)
|
|
@@ -72,6 +73,10 @@ module EasyFlow
|
|
|
72
73
|
@routing.present?
|
|
73
74
|
end
|
|
74
75
|
|
|
76
|
+
def outputs_for(node)
|
|
77
|
+
outputs + named_outputs(node)
|
|
78
|
+
end
|
|
79
|
+
|
|
75
80
|
def values_of(name, node)
|
|
76
81
|
outputs.find { |output| output.name.to_s == name.to_s }&.values_for(node).to_a
|
|
77
82
|
end
|
|
@@ -108,5 +113,13 @@ module EasyFlow
|
|
|
108
113
|
chosen = flow_chosen_by(node)
|
|
109
114
|
ChosenFlow.worked_out(chosen).name if chosen
|
|
110
115
|
end
|
|
116
|
+
|
|
117
|
+
private
|
|
118
|
+
|
|
119
|
+
def named_outputs(node)
|
|
120
|
+
return [] unless @outputs_named_by
|
|
121
|
+
|
|
122
|
+
Array(node.config[@outputs_named_by.to_s]).filter_map { |entry| entry["name"].presence }.map { |name| Output.new(name: name) }
|
|
123
|
+
end
|
|
111
124
|
end
|
|
112
125
|
end
|
|
@@ -176,7 +176,18 @@ module EasyFlow
|
|
|
176
176
|
def missing_settings
|
|
177
177
|
@document.nodes.flat_map do |node|
|
|
178
178
|
required_of(node).reject { |name| node.config[name.to_s].present? }
|
|
179
|
-
.map { |name| Violation.new(node: node.id, problem: :missing_setting, detail: name.to_s) }
|
|
179
|
+
.map { |name| Violation.new(node: node.id, problem: :missing_setting, detail: name.to_s) } + missing_entry_settings(node)
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def missing_entry_settings(node)
|
|
184
|
+
return [] unless @registry.registered?(node.type)
|
|
185
|
+
|
|
186
|
+
@registry.fetch(node.type).settings.record_required.flat_map do |list, required|
|
|
187
|
+
Array(node.config[list.to_s]).each_with_index.flat_map do |entry, index|
|
|
188
|
+
required.reject { |name| entry.to_h[name.to_s].present? }
|
|
189
|
+
.map { |name| Violation.new(node: node.id, problem: :missing_setting, detail: "#{list} #{index + 1} #{name}") }
|
|
190
|
+
end
|
|
180
191
|
end
|
|
181
192
|
end
|
|
182
193
|
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module EasyFlow
|
|
2
|
+
class Wait
|
|
3
|
+
include Step
|
|
4
|
+
|
|
5
|
+
step_name "Wait"
|
|
6
|
+
|
|
7
|
+
setting :step, type: :previous_step, label: "Counting from", required: true
|
|
8
|
+
setting :minutes, type: :integer, label: "Minutes after it"
|
|
9
|
+
setting :time_of_day, type: :string, label: "Next time of day after it, as HH:MM"
|
|
10
|
+
setting :date, type: :string, label: "Date, as YYYY-MM-DD"
|
|
11
|
+
|
|
12
|
+
names_by { |node| Wait.named(node.config) }
|
|
13
|
+
|
|
14
|
+
waits_until { |node, _state, times| Wait.held_until(node, times)&.then { |held| held <= Time.current } || false }
|
|
15
|
+
|
|
16
|
+
def self.named(config)
|
|
17
|
+
return config["date"] if config["date"].present?
|
|
18
|
+
|
|
19
|
+
waited = config["time_of_day"].presence || ("#{config["minutes"]} minutes" if config["minutes"].present?)
|
|
20
|
+
"#{waited} after #{config["step"]}" if waited
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def self.held_until(node, times)
|
|
24
|
+
from = times[node.config["step"]]
|
|
25
|
+
return Time.zone.parse(node.config["date"]) if node.config["date"].present?
|
|
26
|
+
return if from.nil?
|
|
27
|
+
return next_time_of_day(from, node.config["time_of_day"]) if node.config["time_of_day"].present?
|
|
28
|
+
|
|
29
|
+
from + node.config["minutes"].to_i.minutes
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def self.next_time_of_day(from, time_of_day)
|
|
33
|
+
hour, minute = time_of_day.split(":").map(&:to_i)
|
|
34
|
+
same_day = from.in_time_zone.change(hour: hour, min: minute)
|
|
35
|
+
same_day > from ? same_day : same_day.tomorrow
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -13,6 +13,9 @@
|
|
|
13
13
|
|
|
14
14
|
<% if @waiting %>
|
|
15
15
|
<p class="ks-hint">Waiting for <%= @waiting %>.</p>
|
|
16
|
+
<% if carries_answers? %>
|
|
17
|
+
<div class="mt-4"><%= ui_button(label: "Check again", href: "#{flow_step_path(@guide.slug)}?#{{ answers: @answers, completed_at: @progress.completed_at.transform_values(&:iso8601) }.to_query}", variant: :secondary) %></div>
|
|
18
|
+
<% end %>
|
|
16
19
|
<% else %>
|
|
17
20
|
<%= form_with url: step_form[:url], method: step_form[:method], multipart: true, data: { turbo: false } do %>
|
|
18
21
|
<%= hidden_field_tag :asked, @question.id %>
|
|
@@ -25,6 +28,9 @@
|
|
|
25
28
|
<% else %>
|
|
26
29
|
<%= hidden_field_tag "answers[#{key}]", value %>
|
|
27
30
|
<% end %>
|
|
31
|
+
<% if (answered = @progress.completed_at[key]) %>
|
|
32
|
+
<%= hidden_field_tag "completed_at[#{key}]", answered.iso8601, id: nil %>
|
|
33
|
+
<% end %>
|
|
28
34
|
<% end %>
|
|
29
35
|
<% end %>
|
|
30
36
|
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
class KeepStepVisitsWholeInEasyFlowRuns < ActiveRecord::Migration[8.1]
|
|
2
|
+
class Run < ActiveRecord::Base
|
|
3
|
+
self.table_name = "easy_flow_runs"
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
def up
|
|
7
|
+
Run.find_each do |run|
|
|
8
|
+
run.update_columns(recorded: run.recorded.to_h.transform_values { |value| whole?(value) ? value : { "value" => value } })
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def down
|
|
13
|
+
Run.find_each do |run|
|
|
14
|
+
run.update_columns(recorded: run.recorded.to_h.transform_values { |value| whole?(value) ? value["value"] : value })
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def whole?(value)
|
|
21
|
+
value.is_a?(Hash) && value.key?("value") && (value.keys - %w[value completed_at]).empty?
|
|
22
|
+
end
|
|
23
|
+
end
|
data/lib/easy_flow/engine.rb
CHANGED
|
@@ -24,6 +24,10 @@ module EasyFlow
|
|
|
24
24
|
EasyFlow::Condition.register
|
|
25
25
|
EasyFlow::Switch.register
|
|
26
26
|
EasyFlow::Compare.register
|
|
27
|
+
EasyFlow::CompareTwoValues.register
|
|
28
|
+
EasyFlow::AllOrAny.register
|
|
29
|
+
EasyFlow::Count.register
|
|
30
|
+
EasyFlow::Wait.register
|
|
27
31
|
EasyFlow::FlowStep.register
|
|
28
32
|
|
|
29
33
|
EasyFlow.check(:unrouted_value)
|
data/lib/easy_flow/version.rb
CHANGED