trace_viz 1.0.0 → 1.0.1

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.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +63 -41
  3. data/lib/trace_viz/builders/base_builder.rb +11 -0
  4. data/lib/trace_viz/builders/diagram/base_builder.rb +10 -0
  5. data/lib/trace_viz/builders/diagram/message_builder.rb +96 -0
  6. data/lib/trace_viz/builders/diagram/sequence_builder.rb +50 -0
  7. data/lib/trace_viz/collectors/filters/base_class_filter.rb +3 -1
  8. data/lib/trace_viz/config/validator.rb +1 -1
  9. data/lib/trace_viz/defaults/config.rb +4 -2
  10. data/lib/trace_viz/exporters/base_exporter.rb +26 -5
  11. data/lib/trace_viz/exporters/mermaid_exporter.rb +17 -0
  12. data/lib/trace_viz/exporters/registry.rb +2 -0
  13. data/lib/trace_viz/exporters/text_exporter.rb +2 -24
  14. data/lib/trace_viz/extractors/base_extractor.rb +17 -0
  15. data/lib/trace_viz/extractors/diagram/base_extractor.rb +18 -0
  16. data/lib/trace_viz/extractors/diagram/box_extractor.rb +50 -0
  17. data/lib/trace_viz/extractors/diagram/message_extractor.rb +23 -0
  18. data/lib/trace_viz/extractors/diagram/participant_extractor.rb +37 -0
  19. data/lib/trace_viz/extractors/diagram/processors/message_processor.rb +93 -0
  20. data/lib/trace_viz/formatters/base_formatter.rb +1 -0
  21. data/lib/trace_viz/formatters/base_formatter_factory.rb +23 -0
  22. data/lib/trace_viz/formatters/diagram/sequence/base_formatter.rb +14 -0
  23. data/lib/trace_viz/formatters/diagram/sequence/message_formatter.rb +37 -0
  24. data/lib/trace_viz/formatters/diagram_formatter.rb +10 -0
  25. data/lib/trace_viz/formatters/export/formatter_factory.rb +8 -13
  26. data/lib/trace_viz/formatters/export/summary_group_formatter.rb +1 -1
  27. data/lib/trace_viz/formatters/helpers/digram/action_helper.rb +17 -0
  28. data/lib/trace_viz/formatters/helpers/digram/result_helper.rb +39 -0
  29. data/lib/trace_viz/formatters/helpers/log/params_helper.rb +8 -4
  30. data/lib/trace_viz/formatters/helpers/log/result_helper.rb +3 -3
  31. data/lib/trace_viz/formatters/helpers/log/summary/params_helper.rb +8 -4
  32. data/lib/trace_viz/formatters/helpers/params_helper.rb +8 -4
  33. data/lib/trace_viz/formatters/helpers/result_helper.rb +4 -3
  34. data/lib/trace_viz/formatters/helpers/source_helper.rb +4 -3
  35. data/lib/trace_viz/formatters/helpers/summary/params_helper.rb +7 -3
  36. data/lib/trace_viz/formatters/helpers/summary/source_helper.rb +3 -3
  37. data/lib/trace_viz/formatters/log/formatter_factory.rb +8 -13
  38. data/lib/trace_viz/formatters/log/summary_group_formatter.rb +1 -1
  39. data/lib/trace_viz/helpers/config_helper.rb +4 -0
  40. data/lib/trace_viz/loggers/post_collection_logger.rb +9 -4
  41. data/lib/trace_viz/loggers/trace_logger.rb +3 -6
  42. data/lib/trace_viz/managers/diagram/participant_manager.rb +23 -0
  43. data/lib/trace_viz/models/box.rb +19 -0
  44. data/lib/trace_viz/models/diagram.rb +27 -0
  45. data/lib/trace_viz/models/message.rb +16 -0
  46. data/lib/trace_viz/models/participant.rb +18 -0
  47. data/lib/trace_viz/models.rb +8 -0
  48. data/lib/trace_viz/renderers/base_renderer.rb +6 -3
  49. data/lib/trace_viz/renderers/diagram/sequence_renderer.rb +59 -0
  50. data/lib/trace_viz/renderers/render_context.rb +2 -3
  51. data/lib/trace_viz/renderers/renderer_builder.rb +20 -0
  52. data/lib/trace_viz/renderers/renderer_factory.rb +10 -22
  53. data/lib/trace_viz/renderers/summary_renderer.rb +18 -6
  54. data/lib/trace_viz/renderers/verbose_renderer.rb +6 -6
  55. data/lib/trace_viz/shared/renderer_helper.rb +4 -25
  56. data/lib/trace_viz/syntax/mermaid/sequence_syntax.rb +99 -0
  57. data/lib/trace_viz/trace_data/base.rb +7 -0
  58. data/lib/trace_viz/trace_data/node.rb +9 -3
  59. data/lib/trace_viz/trace_data/root_node.rb +4 -0
  60. data/lib/trace_viz/trace_data/summary_node.rb +5 -9
  61. data/lib/trace_viz/trace_data/trace_point/base.rb +4 -0
  62. data/lib/trace_viz/trace_data/trace_point/method_call.rb +4 -0
  63. data/lib/trace_viz/transformers/base_transformer.rb +29 -0
  64. data/lib/trace_viz/transformers/summary_transformer.rb +70 -0
  65. data/lib/trace_viz/utils/alias_generator.rb +58 -0
  66. data/lib/trace_viz/utils/format/key_value_formatter.rb +42 -0
  67. data/lib/trace_viz/utils/format/value_truncator.rb +123 -0
  68. data/lib/trace_viz/utils.rb +8 -0
  69. data/lib/trace_viz/version.rb +1 -1
  70. metadata +38 -11
  71. data/lib/trace_viz/renderers/summary/node_processor.rb +0 -82
  72. data/lib/trace_viz/utils/format_utils/key_value_formatter.rb +0 -37
  73. data/lib/trace_viz/utils/format_utils/value_truncator.rb +0 -74
  74. data/lib/trace_viz/utils/format_utils.rb +0 -24
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TraceViz
4
+ module Models
5
+ class Box
6
+ attr_reader :participants, :color, :description
7
+
8
+ def initialize(color:, description:)
9
+ @color = color
10
+ @description = description
11
+ @participants = []
12
+ end
13
+
14
+ def add_participant(participant)
15
+ @participants << participant
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TraceViz
4
+ module Models
5
+ class Diagram
6
+ attr_reader :boxes, :participants, :messages
7
+
8
+ def initialize
9
+ @boxes = []
10
+ @participants = []
11
+ @messages = []
12
+ end
13
+
14
+ def add_box(box)
15
+ @boxes << box unless @boxes.include?(box)
16
+ end
17
+
18
+ def add_participant(participant)
19
+ @participants << participant unless @participants.include?(participant)
20
+ end
21
+
22
+ def add_message(message)
23
+ @messages << message
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TraceViz
4
+ module Models
5
+ class Message
6
+ attr_reader :type, :from, :to, :content
7
+
8
+ def initialize(type:, from:, to:, content:)
9
+ @type = type
10
+ @from = from
11
+ @to = to
12
+ @content = content
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TraceViz
4
+ module Models
5
+ class Participant
6
+ attr_accessor :name, :alias_name
7
+
8
+ def initialize(name:, alias_name: nil)
9
+ @name = name
10
+ @alias_name = alias_name
11
+ end
12
+
13
+ def ==(other)
14
+ name == other.name
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ Dir[File.join(__dir__, "models/**/*.rb")].each { |file| require_relative file }
4
+
5
+ module TraceViz
6
+ module Models
7
+ end
8
+ end
@@ -3,8 +3,10 @@
3
3
  module TraceViz
