Class: Rhales::Hydrator
- Inherits:
-
Object
- Object
- Rhales::Hydrator
- Defined in:
- lib/rhales/hydrator.rb
Overview
Data Hydrator for RSFC client-side data injection
RSFC Security Model: Server-to-Client Security Boundary
The Hydrator enforces a critical security boundary between server and client:
Server Side (Template Rendering)
- Templates have FULL server context access (like ERB/HAML)
- Can access user objects, database connections, internal APIs
- Can access secrets, configuration, authentication state
- Can process sensitive business logic
Client Side (Data Hydration)
- Only data declared in section reaches the browser
- Creates explicit allowlist like designing a REST API
- Server-side variable interpolation processes secrets safely
- JSON serialization validates data structure
Process Flow
- Server processes section with full context access
- Variables like {user{user.name} are interpolated server-side
- Result is serialized as JSON and sent to client
- Client receives only the processed, safe data
Example
```rue
{ "user_name": "{user{user.name}", // Safe: just the name "theme": "{user{user.theme_preference}" // Safe: just the theme }```
Server template can access {user{user.admin?} and {internal_config}, but client only gets the declared user_name and theme values.
This creates an API-like boundary where data is serialized once and parsed once, enforcing the same security model as REST endpoints.
Note: With the new two-pass architecture, the Hydrator’s role is greatly simplified. All data merging happens server-side in the HydrationDataAggregator, so this class only handles JSON generation for individual templates (used during the aggregation phase).
Defined Under Namespace
Classes: HydrationError, JSONSerializationError
Instance Attribute Summary collapse
-
#context ⇒ Object
readonly
Returns the value of attribute context.
-
#parser ⇒ Object
readonly
Returns the value of attribute parser.
-
#window_attribute ⇒ Object
readonly
Returns the value of attribute window_attribute.
Class Method Summary collapse
-
.generate(parser, context) ⇒ Object
Convenience method to generate hydration HTML DEPRECATED: Use the two-pass rendering architecture instead.
-
.generate_data_hash(parser, context) ⇒ Object
Generate data hash (for internal processing).
-
.generate_json(parser, context) ⇒ Object
Generate only JSON data (for testing or API endpoints).
Instance Method Summary collapse
-
#build_template_path ⇒ Object
private
Build template path with line number for error reporting (Used by HydrationDataAggregator).
-
#generate_hydration_html ⇒ Object
This method is now deprecated in favor of the two-pass architecture It’s kept for backward compatibility but will be removed in future versions.
-
#initialize(parser, context) ⇒ Hydrator
constructor
A new instance of Hydrator.
-
#process_data_section ⇒ Object
Process section and return JSON string.
-
#process_data_variables(data_content) ⇒ Object
private
Process variable interpolations in data section Uses Rhales consistently for all template processing.
-
#processed_data_hash ⇒ Object
Get processed data as Ruby hash (for internal use).
-
#validate_json(json_string) ⇒ Object
private
Validate that processed content is valid JSON.
Constructor Details
#initialize(parser, context) ⇒ Hydrator
Returns a new instance of Hydrator.
57 58 59 60 61 |
# File 'lib/rhales/hydrator.rb', line 57 def initialize(parser, context) @parser = parser @context = context @window_attribute = parser.window_attribute || 'data' end |
Instance Attribute Details
#context ⇒ Object (readonly)
Returns the value of attribute context.
55 56 57 |
# File 'lib/rhales/hydrator.rb', line 55 def context @context end |
#parser ⇒ Object (readonly)
Returns the value of attribute parser.
55 56 57 |
# File 'lib/rhales/hydrator.rb', line 55 def parser @parser end |
#window_attribute ⇒ Object (readonly)
Returns the value of attribute window_attribute.
55 56 57 |
# File 'lib/rhales/hydrator.rb', line 55 def window_attribute @window_attribute end |
Class Method Details
.generate(parser, context) ⇒ Object
Convenience method to generate hydration HTML DEPRECATED: Use the two-pass rendering architecture instead
125 126 127 128 |
# File 'lib/rhales/hydrator.rb', line 125 def generate(parser, context) warn '[DEPRECATION] Hydrator.generate is deprecated. Use the two-pass rendering architecture instead.' new(parser, context).generate_hydration_html end |
.generate_data_hash(parser, context) ⇒ Object
Generate data hash (for internal processing)
136 137 138 |
# File 'lib/rhales/hydrator.rb', line 136 def generate_data_hash(parser, context) new(parser, context).processed_data_hash end |
.generate_json(parser, context) ⇒ Object
Generate only JSON data (for testing or API endpoints)
131 132 133 |
# File 'lib/rhales/hydrator.rb', line 131 def generate_json(parser, context) new(parser, context).process_data_section end |
Instance Method Details
#build_template_path ⇒ Object (private)
Build template path with line number for error reporting (Used by HydrationDataAggregator)
111 112 113 114 115 116 117 118 119 120 |
# File 'lib/rhales/hydrator.rb', line 111 def build_template_path data_node = @parser.section_node('data') line_number = data_node ? data_node.location.start_line : 1 if @parser.file_path "#{@parser.file_path}:#{line_number}" else "<inline>:#{line_number}" end end |
#generate_hydration_html ⇒ Object
This method is now deprecated in favor of the two-pass architecture It’s kept for backward compatibility but will be removed in future versions
65 66 67 68 |
# File 'lib/rhales/hydrator.rb', line 65 def generate_hydration_html warn '[DEPRECATION] Hydrator#generate_hydration_html is deprecated. Use the two-pass rendering architecture instead.' '' end |
#process_data_section ⇒ Object
Process section and return JSON string
71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/rhales/hydrator.rb', line 71 def process_data_section data_content = @parser.section('data') return '{}' unless data_content # Process variable interpolations in the data section processed_content = process_data_variables(data_content) # Validate and return JSON validate_json(processed_content) processed_content rescue JSON::ParserError => ex raise JSONSerializationError, "Invalid JSON in data section: #{ex.}" end |
#process_data_variables(data_content) ⇒ Object (private)
Process variable interpolations in data section Uses Rhales consistently for all template processing
97 98 99 100 |
# File 'lib/rhales/hydrator.rb', line 97 def process_data_variables(data_content) rhales = TemplateEngine.new(data_content, @context) rhales.render end |
#processed_data_hash ⇒ Object
Get processed data as Ruby hash (for internal use)
86 87 88 89 90 91 |
# File 'lib/rhales/hydrator.rb', line 86 def processed_data_hash json_string = process_data_section JSON.parse(json_string) rescue JSON::ParserError => ex raise JSONSerializationError, "Cannot parse processed data as JSON: #{ex.}" end |
#validate_json(json_string) ⇒ Object (private)
Validate that processed content is valid JSON
103 104 105 106 107 |
# File 'lib/rhales/hydrator.rb', line 103 def validate_json(json_string) JSON.parse(json_string) rescue JSON::ParserError => ex raise JSONSerializationError, "Processed data section is not valid JSON: #{ex.}" end |