theatre/packages/dataverse/src/derivations/DerivationFromSource.ts

73 lines
1.7 KiB
TypeScript
Raw Normal View History

2021-06-18 13:05:06 +02:00
import type {VoidFn} from '../types'
import AbstractDerivation from './AbstractDerivation'
const noop = () => {}
2022-01-19 13:06:13 +01:00
/**
* Represents a derivation based on a tappable (subscribable) data source.
*/
2021-06-18 13:05:06 +02:00
export default class DerivationFromSource<V> extends AbstractDerivation<V> {
private _untapFromChanges: () => void
private _cachedValue: undefined | V
private _hasCachedValue: boolean
2022-01-19 13:06:13 +01:00
/**
2022-02-23 22:53:39 +01:00
* @param _tapToSource - A function that takes a listener and subscribes it to the underlying data source.
* @param _getValueFromSource - A function that returns the current value of the data source.
2022-01-19 13:06:13 +01:00
*/
2021-06-18 13:05:06 +02:00
constructor(
private readonly _tapToSource: (listener: (newValue: V) => void) => VoidFn,
private readonly _getValueFromSource: () => V,
) {
super()
this._untapFromChanges = noop
this._cachedValue = undefined
this._hasCachedValue = false
}
2022-01-19 13:06:13 +01:00
/**
* @internal
*/
2021-06-18 13:05:06 +02:00
_recalculate() {
if (this.isHot) {
if (!this._hasCachedValue) {
this._cachedValue = this._getValueFromSource()
this._hasCachedValue = true
}
return this._cachedValue as V
} else {
return this._getValueFromSource()
}
}
2022-01-19 13:06:13 +01:00
/**
* @internal
*/
2021-06-18 13:05:06 +02:00
_keepHot() {
this._hasCachedValue = false
this._cachedValue = undefined
this._untapFromChanges = this._tapToSource((newValue) => {
this._hasCachedValue = true
this._cachedValue = newValue
this._markAsStale(this)
})
}
2022-01-19 13:06:13 +01:00
/**
* @internal
*/
2021-06-18 13:05:06 +02:00
_becomeCold() {
this._untapFromChanges()
this._untapFromChanges = noop
this._hasCachedValue = false
this._cachedValue = undefined
}
2022-01-19 13:06:13 +01:00
/**
* @internal
*/
2021-06-18 13:05:06 +02:00
_reactToDependencyBecomingStale() {}
}