4
4
  module Renderers
5
5
  class BaseRenderer
6
- def initialize(data, context:)
7
- @data = data
6
+ NodeLine = Struct.new(:data, :line)
7
+
8
+ def initialize(collector, context)
9
+ @collector = collector
8
10
  @context = context
9
11
  end
10
12
 
@@ -12,13 +14,14 @@ module TraceViz
12
14
  to_lines.map { |line| line[:line] }.join("\n")
13
15
  end
14
16
 
17
+ # [ { line: 'line1' }, { line: 'line2' } ]
15
18
  def to_lines
16
19
  []
17
20
  end
18
21
 
19
22
  private
20
23
 
21
- attr_reader :data, :context
24
+ attr_reader :collector, :context
22
25
  end
23
26
  end
24
27
  end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../base_renderer"
4
+ require "trace_viz/builders/diagram/sequence_builder"
5
+ require "trace_viz/syntax/mermaid/sequence_syntax"
6
+
7
+ module TraceViz
8
+ module Renderers
9
+ module Diagram
10
+ class SequenceRenderer < BaseRenderer
11
+ def initialize(collector, context)
12
+ super(collector, context)
13
+
14
+ @builder = Builders::Diagram::SequenceBuilder.new(collector)
15
+ @syntax = Syntax::Mermaid::SequenceSyntax.new
16
+ @diagram = builder.build
17
+ end
18
+
19
+ def to_lines
20
+ [
21
+ header_line,
22
+ *render_boxes,
23
+ *render_messages,
24
+ ]
25
+ end
26
+
27
+ private
28
+
29
+ attr_reader :builder, :diagram, :syntax
30
+
31
+ def header_line
32
+ NodeLine.new(nil, syntax.header)
33
+ end
34
+
35
+ def render_boxes
36
+ diagram.boxes.flat_map { |box| render_box(box) }
37
+ end
38
+
39
+ def render_messages
40
+ diagram.messages.map { |message| NodeLine.new(nil, syntax.message(message)) }
41
+ end
42
+
43
+ def render_box(box)
44
+ [
45
+ NodeLine.new(nil, syntax.box_start(box)),
46
+ *render_participants(box),
47
+ NodeLine.new(nil, syntax.box_end(box)),
48
+ ]
49
+ end
50
+
51
+ def render_participants(box)
52
+ box.participants.map do |participant|
53
+ NodeLine.new(nil, syntax.participant(participant))
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -3,11 +3,10 @@
3
3
  module TraceViz
