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
BallastException
base-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 interfaces
instead 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:
InputStrategies
no 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. AChannelInputStrategy
base-class is used to implement the previous functionality of buffering through a channel. The existingLifo
,Fifo
, andParallel
InputStrategies all extend this base class, but you are free to extend it yourself if you need to tweak the configuration of the channel.InputFilter
has been removed as a property of theBallastViewModelConfiguration
, because the basic idea behind it is not compatible with all InputStrategies. Instead, theInputFilter
can be passed directly to theInputStrategies
which are compatible.- A new API,
EventStrategy
is 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
, aChannelEventStrategy
provides 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 tobuilder.withViewModel()
. Interceptors which do need to know specifics about the ViewModel instance and its Contract types (likeBootstrapInterceptor
) 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
BallastDebuggerInterceptor
are now encapsulated in theDebuggerAdapter
interface. Functions on theBallastDebuggerInterceptor
companion object keep the construction ofBallastDebuggerInterceptor
source-compatible, but you may now create your own instance ofDebuggerAdapter
for 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
@Serializable
withkotlinx.serialization
to use the built-inJsonDebuggerAdapter
orBallastDebuggerInterceptor()
convenience function. Alternatively, if you need to support a different serialization format or use a different serialization library, you can implement a customDebuggerAdapter
to 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.PopAllWithAnnotation
allows you to remove the last destinations which have a givenRouteAnnotation
. 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.PopUntilAnnotation
allows you to remove the last destinations until one is encountered with a specificRouteAnnotation
. For example, this may be used to annotation the first destination of a sub-flow with aRouteAnnotation
, so you can either quickly return to the start of the flow, or return to the destination just before starting the flow.RouterContract.Inputs.PopUntilRoute
has similar behavior toPopUntilAnnotation
, but uses Route types instead ofRouteAnnotation
.
- New Inputs added to the
ballast-saved-state
- You can now access (and return) the default initial state from the
RestoreStateScope
for 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
SaveStateScope
to allow you to manually determine if a value has been changed, rather than relying on the defaultequals
(!=
) operator. Overrides ofsaveDiff()
andsaveAll()
have an additionalisChanged
parameter 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