Simplify Derivation.onStale()

This commit is contained in:
Aria Minaei 2022-12-01 13:33:52 +01:00
parent 5c1aa1cd50
commit f1cb8edc91
2 changed files with 6 additions and 53 deletions

View file

@ -1,51 +0,0 @@
import Emitter from '../utils/Emitter'
import type {default as Tappable} from '../utils/Tappable'
import type {IDerivation} from './IDerivation'
/**
* Like DerivationEmitter, but with a different performance model. DerivationValuelessEmitter emits every time the
* derivation is updated, even if the value didn't change, and tappers are called without the value. The advantage of
* this is that you have control over when the underlying derivation is freshened, it won't automatically be freshened
* by the emitter.
*/
export default class DerivationValuelessEmitter<V> {
_derivation: IDerivation<V>
_emitter: Emitter<void>
_hadTappers: boolean
constructor(
derivation: IDerivation<V>,
readonly dontEmitValues: boolean = false,
) {
this._derivation = derivation
this._emitter = new Emitter()
this._emitter.onNumberOfTappersChange(() => {
this._reactToNumberOfTappersChange()
})
this._hadTappers = false
return this
}
private _possiblyMarkAsStale = () => {
this._emitter.emit(undefined)
}
_reactToNumberOfTappersChange() {
const hasTappers = this._emitter.hasTappers()
if (hasTappers !== this._hadTappers) {
this._hadTappers = hasTappers
if (hasTappers) {
this._derivation.addDependent(this._possiblyMarkAsStale)
} else {
this._derivation.removeDependent(this._possiblyMarkAsStale)
}
}
}
/**
* The tappable associated with the emitter. You can use it to tap (subscribe to) the underlying derivation.
*/
tappable(): Tappable<void> {
return this._emitter.tappable
}
}

View file

@ -3,7 +3,6 @@ import type {$IntentionalAny, VoidFn} from '../../types'
import Stack from '../../utils/Stack' import Stack from '../../utils/Stack'
import type Tappable from '../../utils/Tappable' import type Tappable from '../../utils/Tappable'
import DerivationEmitter from '../DerivationEmitter' import DerivationEmitter from '../DerivationEmitter'
import DerivationValuelessEmitter from '../DerivationValuelessEmitter'
import type {IDerivation} from '../IDerivation' import type {IDerivation} from '../IDerivation'
import {isDerivation} from '../IDerivation' import {isDerivation} from '../IDerivation'
import { import {
@ -235,7 +234,12 @@ class PrismDerivation<V> implements IDerivation<V> {
* Returns a tappable that fires every time the prism's state goes from `fresh-\>stale.` * Returns a tappable that fires every time the prism's state goes from `fresh-\>stale.`
*/ */
onStale(callback: () => void): VoidFn { onStale(callback: () => void): VoidFn {
return new DerivationValuelessEmitter(this).tappable().tap(callback) const untap = () => {
this.removeDependent(fn)
}
const fn = () => callback()
this.addDependent(fn)
return untap
} }
/** /**