Skip to content

Commit a885f3e

Browse files
authored
Releases v1.5.0 (#80)
1 parent d329151 commit a885f3e

File tree

3 files changed

+325
-2
lines changed

3 files changed

+325
-2
lines changed

CHANGELOG.md

Lines changed: 323 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,329 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [1.5.0] 2025-08-29
11+
12+
### Added
13+
14+
#### Modern API with Relaxed Parsing Mode
15+
16+
- **`Statifier.parse/2` Function**: New streamlined API combining parsing and validation in one call
17+
- **3-Tuple Return Format**: Returns `{:ok, document, warnings}` for comprehensive result handling
18+
- **Automatic Validation**: Validates documents by default, returns errors as `{:error, {:validation_errors, errors, warnings}}`
19+
- **Options Support**: Accepts keyword options for parsing customization
20+
- **Relaxed Mode Support**: Passes options to SCXML.parse for enhanced flexibility
21+
- **Skip Validation Option**: `validate: false` returns unvalidated documents for advanced use cases
22+
23+
- **Enhanced `SCXML.parse/2` with XML Normalization**: Comprehensive relaxed parsing mode for simplified SCXML authoring
24+
- **XML Declaration Handling**: Optional XML declaration addition with `xml_declaration` option (default: false to preserve line numbers)
25+
- **Default Namespace Addition**: Automatically adds W3C SCXML namespace when missing
26+
- **Default Version Addition**: Automatically adds version="1.0" when missing
27+
- **Backwards Compatible**: Preserves existing XML declarations and attributes when present
28+
- **Test-Friendly**: Eliminates XML boilerplate for cleaner test documents
29+
30+
- **Validation Status Tracking**: Added `validated` field to Document struct for better API clarity
31+
- **Document.validated**: Boolean field indicating whether document has been validated
32+
- **Interpreter Optimization**: Skips redundant validation for pre-validated documents
33+
- **Helper Functions**: `Statifier.validated?/1` and `Statifier.parse_only/2` for API completeness
34+
35+
#### Basic Send Element Support
36+
37+
- **`<send>` Element Implementation**: Comprehensive Phase 1 support for SCXML send elements with internal event communication
38+
- **`Statifier.Actions.SendAction`**: Complete data structure with event_expr, target_expr, type_expr, delay_expr, namelist support
39+
- **`Statifier.Actions.SendParam`**: Support for `<param>` child elements with name/expr attributes
40+
- **`Statifier.Actions.SendContent`**: Support for `<content>` child elements with expr attribute
41+
- **Expression Evaluation**: Dynamic event names, target resolution, and data payload construction
42+
- **Internal Event Routing**: Events sent to #_internal properly queued and processed in state machine
43+
- **Transition Actions**: Send elements within `<transition>` elements with proper execution order
44+
45+
- **Enhanced Parser Support**: Extended SCXML parser for comprehensive send element parsing
46+
- **Send Element Parsing**: Complete parsing of `<send>` elements with all W3C attributes
47+
- **Child Element Support**: Parsing of nested `<param>` and `<content>` elements
48+
- **Location Tracking**: Precise source location tracking for all send-related elements
49+
- **Handler Integration**: SAX-based parsing with proper state stack management
50+
51+
- **ActionExecutor Integration**: Enhanced action execution framework with send support
52+
- **Transition Action Execution**: Added `execute_transition_actions/3` for actions within transitions
53+
- **Proper Action Order**: SCXML-compliant action execution (exit → transition → entry)
54+
- **Pipeline Programming**: Refactored parameter order for better |> operator usage
55+
56+
#### StateHierarchy Module Extraction
57+
58+
- **`Statifier.StateHierarchy`**: 422-line dedicated module extracted from Interpreter for hierarchy operations
59+
- **8 Core Functions**: `descendant_of?/3`, `compute_lcca/3`, `get_ancestor_path/2`, `get_parallel_ancestors/2`, etc.
60+
- **Reduced Interpreter Size**: 824 → 636 lines (23% reduction, 188 lines extracted)
61+
- **Single Responsibility**: All state hierarchy logic consolidated in focused module
62+
- **Comprehensive Testing**: 45 new tests covering complex hierarchies, edge cases, parallel regions
63+
64+
#### Hierarchy Caching Infrastructure
65+
66+
- **`Statifier.HierarchyCache`**: O(1) performance optimization system for expensive hierarchy operations
67+
- **Pre-computed Relationships**: Ancestor paths, LCCA matrix, descendant sets, parallel regions
68+
- **Performance Gains**: 5-15x speedup for hierarchy operations (O(depth) → O(1))
69+
- **Memory Efficient**: ~1.5-2x memory overhead for significant performance benefits
70+
- **Automatic Building**: Cache built during validation phase for valid documents only
71+
- **Statistics Tracking**: Build time, memory usage, and cache size metrics
72+
73+
- **Enhanced Document Structure**: Extended Document struct with hierarchy_cache field
74+
- **Integration with Validation**: Cache built in Validator.finalize/2 pipeline
75+
- **Helper Functions**: `Document.get_all_states/1` for comprehensive state enumeration
76+
- **Benchmark Testing**: Performance and memory usage validation with dedicated benchmarks
77+
78+
#### TransitionResolver Module Extraction
79+
80+
- **`Statifier.Interpreter.TransitionResolver`**: 161-line focused module extracted from Interpreter
81+
- **Single Responsibility**: Dedicated to SCXML transition conflict resolution and matching
82+
- **6 Core Functions**: `find_enabled_transitions/2`, `find_eventless_transitions/1`, `resolve_transition_conflicts/2`, etc.
83+
- **SCXML-Compliant**: Implements W3C specification for optimal transition set computation
84+
- **Comprehensive Testing**: 300 lines of tests with 12 test cases covering all scenarios
85+
- **Better Maintainability**: Reduces Interpreter complexity from 655 to 581 lines (11% reduction)
86+
87+
### Changed
88+
89+
#### API Modernization and Backwards Compatibility
90+
91+
- **⚠️ BREAKING**: Updated all test files to use new 3-tuple `Statifier.parse/2` API
92+
- **Comprehensive Migration**: All 857 tests updated to new API format
93+
- **Maintained Coverage**: All tests continue passing with enhanced API
94+
- **Improved Test Clarity**: 3-tuple format provides better access to warnings in tests
95+
96+
- **Streamlined Main Module**: Complete rewrite of `/lib/statifier.ex` with modern architecture
97+
- **New Functions**: `parse/2`, `parse_only/2`, `validated?/1` for comprehensive API coverage
98+
- **Error Handling**: Enhanced error handling with `handle_validation/2` helper
99+
- **Reduced Nesting**: Improved code maintainability with better function organization
100+
- **Options Integration**: Seamless integration with relaxed parsing options
101+
102+
#### Code Quality and Performance Improvements
103+
104+
- **Perfect Credo Compliance**: Achieved 0 issues across 863 analyzed modules/functions
105+
- **Function Nesting Depth**: Fixed all nesting depth violations in StateHierarchy module
106+
- **Helper Function Extraction**: Added `check_descendant_relationship/3`, `lookup_lcca_in_matrix/3`, `normalize_lcca_key/2`
107+
- **Clean Architecture**: Better separation of concerns and improved readability
108+
- **Benchmark Test Configuration**: Added Credo disable for IO.puts in benchmark tests
109+
110+
- **Major Interpreter Refactoring**: Comprehensive architectural improvements for better maintainability
111+
- **Module Extraction Benefits**: StateHierarchy, TransitionResolver, and HierarchyCache provide focused functionality
112+
- **Performance Optimizations**: O(1) hierarchy operations with pre-computed cache infrastructure
113+
- **Pipeline Programming**: Enhanced parameter ordering for better Elixir |> operator usage
114+
- **Action Execution Improvements**: Proper SCXML-compliant action execution order and integration
115+
- **Future Extensibility**: Clean architecture prepared for advanced SCXML features and optimizations
116+
117+
#### Enhanced Action Execution Architecture
118+
119+
- **ActionExecutor Parameter Refactoring**: Improved parameter ordering for better Elixir programming patterns
120+
- **StateChart First**: All execute_*_actions functions now put state_chart as first parameter
121+
- **Pipeline Friendly**: Better |> operator support for functional programming style
122+
- **Transition Actions**: New `execute_transition_actions/3` function for actions within transitions
123+
- **Separation of Concerns**: Moved transition action execution from Interpreter to ActionExecutor
124+
125+
### Fixed
126+
127+
#### XML Normalization and Location Tracking
128+
129+
- **Version Attribute Detection**: Fixed regex pattern in `maybe_add_default_version/1` for proper version attribute recognition
130+
- **Location Tracking Preservation**: Ensured line number accuracy maintained with optional XML declaration
131+
- **Function Signature Conflicts**: Resolved parse/1 vs parse/2 function definition conflicts
132+
133+
#### Test Infrastructure Improvements
134+
135+
- **Location Tracking Tests**: Updated location-specific tests to include XML declarations for accurate line numbers
136+
- **TransitionResolver Integration**: Fixed StateChart field name issues and event timing in extracted module tests
137+
- **Comprehensive Test Coverage**: All 857 tests passing with new architecture and API changes
138+
139+
### Technical Improvements
140+
141+
#### Enhanced Developer Experience
142+
143+
- **Simplified SCXML Authoring**: Relaxed parsing mode eliminates repetitive XML boilerplate
144+
- **No XML Declaration Required**: Tests can omit `<?xml version="1.0" encoding="UTF-8"?>`
145+
- **No Namespace Required**: Automatic W3C SCXML namespace addition
146+
- **No Version Required**: Automatic version="1.0" addition
147+
- **Cleaner Test Documents**: Focus on state machine logic rather than XML syntax
148+
149+
- **Better Error Messages**: Enhanced validation error reporting with maintained source location accuracy
150+
- **Improved API Consistency**: Uniform return patterns and option handling across all parsing functions
151+
- **Comprehensive Documentation**: Updated all function documentation with examples and options
152+
153+
#### Performance and Quality Metrics
154+
155+
- **All Quality Gates Pass**: Format ✓ Test (857/857) ✓ Credo (0 issues) ✓ Dialyzer ✓
156+
- **Comprehensive Test Coverage**: 857 total tests with significant new module coverage
157+
- **New Test Modules**: SendAction (236 lines), StateHierarchy (591 lines), TransitionResolver (313 lines)
158+
- **Advanced Testing**: Handler (483 lines), StateStack (453 lines), HierarchyCache (524 lines)
159+
- **Performance Benchmarks**: HierarchyCache benchmarks demonstrate 5-15x performance improvements
160+
- **Memory Efficiency**: O(1) hierarchy operations with intelligent caching system
161+
- **Production Ready**: All functionality thoroughly tested with comprehensive edge case coverage
162+
- **Architecture Quality**: Clean separation of concerns with focused, testable modules
163+
164+
### Examples
165+
166+
#### New Streamlined API
167+
168+
```elixir
169+
# Modern API - Parse and validate in one step
170+
{:ok, document, warnings} = Statifier.parse(xml)
171+
172+
# Parse without validation for advanced use cases
173+
{:ok, document} = Statifier.parse_only(xml)
174+
175+
# Check validation status
176+
validated = Statifier.validated?(document) # true/false
177+
178+
# Skip validation explicitly
179+
{:ok, document, []} = Statifier.parse(xml, validate: false)
180+
```
181+
182+
#### Relaxed XML Parsing Mode
183+
184+
```elixir
185+
# Before v1.5.0 - Full XML boilerplate required
186+
xml = """
187+
<?xml version="1.0" encoding="UTF-8"?>
188+
<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" initial="start">
189+
<state id="start"/>
190+
</scxml>
191+
"""
192+
193+
# After v1.5.0 - Clean, minimal syntax
194+
xml = """
195+
<scxml initial="start">
196+
<state id="start"/>
197+
</scxml>
198+
"""
199+
200+
{:ok, document, warnings} = Statifier.parse(xml)
201+
# XML declaration, namespace, and version automatically added
202+
```
203+
204+
#### XML Declaration Control
205+
206+
```elixir
207+
# Preserve line numbers (default behavior)
208+
{:ok, document, warnings} = Statifier.parse(minimal_xml)
209+
210+
# Add XML declaration explicitly
211+
{:ok, document, warnings} = Statifier.parse(minimal_xml, xml_declaration: true)
212+
```
213+
214+
#### Error Handling Examples
215+
216+
```elixir
217+
# Validation errors with enhanced format
218+
case Statifier.parse(invalid_xml) do
219+
{:ok, document, warnings} ->
220+
# Success with optional warnings
221+
{:error, {:validation_errors, errors, warnings}} ->
222+
# Validation failed with detailed errors
223+
{:error, reason} ->
224+
# Parsing failed
225+
end
226+
```
227+
228+
#### Send Element Usage
229+
230+
```xml
231+
<scxml initial="waiting">
232+
<state id="waiting">
233+
<transition event="start" target="processing">
234+
<!-- Send internal event with data -->
235+
<send target="#_internal" event="process_data">
236+
<param name="userId" expr="'user123'"/>
237+
<param name name="priority" expr="5"/>
238+
<content expr="'Processing started'"/>
239+
</send>
240+
</transition>
241+
</state>
242+
243+
<state id="processing">
244+
<transition event="process_data" target="complete">
245+
<!-- Event data available via _event.data -->
246+
<log expr="'Processing for user: ' + _event.data.userId"/>
247+
</transition>
248+
</state>
249+
250+
<state id="complete"/>
251+
</scxml>
252+
```
253+
254+
#### Dynamic Send Elements
255+
256+
```xml
257+
<state id="router">
258+
<transition event="route_message">
259+
<!-- Dynamic event and target evaluation -->
260+
<send targetexpr="_event.data.target"
261+
eventexpr="_event.data.eventName"
262+
namelist="status priority">
263+
<param name="timestamp" expr="Date.now()"/>
264+
</send>
265+
</transition>
266+
</state>
267+
```
268+
269+
#### Performance Optimization Examples
270+
271+
```elixir
272+
# Before v1.5.0 - O(depth) hierarchy operations
273+
time_uncached = benchmark_hierarchy_operations(uncached_document)
274+
275+
# After v1.5.0 - O(1) hierarchy operations with caching
276+
{:ok, cached_document, _warnings} = Statifier.parse(xml)
277+
time_cached = benchmark_hierarchy_operations(cached_document)
278+
279+
# Typical performance improvement: 5-15x speedup
280+
speedup = time_uncached / time_cached # => ~10.5x
281+
```
282+
283+
### Migration Guide
284+
285+
#### API Updates
286+
287+
```elixir
288+
# Before v1.5.0
289+
{:ok, document} = SCXML.parse(xml)
290+
{:ok, validated_doc, warnings} = Validator.validate(document)
291+
292+
# After v1.5.0 - Streamlined approach
293+
{:ok, document, warnings} = Statifier.parse(xml)
294+
```
295+
296+
#### Test Simplification
297+
298+
```elixir
299+
# Before v1.5.0 - Verbose XML
300+
xml = """
301+
<?xml version="1.0" encoding="UTF-8"?>
302+
<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" initial="idle">
303+
<state id="idle">
304+
<transition event="start" target="running"/>
305+
</state>
306+
<state id="running"/>
307+
</scxml>
308+
"""
309+
310+
# After v1.5.0 - Focus on logic
311+
xml = """
312+
<scxml initial="idle">
313+
<state id="idle">
314+
<transition event="start" target="running"/>
315+
</state>
316+
<state id="running"/>
317+
</scxml>
318+
"""
319+
```
320+
321+
### Notes
322+
323+
- **Major Release**: Comprehensive modernization spanning API, architecture, performance, and new SCXML features
324+
- **API Modernization**: Complete modernization of parsing and validation API for better developer experience
325+
- **Architectural Revolution**: Major refactoring with StateHierarchy, TransitionResolver, HierarchyCache, and SendAction modules
326+
- **Performance Breakthrough**: O(1) hierarchy operations provide 5-15x performance improvements for complex state machines
327+
- **SCXML Feature Expansion**: Basic send element support enables internal event communication and transition actions
328+
- **Quality Excellence**: Perfect Credo compliance, comprehensive test coverage (857 tests), and thorough documentation
329+
- **Developer Productivity**: Significant reduction in XML boilerplate and improved error handling
330+
- **Production Ready**: Battle-tested architecture with comprehensive edge case coverage and benchmark validation
331+
- **Foundation for Future**: Clean, extensible architecture prepares for advanced SCXML features (delays, external targets, etc.)
332+
10333
## [1.4.0] 2025-08-29
11334

12335
### Added

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ Add `statifier` to your list of dependencies in `mix.exs`:
147147
```elixir
148148
def deps do
149149
[
150-
{:statifier, "~> 1.4"}
150+
{:statifier, "~> 1.5"}
151151
]
152152
end
153153
```

mix.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ defmodule Statifier.MixProject do
22
use Mix.Project
33

44
@app :statifier
5-
@version "1.4.0"
5+
@version "1.5.0"
66
@description "StateCharts for Elixir with W3C compliance"
77
@source_url "https://github.com/riddler/statifier"
88
@deps [

0 commit comments

Comments
 (0)