Derived State
It is common to need to cache the result of expensive work that does not represent true alterations in application state. Derived state exists to store this kind of data in memory and keep it up to date when the underlying observable state changes.
DeriveDefinition
Derived state has all of the same issues with storage and retrieval that normal state does. Similar
to KeyDefinition, derived state depends on DeriveDefinitions to define magic string keys to
store and retrieve data from a cache. Unlike normal state, derived state is always stored in memory.
It still takes a StateDefinition, but this is used only to define a namespace for the derived
state, the storage location is ignored. This can lead to collisions if you use the same key for two
different derived state definitions in the same namespace.
Derive definitions can be created in two ways:
new DeriveDefinition(STATE_DEFINITION, "uniqueKey", _DeriveOptions_);
// or
const keyDefinition: KeyDefinition<T>;
DeriveDefinition.from(keyDefinition, _DeriveOptions_);
The first allows building from basic building blocks, the second recognizes that derived state is
often built from existing state and allows you to create a definition from an existing
KeyDefinition. The resulting DeriveDefinition will have the same state namespace, key, and
TFrom type as the KeyDefinition it was built from.
Type Parameters
DeriveDefinitions have three type parameters:
TFrom: The type of the state that the derived state is built from.TTo: The type of the derived state.TDeps: defines the dependencies required to derive the state. This is further discussed in Derive Definition Options.
DeriveDefinitionOptions
The DeriveDefinition section specifies a third parameter as
_DeriveOptions_, which is used to fully specify the way to transform TFrom to TTo.
deserializer- For the same reasons as Key Definition Options,DeriveDefinitions require have adeserializerfunction that is used to convert the stored data back into theTTotype.derive- A function that takes the current state and returns the derived state. This function takes two parameters:from- The latest value of the parent state.deps- dependencies used to instantiate the derived state. These are provided when theDerivedStateclass is instantiated. This object should contain all of the application runtime dependencies for transform the from parent state to the derived state.
cleanupDelayMs(optional) - Takes the number of milliseconds to wait before cleaning up the state after the last subscriber unsubscribes. Defaults to 1000ms. If you have a particularly expensive operation, such as decryption of a vault, it may be worth increasing this value to avoid unnecessary recomputation.
Specifying dependencies required for your derive function is done through the type parameters on
DerivedState.
new DerivedState<TFrom, TTo, { example: Dependency }>();
would require a deps object with an example property of type Dependency to be passed to any
DerivedState configured to use the DerivedDefinition.
Both derive and deserializer functions should take null inputs into consideration. Both parent
state and stored data for deserialization can be null or undefined.