4
4
  module Renderers
5
5
  class RenderContext
6
- attr_reader :formatter_factory, :group_keys
6
+ attr_reader :formatter_factory
7
7
 
8
- def initialize(formatter_factory:, group_keys: [])
8
+ def initialize(formatter_factory:)
9
9
  @formatter_factory = formatter_factory
10
- @group_keys = group_keys
11
10
  end
12
11
 
13
12
  def fetch_formatter(key)
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "render_context"
4
+ require_relative "renderer_factory"
5
+
6
+ module TraceViz
7
+ module Renderers
8
+ class RendererBuilder
9
+ class << self
10
+ def build(collector, key:, formatter_factory:)
11
+ raise ArgumentError, "Renderer key must be provided" if key.nil?
12
+
13
+ render_context = RenderContext.new(formatter_factory: formatter_factory)
14
+ renderer_factory = RendererFactory.new(collector, render_context)
15
+ renderer_factory.build(key)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require_relative "verbose_renderer"
4
4
  require_relative "summary_renderer"
5
+ require_relative "diagram/sequence_renderer"
5
6
 
6
7
  module TraceViz
7
8
  module Renderers
@@ -9,32 +10,19 @@ module TraceViz
9
10
  RENDERERS = {
10
11
  verbose: VerboseRenderer,
11
12
  summary: SummaryRenderer,
13
+ sequence_diagram: Diagram::SequenceRenderer,
12
14
  }.freeze
13
15
 
14
- class << self
15
- def build(mode, collector, context:)
16
- renderer_class = fetch_renderer_class(mode)
17
- renderer_class.new(determine_input(mode, collector), context: context)
18
- end
19
-
20
- private
16
+ def initialize(collector, context)
17
+ @collector = collector
18
+ @context = context
19
+ end
21
20
 
