Migrate from V3 to V4
Ballast v4.0.0 is a major release, which some breaking changes in its public API and many changes to its internals. Most (but not all) changes are source-compatible with Ballast v3, but these changes are not intended to be binary-compatible.
Below is a list of all changes, broken down by module.
- All modules
- APIs that were deprecated since v3.0.0 have been removed.
- The BallastExceptionbase-class has been removed. Each module had already been using its own Exception sub-types where necessary, but these exceptions no longer share a common super-type.
- Modules which provided their own Inputs and Events classes are now changed to be sealed interfacesinstead ofsealed classes.
- Modules which provided their own Inputs and Events classes are now changed to use data objects.
- Added proper toString()values to Interceptors, for prettier logs
 
- ballast-api/- ballast-core- New API added to BallastInterceptorScope:getInitialState(). This allows an Interceptor to access the initial state passed to theBallastViewModelConfiguration.
- Began refactoring internals for greater flexibility. This work is only partly done, but some new features are now
available for advanced usage:
- InputStrategiesno longer require buffering Inputs through a Channel. You may create your own InputStrategy for special use-cases that do not use a Channel, like immediately dispatching Inputs, or buffering Inputs though another mechanism such as AWS SQS. A- ChannelInputStrategybase-class is used to implement the previous functionality of buffering through a channel. The existing- Lifo,- Fifo, and- ParallelInputStrategies all extend this base class, but you are free to extend it yourself if you need to tweak the configuration of the channel.
- InputFilterhas been removed as a property of the- BallastViewModelConfiguration, because the basic idea behind it is not compatible with all InputStrategies. Instead, the- InputFiltercan be passed directly to the- InputStrategieswhich are compatible.
- A new API, EventStrategyis now available to provide the same kind of pluggable extensibility for handling Events that is used for Inputs. This feature is still a work-in-progress, use at your own discretion. As with theInputStrategies, aChannelEventStrategyprovides the basic functionality of buffering Events through a Channel, and you can extend that base class to customize the channel's parameters.
 
- Builder.withViewModel()now returns a strongly-typed variant of the Builder class, allowing for greater type-safety when applying Interceptors. The new convention, which is somewhat enforced by the builder APIs, is that common Interceptors which don't require specifics about the Contract types (like logging, or attaching the debugger client) should be placed before the call to- builder.withViewModel(). Interceptors which do need to know specifics about the ViewModel instance and its Contract types (like- BootstrapInterceptor) should go after that call, to ensure the values passed to the interceptor match the ViewModel's types.
 
- New API added to 
- ballast-debugger- This artifact's dependency coordinates have been renamed to ballast-debugger-client.
- The lambdas passed to the BallastDebuggerInterceptorare now encapsulated in theDebuggerAdapterinterface. Functions on theBallastDebuggerInterceptorcompanion object keep the construction ofBallastDebuggerInterceptorsource-compatible, but you may now create your own instance ofDebuggerAdapterfor easier setup and maintenance.
- A new concept has been added to the Debugger UI and client: processing Inputs and restoring States from JSON (or
other serialized state). You simply need to mark your Input and State classes as @Serializablewithkotlinx.serializationto use the built-inJsonDebuggerAdapterorBallastDebuggerInterceptor()convenience function. Alternatively, if you need to support a different serialization format or use a different serialization library, you can implement a customDebuggerAdapterto deserialize values based on the incomingContentType.
 
- This artifact's dependency coordinates have been renamed to 
- ballast-navigation- New Inputs added to the RouterContract, to handle some common navigational patterns:- RouterContract.Inputs.PopAllWithAnnotationallows you to remove the last destinations which have a given- RouteAnnotation. For example, this may be used if a sub-flow's destinations all have a common annotation, so you can quickly exit the flow by removing all routes with that annotation.
- RouterContract.Inputs.PopUntilAnnotationallows you to remove the last destinations until one is encountered with a specific- RouteAnnotation. For example, this may be used to annotation the first destination of a sub-flow with a- RouteAnnotation, so you can either quickly return to the start of the flow, or return to the destination just before starting the flow.
- RouterContract.Inputs.PopUntilRoutehas similar behavior to- PopUntilAnnotation, but uses Route types instead of- RouteAnnotation.
 
 
- New Inputs added to the 
- ballast-saved-state- You can now access (and return) the default initial state from the RestoreStateScopefor cases where you want to optionally restore the state, rather than recreating the default initial state yourself within the Adapter, or passing the default initial state to multiple locations.
- New APIs have been added to SaveStateScopeto allow you to manually determine if a value has been changed, rather than relying on the defaultequals(!=) operator. Overrides ofsaveDiff()andsaveAll()have an additionalisChangedparameter where you can compare the previous and current values for equality.
 
- You can now access (and return) the default initial state from the 
- ballast-test- Test: A new API has been added to BallastScenarioScope,customizeConfiguration(). This allows you to fully customize the entire Builder configuration used to run the test.
 
- Test: A new API has been added to