export class MemoLazy<S, V> {
private selected: S | undefined = undefined
private _value: Promise<V> | undefined = undefined
constructor(
private selector: () => S,
private creator: (selected: S) => Promise<V>
) {}
get hasValue() {
return this._value !== undefined
}
get value(): Promise<V> {
const selected = this.selector()
if (this._value !== undefined && equals(this.selected, selected)) {
return this._value
}
this.selected = selected
const result = this.creator(selected)
this.value = result
return result
}
set value(value: Promise<V>) {
this._value = value
}
}
function equals(firstValue: any, secondValue: any): boolean {
const isFirstObject = typeof firstValue === "object" && firstValue !== null
const isSecondObject = typeof secondValue === "object" && secondValue !== null
if (isFirstObject && isSecondObject) {
const keys1 = Object.keys(firstValue)
const keys2 = Object.keys(secondValue)
return keys1.length === keys2.length && keys1.every((key: any) => equals(firstValue[key], secondValue[key]))
}
return firstValue === secondValue
}