Exception: Rhales::HydrationCollisionError

Inherits:
Error
  • Object
show all
Defined in:
lib/rhales/errors/hydration_collision_error.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(window_attribute, first_path, conflict_path) ⇒ HydrationCollisionError

Returns a new instance of HydrationCollisionError.



7
8
9
10
11
12
13
# File 'lib/rhales/errors/hydration_collision_error.rb', line 7

def initialize(window_attribute, first_path, conflict_path)
  @window_attribute = window_attribute
  @first_path       = first_path
  @conflict_path    = conflict_path

  super(build_message)
end

Instance Attribute Details

#conflict_pathObject (readonly)

Returns the value of attribute conflict_path.



5
6
7
# File 'lib/rhales/errors/hydration_collision_error.rb', line 5

def conflict_path
  @conflict_path
end

#first_pathObject (readonly)

Returns the value of attribute first_path.



5
6
7
# File 'lib/rhales/errors/hydration_collision_error.rb', line 5

def first_path
  @first_path
end

#window_attributeObject (readonly)

Returns the value of attribute window_attribute.



5
6
7
# File 'lib/rhales/errors/hydration_collision_error.rb', line 5

def window_attribute
  @window_attribute
end

Instance Method Details

#base_name_from_path(path) ⇒ Object (private)



70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/rhales/errors/hydration_collision_error.rb', line 70

def base_name_from_path(path)
  # Extract a base name from the file path for suggestion
  filename = path.split('/').last.split('.').first
  case filename
  when 'index', 'main', 'application'
    'page'
  when /^_/, 'partial'
    'partial'
  when 'header', 'footer', 'sidebar', 'nav'
    filename
  else
    filename.gsub(/[^a-zA-Z0-9]/, '').downcase
  end
end

#build_messageObject (private)



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/rhales/errors/hydration_collision_error.rb', line 21

def build_message
  <<~MSG.strip
    Window attribute collision detected

    Attribute: '#{@window_attribute}'
    First defined: #{@first_path}#{extract_tag_content(@first_path)}
    Conflict with: #{@conflict_path}#{extract_tag_content(@conflict_path)}

    Quick fixes:
      1. Rename one: <data window="#{suggested_alternative_name}">
      2. Enable merging: <data window="#{@window_attribute}" merge="deep">

    Learn more: https://rhales.dev/docs/data-boundaries#collisions
  MSG
end

#extract_tag_content(path) ⇒ Object (private)



37
38
39
40
41
42
43
44
45
# File 'lib/rhales/errors/hydration_collision_error.rb', line 37

def extract_tag_content(path)
  # If the path includes the actual tag content after the line number,
  # extract and format it for display
  if path.include?(':<data')
    tag_match = path.match(/(:.*?<data[^>]*>)/)
    return "\n               #{tag_match[1].sub(/^:/, '')}" if tag_match
  end
  ''
end

#messageObject



15
16
17
# File 'lib/rhales/errors/hydration_collision_error.rb', line 15

def message
  build_message
end

#suggested_alternative_nameObject (private)



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/rhales/errors/hydration_collision_error.rb', line 47

def suggested_alternative_name
  # For specific known patterns, use the first defined location
  # This provides a more predictable suggestion
  if @window_attribute == 'appState' && @first_path.include?('header')
    'headerState'
  elsif @window_attribute == 'data'
    # For generic 'data', use the conflict path to generate unique name
    base_name_from_path(@conflict_path) + 'Data'
  else
    # For other cases, suggest a simple modification
    case @window_attribute
    when /Data$/
      @window_attribute.sub(/Data$/, 'State')
    when /State$/
      @window_attribute.sub(/State$/, 'Config')
    when /Config$/
      @window_attribute.sub(/Config$/, 'Settings')
    else
      @window_attribute + 'Data'
    end
  end
end