22
- def fetch_renderer_class(mode)
23
- RENDERERS.fetch(mode) do
24
- raise ArgumentError, "Unknown mode: #{mode}. Valid modes are: #{RENDERERS.keys.join(", ")}"
25
- end
26
- end
21
+ def build(key)
22
+ renderer_class = RENDERERS[key]
23
+ raise ArgumentError, "Invalid renderer key: #{key}" unless renderer_class
27
24
 
28
- def determine_input(mode, collector)
29
- case mode
30
- when :verbose
31
- collector.collection
32
- when :summary
33
- collector.hierarchy.root
34
- else
35
- raise ArgumentError, "Invalid mode for input determination: #{mode}"
36
- end
37
- end
25
+ renderer_class.new(@collector, @context)
38
26
  end
39
27
  end
40
28
  end
@@ -1,21 +1,33 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "base_renderer"
4
- require_relative "summary/node_processor"
4
+ require "trace_viz/transformers/summary_transformer"
5
5
 
6
6
  module TraceViz
7
7
  module Renderers
8
8
  class SummaryRenderer < BaseRenderer
9
9
  def to_lines
10
- return [] unless valid_children?(data)
11
-
12
- NodeProcessor.new(data.children, context).process
10
+ render_nodes(data.children)
13
11
  end
14
12
 
15
13
  private
16
14
 
17
- def valid_children?(node)
18
- node.respond_to?(:children) && node.children.any?
15
+ def data
16
+ Transformers::SummaryTransformer.new(collector).transform
17
+ end
18
+
19
+ def render_nodes(nodes)
20
+ nodes.flat_map { |node| render_node(node) }
21
+ end
22
+
23
+ def render_node(node)
24
+ node_line = NodeLine.new(node.data, format_node(node.data))
25
+
26
+ [node_line] + render_nodes(node.children)
27
+ end
28
+
29
+ def format_node(data)
30
+ context.fetch_formatter(data.key).call(data)
19
31
  end
20
32
  end
21
33
  end
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "base_renderer"
4
- require "trace_viz/formatters/log/formatter_factory"
5
4
 
6
5
  module TraceViz
7
6
  module Renderers
@@ -12,17 +11,18 @@ module TraceViz
12
11
 
13
12
  private
14
13
 
14
+ def data
15
+ collector.collection
16
+ end
17
+
15
18
  def traverse_data(data)
16
19
  data.map do |trace_data|
17
- {
18
- line: format_for(trace_data),
19
- trace_data: trace_data,
20
- }
20
+ NodeLine.new(trace_data, format_for(trace_data))
21
21
  end
22
22
  end
23
23
 
24
24
  def format_for(trace_data)
25
- context.fetch_formatter(trace_data.event).call(trace_data)
25
+ context.fetch_formatter(trace_data.key).call(trace_data)
26
26
  end
27
27
  end
28
28
  end
@@ -1,27 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "trace_viz/renderers/renderer_factory"
4
- require "trace_viz/renderers/render_context"
5
- require "trace_viz/formatters/export/formatter_factory"
6
- require "trace_viz/formatters/log/formatter_factory"
7
-
8
3
  module TraceViz
9
4
  module Shared
10
5
  module RendererHelper
11
- def build_renderer(collector, formatter_factory)
12
- raise ArgumentError, "Collector cannot be nil" unless collector
13
- raise ArgumentError, "FormatterFactory cannot be nil" unless formatter_factory
14
-
15
- mode = fetch_config(collector, :mode)
16
- group_keys = fetch_config(collector, :group_keys)
17
-
18
- context = Renderers::RenderContext.new(
19
- formatter_factory: formatter_factory,
20
- group_keys: group_keys,
21
- )
22
- Renderers::RendererFactory.build(mode, collector, context: context)
23
- end
24
-
25
6
  def process_lines(lines, &block)
26
7
  return [] unless lines.is_a?(Array)
27
8
 
@@ -33,13 +14,11 @@ module TraceViz
33
14
 
34
15
  private
35
16
 
36
- def fetch_config(collector, key)
37
- collector.config.general[key]
38
- end
39
-
40
17
  def validate_line_structure!(line)
