By default all ActiveJS Units cache 2 values, and can be configured with minimum 1 or maximum Infinity for as many values as possible.

The cache is maintained in an array, at the last index we have the latest value, and at 0 index we have the first value. So the cache might look like this [initialValue, v1, v2, ... , lastDispatchedValue]. When the length becomes more than the cacheSize, values are removed from the start.

The way cache-navigation methods work is that, when you call one of them, let's say goBack, the Unit will emit the previous value from the cache, without modifying the cached values, so that the cached values would still be the same and in the same order. Only that the cacheIndex would now be cacheIndex - 1

Now if you dispatch a new value, this new value will be inserted directly after the current cacheIndex and all the values coming after that will be removed from the cache. So that the new value would become the last value in the cache. That's exactly how browser history works, we can open links after links, then we can go back and we can go forward, but as soon as we open a new link, that link becomes the last point in history, and now we can only go back.

However, if you don't want that to happen you can do an in-place cache replace by passing {replaceCache: true} flag to the dispatch method. It'll replace the value in cache at the current cacheIndex, just like we'd do History.replaceState() in case of browser history.

const unit = new StringUnit({initialValue: 'a'}); 

// cache is ['a']

unit.goBack(); // won't work, returns false
unit.goForward(); // won't work, returns false

unit.dispatch('b'); // cache becomes ['a', 'b']
console.log(unit.value()) // logs 'b'

unit.goBack(); // cache is still ['a', 'b']
console.log(unit.value()) // logs 'a'

unit.goForward(); // cache is still ['a', 'b']
console.log(unit.value()) // logs 'b'

unit.jumoToStart(); // cache is still ['a', 'b']
console.log(unit.value()) // logs 'a'

unit.dispatch('d', {replaceCache: true}) // now the cache becomes ['d', 'b']
// 'a' is gone, instead of 'b'
console.log(unit.value()) // logs 'd'

unit.jump(1) // cache is still ['d', 'b']
console.log(unit.value()) // logs 'b'

// we can also access all the cached values
console.log(unit.cachedValues()) // logs ['d', 'b']

// or check the current cache index
console.log(unit.cacheIndex) // logs 0

// or check the count of cached values
console.log(unit.cachedValuesCount) // logs 2

Cache navigation and immutability

When you use cache navigation with Units that store non-primitive values i.e. DictUnit, ListUnit, and GenericUnit, you will need to make sure to not mutate the value, otherwise cached value will also get mutated and goBack, goForward or other cache-navigation methods wouldn't work as expected, because the cached values would have been mutated, which is not what you expect.

To mitigate this problem you can simply make the Unit immutable, which will ensure that the cached values stay unaffected. See Immutability for how immutability works in ActiveJS Units.

Otherwise, you have to ensure that every time you dispatch a value it shouldn't have any reference to the Unit's current value, and when you access the Unit's value, you should make sure to not mutate this value in any way.

Last updated