trailblazer-activity-dsl-linear 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +2 -5
- data/CHANGES.md +72 -0
- data/Gemfile +6 -3
- data/lib/trailblazer/activity/dsl/linear/feature/merge.rb +2 -2
- data/lib/trailblazer/activity/dsl/linear/feature/patch.rb +9 -9
- data/lib/trailblazer/activity/dsl/linear/feature/variable_mapping/dsl.rb +19 -29
- data/lib/trailblazer/activity/dsl/linear/feature/variable_mapping/runtime.rb +6 -8
- data/lib/trailblazer/activity/dsl/linear/feature/variable_mapping.rb +25 -35
- data/lib/trailblazer/activity/dsl/linear/helper/path.rb +37 -18
- data/lib/trailblazer/activity/dsl/linear/helper.rb +27 -18
- data/lib/trailblazer/activity/dsl/linear/normalizer/extensions.rb +63 -0
- data/lib/trailblazer/activity/dsl/linear/normalizer/inherit.rb +90 -0
- data/lib/trailblazer/activity/dsl/linear/normalizer/output_tuples.rb +160 -0
- data/lib/trailblazer/activity/dsl/linear/normalizer/terminus.rb +26 -29
- data/lib/trailblazer/activity/dsl/linear/normalizer.rb +96 -148
- data/lib/trailblazer/activity/dsl/linear/sequence/builder.rb +3 -2
- data/lib/trailblazer/activity/dsl/linear/sequence/compiler.rb +21 -17
- data/lib/trailblazer/activity/dsl/linear/sequence/search.rb +2 -8
- data/lib/trailblazer/activity/dsl/linear/strategy.rb +17 -17
- data/lib/trailblazer/activity/dsl/linear/version.rb +1 -1
- data/lib/trailblazer/activity/dsl/linear.rb +12 -1
- data/lib/trailblazer/activity/fast_track.rb +91 -54
- data/lib/trailblazer/activity/path.rb +22 -29
- data/lib/trailblazer/activity/railway.rb +60 -54
- data/trailblazer-activity-dsl-linear.gemspec +7 -8
- metadata +21 -36
- data/.github/workflows/ci_jruby.yml +0 -19
- data/.github/workflows/ci_legacy.yml +0 -19
- data/.github/workflows/ci_truffleruby.yml +0 -19
- data/lib/trailblazer/activity/dsl/linear/feature/variable_mapping/inherit.rb +0 -38
@@ -6,10 +6,7 @@ module Trailblazer
|
|
6
6
|
# and then get processed in the normalizer.
|
7
7
|
#
|
8
8
|
# @private
|
9
|
-
|
10
|
-
Id = Struct.new(:value)
|
11
|
-
Track = Struct.new(:color, :adds, :options)
|
12
|
-
Extension = Struct.new(:callable) do
|
9
|
+
Extension = Struct.new(:callable) do
|
13
10
|
def call(*args, &block)
|
14
11
|
callable.(*args, &block)
|
15
12
|
end
|
@@ -27,14 +24,14 @@ module Trailblazer
|
|
27
24
|
|
28
25
|
# Output( Left, :failure )
|
29
26
|
# Output( :failure ) #=> Output::Semantic
|
30
|
-
def Output(signal, semantic=nil)
|
31
|
-
return
|
27
|
+
def Output(signal, semantic = nil)
|
28
|
+
return Normalizer::OutputTuples::Output::Semantic.new(signal) if semantic.nil?
|
32
29
|
|
33
|
-
|
30
|
+
Normalizer::OutputTuples::Output::CustomOutput.new(signal, semantic)
|
34
31
|
end
|
35
32
|
|
36
33
|
def End(semantic)
|
37
|
-
|
34
|
+
Normalizer::OutputTuples::End.new(semantic).freeze
|
38
35
|
end
|
39
36
|
|
40
37
|
def end_id(semantic:, **)
|
@@ -42,15 +39,15 @@ module Trailblazer
|
|
42
39
|
end
|
43
40
|
|
44
41
|
def Track(color, wrap_around: false)
|
45
|
-
Track.new(color, [], wrap_around: wrap_around).freeze
|
42
|
+
Normalizer::OutputTuples::Track.new(color, [], wrap_around: wrap_around).freeze
|
46
43
|
end
|
47
44
|
|
48
45
|
def Id(id)
|
49
|
-
Id.new(id).freeze
|
46
|
+
Normalizer::OutputTuples::Id.new(id).freeze
|
50
47
|
end
|
51
48
|
|
52
49
|
def Path(**options, &block)
|
53
|
-
options = options.merge(block: block) if
|
50
|
+
options = options.merge(block: block) if block
|
54
51
|
|
55
52
|
Linear::PathBranch.new(options) # picked up by normalizer.
|
56
53
|
end
|
@@ -59,27 +56,39 @@ module Trailblazer
|
|
59
56
|
# @param :strict If true, all outputs of {activity} will be wired to the track named after the
|
60
57
|
# output's semantic.
|
61
58
|
def Subprocess(activity, patch: {}, strict: false)
|
62
|
-
activity = Linear.
|
59
|
+
activity = Linear::Patch.customize(activity, options: patch)
|
63
60
|
|
64
61
|
outputs = activity.to_h[:outputs]
|
65
62
|
options = {}
|
66
63
|
|
67
64
|
if strict
|
68
65
|
options.merge!(
|
69
|
-
outputs.collect { |output| [Output(output.semantic), Track(output.semantic)] }.to_h
|
66
|
+
outputs.collect { |output| [Normalizer::OutputTuples::Output::Semantic.new(output.semantic, true), Track(output.semantic)] }.to_h
|
70
67
|
)
|
71
68
|
end
|
72
69
|
|
73
70
|
{
|
74
71
|
task: activity,
|
75
72
|
outputs: outputs.collect { |output| [output.semantic, output] }.to_h,
|
76
|
-
}
|
77
|
-
|
73
|
+
}
|
74
|
+
.merge(options)
|
78
75
|
end
|
79
76
|
|
80
|
-
def In(**kws)
|
81
|
-
|
82
|
-
|
77
|
+
def In(**kws)
|
78
|
+
VariableMapping::DSL::In(**kws)
|
79
|
+
end
|
80
|
+
|
81
|
+
def Out(**kws)
|
82
|
+
VariableMapping::DSL::Out(**kws)
|
83
|
+
end
|
84
|
+
|
85
|
+
def Inject(*args, **kws)
|
86
|
+
VariableMapping::DSL::Inject(*args, **kws)
|
87
|
+
end
|
88
|
+
|
89
|
+
def Extension(*args, **kws)
|
90
|
+
Normalizer::Extensions.Extension(*args, **kws)
|
91
|
+
end
|
83
92
|
|
84
93
|
def DataVariable
|
85
94
|
DataVariableName.new
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Trailblazer
|
2
|
+
class Activity
|
3
|
+
module DSL
|
4
|
+
module Linear
|
5
|
+
module Normalizer
|
6
|
+
# Implements {:extensions} option and allows adding taskWrap extensions using
|
7
|
+
# Linear::Normalizer::Extensions.Extension().
|
8
|
+
module Extensions
|
9
|
+
module_function
|
10
|
+
|
11
|
+
Extension = Struct.new(:generic?, :id)
|
12
|
+
|
13
|
+
def Extension(is_generic: false)
|
14
|
+
Extension.new(is_generic, rand) # {id} has to be unique for every Extension instance (for Hash identity).
|
15
|
+
end
|
16
|
+
|
17
|
+
# Convert {:extensions} option to {Extension} tuples. The new way of adding extensions is
|
18
|
+
# step ..., Extension() => my_extension
|
19
|
+
def convert_extensions_option_to_tuples(ctx, non_symbol_options:, extensions: nil, **)
|
20
|
+
return unless extensions
|
21
|
+
# TODO: deprecate {:extensions} in the DSL?
|
22
|
+
|
23
|
+
extensions_tuples = extensions.collect { |ext| [Extension(), ext] }.to_h
|
24
|
+
|
25
|
+
ctx.merge!(
|
26
|
+
non_symbol_options: non_symbol_options.merge(extensions_tuples)
|
27
|
+
)
|
28
|
+
end
|
29
|
+
|
30
|
+
def compile_extensions(ctx, non_symbol_options:, **)
|
31
|
+
extensions_ary =
|
32
|
+
non_symbol_options
|
33
|
+
.find_all { |k, v| k.instance_of?(Extension) }
|
34
|
+
.to_h
|
35
|
+
.values
|
36
|
+
|
37
|
+
ctx.merge!(
|
38
|
+
extensions: extensions_ary
|
39
|
+
)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Don't record Extension()s created by the DSL! This happens in VariableMapping, for instance.
|
43
|
+
# Either the user also inherits I/O tuples and the extension will be recreated,
|
44
|
+
# or they really don't want this particular extension to be inherited.
|
45
|
+
def compile_recorded_extensions(ctx, non_symbol_options:, **)
|
46
|
+
recorded_extension_tuples =
|
47
|
+
non_symbol_options
|
48
|
+
.find_all { |k, v| k.instance_of?(Extension) }
|
49
|
+
.reject { |k, v| k.generic? }
|
50
|
+
.to_h
|
51
|
+
|
52
|
+
ctx.merge!(
|
53
|
+
non_symbol_options: non_symbol_options.merge(
|
54
|
+
Normalizer::Inherit.Record(recorded_extension_tuples, type: :extensions)
|
55
|
+
)
|
56
|
+
)
|
57
|
+
end
|
58
|
+
end # Extensions
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module Trailblazer
|
2
|
+
class Activity
|
3
|
+
module DSL
|
4
|
+
module Linear
|
5
|
+
module Normalizer
|
6
|
+
# Implements the generic {:inherit} option.
|
7
|
+
# Features such as variable mapping or the Wiring API can
|
8
|
+
# use the generic behavior for their inheritance.
|
9
|
+
|
10
|
+
# "generic": built by the DSL from options, options that are inherited, so you might not want to record or inherit generic options
|
11
|
+
module Inherit
|
12
|
+
module_function
|
13
|
+
|
14
|
+
# Options you want to have stored and inherited can be
|
15
|
+
# declared using Record.
|
16
|
+
Record = Struct.new(:options, :type, :non_symbol_options?) # FIXME: i hate symbol vs. non-symbol.
|
17
|
+
|
18
|
+
def Record(options, type:, non_symbol_options: true)
|
19
|
+
{Record.new(options, type, non_symbol_options) => nil}
|
20
|
+
end
|
21
|
+
|
22
|
+
# Currently, the {:inherit} option copies over {:extensions} from the original step and merges them with new :extensions.
|
23
|
+
#
|
24
|
+
### Recall
|
25
|
+
# Fetch remembered options and add them to the processed options.
|
26
|
+
def recall_recorded_options(ctx, non_symbol_options:, sequence:, id:, inherit: nil, extensions: [], **)
|
27
|
+
return unless inherit === true || inherit.is_a?(Array)
|
28
|
+
|
29
|
+
# E.g. {variable_mapping: true, wiring_api: true}
|
30
|
+
types_to_recall =
|
31
|
+
if inherit === true
|
32
|
+
# we want to inherit "everything": extensions, output_tuples, variable_mapping
|
33
|
+
Hash.new { true }
|
34
|
+
else
|
35
|
+
inherit.collect { |type| [type, true] }.to_h
|
36
|
+
end
|
37
|
+
|
38
|
+
row = find_row(sequence, id) # from this row we're inheriting options.
|
39
|
+
|
40
|
+
# DISCUSS: should we maybe revert the idea of separating options by type?
|
41
|
+
# Anyway, key idea here is that Record() users don't have to know these details
|
42
|
+
# about symbol vs. non-symbol.
|
43
|
+
symbol_options_to_merge = {}
|
44
|
+
non_symbol_options_to_merge = {}
|
45
|
+
|
46
|
+
row.data[:recorded_options].each do |type, record|
|
47
|
+
next unless types_to_recall[type]
|
48
|
+
|
49
|
+
target = record.non_symbol_options? ? non_symbol_options_to_merge : symbol_options_to_merge
|
50
|
+
target.merge!(record.options)
|
51
|
+
end
|
52
|
+
|
53
|
+
ctx[:non_symbol_options] = non_symbol_options_to_merge.merge(non_symbol_options)
|
54
|
+
|
55
|
+
ctx.merge!(symbol_options_to_merge)
|
56
|
+
|
57
|
+
ctx.merge!(
|
58
|
+
inherited_recorded_options: row.data[:recorded_options]
|
59
|
+
)
|
60
|
+
end
|
61
|
+
|
62
|
+
def find_row(sequence, id)
|
63
|
+
index = Activity::Adds::Insert.find_index(sequence, id)
|
64
|
+
sequence[index]
|
65
|
+
end
|
66
|
+
|
67
|
+
### Record
|
68
|
+
# Figure out what to remember from the options and store it in {row.data[:recorded_options]}.
|
69
|
+
# Note that this is generic logic not tied to variable_mapping, OutputTuples or anything.
|
70
|
+
def compile_recorded_options(ctx, non_symbol_options:, **)
|
71
|
+
recorded_options = {}
|
72
|
+
|
73
|
+
non_symbol_options
|
74
|
+
.find_all { |k, v| k.instance_of?(Record) }
|
75
|
+
.collect do |k, v|
|
76
|
+
recorded_options[k.type] = k # DISCUSS: we overwrite potential data with same type.
|
77
|
+
end
|
78
|
+
|
79
|
+
ctx.merge!(
|
80
|
+
recorded_options: recorded_options,
|
81
|
+
# add {row.data[:recorded_options]} in Sequence:
|
82
|
+
non_symbol_options: non_symbol_options.merge(Strategy.DataVariable() => :recorded_options)
|
83
|
+
)
|
84
|
+
end
|
85
|
+
end # Inherit
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,160 @@
|
|
1
|
+
module Trailblazer
|
2
|
+
class Activity
|
3
|
+
module DSL
|
4
|
+
module Linear
|
5
|
+
module Normalizer
|
6
|
+
# Implements Output(:success) => Track(:success)
|
7
|
+
# Internals are documented: https://trailblazer.to/2.1/docs/internals.html#internals-wiring-api-output-tuples
|
8
|
+
module OutputTuples
|
9
|
+
module_function
|
10
|
+
|
11
|
+
# Connector when using Id(:validate).
|
12
|
+
class Id < Struct.new(:value)
|
13
|
+
def to_a(*)
|
14
|
+
return [Linear::Sequence::Search.method(:ById), value], [] # {value} is the "target".
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# Connector when using Track(:success).
|
19
|
+
class Track < Struct.new(:color, :adds, :options)
|
20
|
+
def to_a(*)
|
21
|
+
search_strategy = options[:wrap_around] ? :WrapAround : :Forward
|
22
|
+
|
23
|
+
return [Linear::Sequence::Search.method(search_strategy), color], adds
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Connector representing a (to-be-created?) terminus when using End(:semantic).
|
28
|
+
class End < Struct.new(:semantic)
|
29
|
+
def to_a(ctx)
|
30
|
+
end_id = Linear::Strategy.end_id(semantic: semantic)
|
31
|
+
end_exists = Activity::Adds::Insert.find_index(ctx[:sequence], end_id)
|
32
|
+
|
33
|
+
terminus = Activity.End(semantic)
|
34
|
+
|
35
|
+
adds = end_exists ? [] : OutputTuples::Connections.add_terminus(terminus, id: end_id, sequence: ctx[:sequence], normalizers: ctx[:normalizers])
|
36
|
+
|
37
|
+
return [Linear::Sequence::Search.method(:ById), end_id], adds
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Logic related to {Output() => ...}, called "Wiring API".
|
42
|
+
# TODO: move to different namespace (feature/dsl)
|
43
|
+
def Output(semantic, is_generic: true)
|
44
|
+
Normalizer::OutputTuples::Output::Semantic.new(semantic, is_generic)
|
45
|
+
end
|
46
|
+
|
47
|
+
module Output
|
48
|
+
# Note that both {Semantic} and {CustomOutput} are {is_a?(Output)}
|
49
|
+
Semantic = Struct.new(:semantic, :generic?).include(Output)
|
50
|
+
CustomOutput = Struct.new(:signal, :semantic, :generic?).include(Output) # generic? is always false
|
51
|
+
end
|
52
|
+
|
53
|
+
def normalize_output_tuples(ctx, non_symbol_options:, **)
|
54
|
+
output_tuples = non_symbol_options.find_all { |k, v| k.is_a?(OutputTuples::Output) }
|
55
|
+
|
56
|
+
ctx.merge!(output_tuples: output_tuples)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Remember all custom (non-generic) {:output_tuples}.
|
60
|
+
def remember_custom_output_tuples(ctx, output_tuples:, non_symbol_options:, **)
|
61
|
+
# We don't include generic OutputSemantic (from Subprocess(strict: true)) for inheritance, as this is not a user customization.
|
62
|
+
custom_output_tuples = output_tuples.reject { |k, v| k.generic? }
|
63
|
+
|
64
|
+
# save Output() tuples under {:custom_output_tuples} for inheritance.
|
65
|
+
ctx.merge!(
|
66
|
+
non_symbol_options: non_symbol_options.merge(
|
67
|
+
Normalizer::Inherit.Record(custom_output_tuples.to_h, type: :custom_output_tuples)
|
68
|
+
)
|
69
|
+
)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Take all Output(signal, semantic), convert to OutputSemantic and extend {:outputs}.
|
73
|
+
# Since only users use this style, we don't have to filter.
|
74
|
+
def register_additional_outputs(ctx, output_tuples:, outputs:, **)
|
75
|
+
# We need to preserve the order when replacing Output with OutputSemantic,
|
76
|
+
# that's why we recreate {output_tuples} here.
|
77
|
+
output_tuples =
|
78
|
+
output_tuples.collect do |(output, connector)|
|
79
|
+
if output.is_a?(Output::CustomOutput)
|
80
|
+
# add custom output to :outputs.
|
81
|
+
outputs = outputs.merge(output.semantic => Activity.Output(output.signal, output.semantic))
|
82
|
+
|
83
|
+
# Convert Output to OutputSemantic.
|
84
|
+
[Strategy.Output(output.semantic), connector]
|
85
|
+
else
|
86
|
+
[output, connector]
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
ctx.merge!(
|
91
|
+
output_tuples: output_tuples,
|
92
|
+
outputs: outputs
|
93
|
+
)
|
94
|
+
end
|
95
|
+
|
96
|
+
# Implements {inherit: :outputs, strict: false}
|
97
|
+
# return connections from {parent} step which are supported by current step
|
98
|
+
def filter_inherited_output_tuples(ctx, outputs:, output_tuples:, inherit: false, inherited_recorded_options: {}, **)
|
99
|
+
return unless inherit === true
|
100
|
+
strict_outputs = false # TODO: implement "strict outputs" for inherit! meaning we connect all inherited Output regardless of the new activity's interface
|
101
|
+
return if strict_outputs === true
|
102
|
+
|
103
|
+
# Grab the inherited {:custom_output_tuples} so we can throw those out if the new activity doesn't support
|
104
|
+
# the respective outputs.
|
105
|
+
inherited_output_tuples_record = inherited_recorded_options[:custom_output_tuples]
|
106
|
+
inherited_output_tuples = inherited_output_tuples_record ? inherited_output_tuples_record.options : {}
|
107
|
+
|
108
|
+
allowed_semantics = outputs.keys # these outputs are exposed by the inheriting step.
|
109
|
+
inherited_semantics = inherited_output_tuples.collect { |output, _| output.semantic }
|
110
|
+
unsupported_semantics = inherited_semantics - allowed_semantics
|
111
|
+
|
112
|
+
filtered_output_tuples = output_tuples.reject { |output, _| unsupported_semantics.include?(output.semantic) }
|
113
|
+
|
114
|
+
ctx.merge!(
|
115
|
+
output_tuples: filtered_output_tuples.to_h
|
116
|
+
)
|
117
|
+
end
|
118
|
+
|
119
|
+
# Compile connections from tuples.
|
120
|
+
module Connections
|
121
|
+
module_function
|
122
|
+
|
123
|
+
# we want this in the end:
|
124
|
+
# {output.semantic => search strategy}
|
125
|
+
# Process {Output(:semantic) => target} and make them {:connections}.
|
126
|
+
# This combines {:connections} and {:outputs}
|
127
|
+
def compile_wirings(ctx, adds:, output_tuples:, outputs:, id:, **)
|
128
|
+
# DISCUSS: how could we add another magnetic_to to an end?
|
129
|
+
# Go through all {Output() => Track()/Id()/End()} tuples.
|
130
|
+
wirings =
|
131
|
+
output_tuples.collect do |output, connector|
|
132
|
+
(search_builder, search_args), connector_adds = connector.to_a(ctx) # Call {#to_a} on Track/Id/End/...
|
133
|
+
|
134
|
+
adds += connector_adds
|
135
|
+
|
136
|
+
semantic = output.semantic
|
137
|
+
output = outputs[semantic] || raise("No `#{semantic}` output found for #{id.inspect} and outputs #{outputs.inspect}")
|
138
|
+
|
139
|
+
# return proc to be called when compiling Seq, e.g. {ById(output, :id)}
|
140
|
+
search_builder.(output, *search_args)
|
141
|
+
end
|
142
|
+
|
143
|
+
ctx[:wirings] = wirings
|
144
|
+
ctx[:adds] = adds
|
145
|
+
end
|
146
|
+
|
147
|
+
# Returns ADDS for the new terminus.
|
148
|
+
# @private
|
149
|
+
def add_terminus(end_event, id:, sequence:, normalizers:)
|
150
|
+
step_options = Linear::Sequence::Builder.invoke_normalizer_for(:terminus, end_event, {id: id}, sequence: sequence, normalizer_options: {}, normalizers: normalizers)
|
151
|
+
|
152
|
+
step_options[:adds]
|
153
|
+
end
|
154
|
+
end # Connections
|
155
|
+
end # OutputTuples
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
@@ -10,28 +10,28 @@ module Trailblazer
|
|
10
10
|
def Normalizer
|
11
11
|
normalizer_steps =
|
12
12
|
{
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
13
|
+
"activity.normalize_step_interface" => Normalizer.Task(Normalizer.method(:normalize_step_interface)), # first
|
14
|
+
"activity.merge_library_options" => Normalizer.Task(Normalizer.method(:merge_library_options)), # Merge "macro"/user options over library options.
|
15
|
+
"activity.normalize_for_macro" => Normalizer.Task(Normalizer.method(:merge_user_options)),
|
16
|
+
"activity.normalize_normalizer_options" => Normalizer.Task(Normalizer.method(:merge_normalizer_options)),
|
17
|
+
"activity.normalize_non_symbol_options" => Normalizer.Task(Normalizer.method(:normalize_non_symbol_options)),
|
18
|
+
"activity.normalize_context" => Normalizer.method(:normalize_context),
|
19
|
+
"terminus.normalize_task" => Normalizer.Task(Terminus.method(:normalize_task)),
|
20
|
+
"terminus.normalize_id" => Normalizer.Task(method(:normalize_id)),
|
21
|
+
"terminus.normalize_magnetic_to" => Normalizer.Task(Terminus.method(:normalize_magnetic_to)),
|
22
|
+
"terminus.append_end" => Normalizer.Task(Terminus.method(:append_end)),
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
24
|
+
"activity.compile_data" => Normalizer.Task(Normalizer.method(:compile_data)), # FIXME: redundant with {Linear::Normalizer}.
|
25
|
+
"activity.create_row" => Normalizer.Task(Normalizer.method(:create_row)),
|
26
|
+
"activity.create_add" => Normalizer.Task(Normalizer.method(:create_add)),
|
27
|
+
"activity.create_adds" => Normalizer.Task(Normalizer.method(:create_adds)),
|
28
28
|
}
|
29
29
|
|
30
30
|
TaskWrap::Pipeline.new(normalizer_steps.to_a)
|
31
31
|
end
|
32
32
|
|
33
33
|
# @private
|
34
|
-
def normalize_id(ctx, id: nil,
|
34
|
+
def normalize_id(ctx, semantic:, id: nil, **)
|
35
35
|
ctx.merge!(
|
36
36
|
id: id || Strategy.end_id(semantic: semantic)
|
37
37
|
)
|
@@ -40,11 +40,11 @@ module Trailblazer
|
|
40
40
|
# @private
|
41
41
|
# Set {:task} and {:semantic}.
|
42
42
|
def normalize_task(ctx, task:, **)
|
43
|
-
if task.
|
44
|
-
|
43
|
+
if task.is_a?(Activity::End) # DISCUSS: do we want this check?
|
44
|
+
_ctx = _normalize_task_for_end_event(ctx, **ctx)
|
45
45
|
else
|
46
46
|
# When used such as {terminus :found}, create the end event automatically.
|
47
|
-
|
47
|
+
_ctx = _normalize_task_for_symbol(ctx, **ctx)
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
@@ -56,8 +56,8 @@ module Trailblazer
|
|
56
56
|
|
57
57
|
def _normalize_task_for_symbol(ctx, task:, semantic: task, **)
|
58
58
|
ctx.merge!(
|
59
|
-
task:
|
60
|
-
semantic: semantic
|
59
|
+
task: Activity.End(semantic),
|
60
|
+
semantic: semantic
|
61
61
|
)
|
62
62
|
end
|
63
63
|
|
@@ -68,19 +68,16 @@ module Trailblazer
|
|
68
68
|
end
|
69
69
|
|
70
70
|
# @private
|
71
|
-
def append_end(ctx, task:,
|
71
|
+
def append_end(ctx, task:, append_to: "End.success", non_symbol_options:, **)
|
72
72
|
terminus_args = {
|
73
|
-
sequence_insert:
|
74
|
-
stop_event:
|
73
|
+
sequence_insert: [Activity::Adds::Insert.method(:Append), append_to],
|
74
|
+
stop_event: true,
|
75
|
+
non_symbol_options: non_symbol_options.merge(Strategy.DataVariable() => [:stop_event, :semantic])
|
75
76
|
}
|
76
77
|
|
77
78
|
ctx.merge!(
|
78
|
-
wirings: [
|
79
|
-
|
80
|
-
Activity::Output.new(task, semantic), # DISCUSS: do we really want to transport the semantic "in" the object?
|
81
|
-
)
|
82
|
-
],
|
83
|
-
adds: [],
|
79
|
+
wirings: [],
|
80
|
+
adds: [],
|
84
81
|
**terminus_args
|
85
82
|
)
|
86
83
|
end
|