41
- raise ArgumentError, "Line must be a Hash" unless line.is_a?(Hash)
42
- raise KeyError, "Line must include a :line key" unless line.key?(:line)
18
+ unless line.respond_to?(:line) && line.respond_to?(:data)
19
+ raise ArgumentError,
20
+ "Invalid line structure: #{line.inspect}. Expected an object with :line and :data attributes."
21
+ end
43
22
  end
44
23
  end
45
24
  end
@@ -0,0 +1,99 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "trace_viz/helpers"
4
+
5
+ module TraceViz
6
+ module Syntax
7
+ module Mermaid
8
+ class SequenceSyntax
9
+ include Helpers::ConfigHelper
10
+
11
+ def header
12
+ "sequenceDiagram"
13
+ end
14
+
15
+ def box_start(box)
16
+ "#{indent}box #{sanitize_name(box.color)} #{sanitize_name(box.description)}"
17
+ end
18
+
19
+ def box_end(_box)
20
+ "#{indent}end"
21
+ end
22
+
23
+ def participant(participant)
24
+ alias_name = sanitize_name(participant.alias_name)
25
+ name = sanitize_name(participant.name)
26
+ "#{indent}participant #{alias_name} as #{name}"
27
+ end
28
+
29
+ def message(message)
30
+ from = sanitize_name(message.from&.alias_name)
31
+ to = sanitize_name(message.to&.alias_name)
32
+ content = sanitize_name(message.content)
33
+
34
+ message_syntax(message.type, from, to, content)
35
+ end
36
+
37
+ private
38
+
39
+ def message_syntax(type, from, to, content)
40
+ case type
41
+ when :call
42
+ "#{indent}#{from} ->> #{to}: #{content}"
43
+ when :return
44
+ "#{indent}#{from} -->> #{to}: #{content}"
45
+ when :activate
46
+ "#{indent}activate #{to}"
47
+ when :deactivate
48
+ "#{indent}deactivate #{to}"
49
+ when :loop_start
50
+ "#{indent}loop #{content}"
51
+ when :loop_end
52
+ "#{indent}end"
53
+ when :note
54
+ "#{indent}Note over #{to}: #{content}"
55
+ else
56
+ raise ArgumentError, "Unsupported message type: #{type}"
57
+ end
58
+ end
59
+
60
+ def indent
61
+ " " * fetch_general_config(:tab_size)
62
+ end
63
+
64
+ def sanitize_name(name)
65
+ return "" if name.nil?
66
+
67
+ # Convert Symbols to Strings and handle string sanitization
68
+ name = name.to_s.dup
69
+
70
+ # Handle class name pattern
71
+ name.sub!(/^#<Class:/, "[Class]")
72
+ name.sub!(/>$/, "")
73
+
74
+ # Replace unconventional method names with readable alternatives
75
+ name.gsub!("[]=", "set_value")
76
+ name.gsub!(/<<\z/, "append")
77
+ name.gsub!("[]", "get_value")
78
+ name.gsub!(/\A=/, "assign")
79
+
80
+ # Escape specific HTML characters in one pass
81
+ name.gsub!(/[<>:]/) do |char|
82
+ case char
83
+ when "<"
84
+ "&lt;"
85
+ when ">"
86
+ "&gt;"
87
+ # when ":"
88
+ # "&#58;"
89
+ else
90
+ char
91
+ end
92
+ end
93
+
94
+ name
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
@@ -15,6 +15,13 @@ module TraceViz
15
15
  record_timestamp
16
16
  end
17
17
 
18
+ #
19
+ # Represents trace data type code
20
+ #
21
+ def key
22
+ :base
23
+ end
24
+
18
25
  def event
19
26
  raise NotImplementedError
20
27
  end
@@ -15,9 +15,15 @@ module TraceViz
15
15
  @children = []
16
16
  end
17
17
 
18
- def add_child(child)
19
- child.parent = self
20
- @children << child
18
+ def add_child(node)
19
+ node.parent = self
20
+ @children << node
21
+ end
22
+
23
+ def add_children(nodes)
24
+ nodes.each do |node|
25
+ add_child(node)
26
+ end
21
27
  end
22
28
 
23
29
  def to_h
@@ -12,6 +12,10 @@ module TraceViz
12
12
  @parent = nil
13
13
  end
14
14
 
15
+ def root?
16
+ true
17
+ end
18
+
15
19
  def parent=(_parent)
16
20
  raise NoMethodError, "RootNode cannot have a parent"
17
21
  end
@@ -27,7 +27,11 @@ module TraceViz
27
27
  add_children(representative_node.children)
28
28
  end
29
29
 
30
- def average_duration
30
+ def key
31
+ :summary_group
32
+ end
33
+
34
+ def duration
31
35
  return 0 if count.zero?
32
36
 
33
37
  total_duration / count
@@ -36,14 +40,6 @@ module TraceViz
36
40
  def total_duration
37
41
  children.map(&:duration).sum
38
42
  end
39
-
40
- private
41
-
42
- def add_children(nodes)
43
- nodes.each do |node|
44
- add_child(node)
45
- end
46
- end
47
43
  end
48
44
  end
49
45
  end
@@ -26,6 +26,10 @@ module TraceViz
26
26
  assign_ids
27
27
  end
28
28
 
29
+ def key
30
+ event
31
+ end
32
+
29
33
  def duration
30
34
  0
31
35
  end
@@ -17,6 +17,10 @@ module TraceViz
17
17
  populate_params
18
18
  end
19
19
 
20
+ def result
21
+ method_return&.result
22
+ end
23
+
20
24
  def link(method_return)
21
25
  @method_return = method_return
22
26
  end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "trace_viz/helpers/config_helper"
4
+
5
+ module TraceViz
6
+ module Transformers
7
+ TransformedNode = Struct.new(:data, :children)
8
+
9
+ class BaseTransformer
10
+ include Helpers::ConfigHelper
11
+
12
+ def initialize(collector)
13
+ @collector = collector
14
+ end
15
+
16
+ def transform
17
+ raise NotImplementedError
18
+ end
19
+
20
+ private
21
+
22
+ attr_reader :collector
23
+
24
+ def data
25
+ raise NotImplementedError
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "trace_viz/trace_data/summary_node"
4
+ require_relative "base_transformer"
5
+
6
+ module TraceViz
7
+ module Transformers
8
+ class SummaryTransformer < BaseTransformer
9
+ def transform
10
+ return root_node unless valid_children?(root_node)
11
+
12
+ TransformedNode.new(
13
+ root_node,
14
+ transform_nodes(root_node.children),
15
+ )
16
+ end
17
+
18
+ private
19
+
20
+ def valid_children?(node)
21
+ node.respond_to?(:children) && node.children.any?
22
+ end
23
+
24
+ def root_node
25
+ collector.hierarchy.root
26
+ end
27
+
28
+ def transform_nodes(nodes)
29
+ nodes.group_by { |node| node_key(node) }
30
+ .map { |_key, group| transform_group(group) }
31
+ end
32
+
33
+ def node_key(node)
34
+ group_keys.map { |key| fetch_node_attribute(node, key) }
35
+ end
36
+
37
+ def fetch_node_attribute(node, key)
38
+ node.respond_to?(key) ? node.public_send(key) : nil
39
+ end
40
+
41
+ def transform_group(group)
42
+ if group.size > 1
43
+ create_summary_node(group)
44
+ else
45
+ create_single_node(group.first)
46
+ end
47
+ end
48
+
49
+ def create_summary_node(group)
50
+ summary_node = TraceData::SummaryNode.new(group: group)
51
+
52
+ TransformedNode.new(
53
+ summary_node,
54
+ transform_nodes(summary_node.children),
55
+ )
56
+ end
57
+
58
+ def create_single_node(node)
59
+ TransformedNode.new(
60
+ node,
61
+ transform_nodes(node.children),
62
+ )
63
+ end
64
+
65
+ def group_keys
66
+ fetch_general_config(:group_keys)
67
+ end
68
+ end
69
+ end
70
+ end