Skip to content

Instantly share code, notes, and snippets.

@mattiamanzati
Created February 5, 2018 12:43
Show Gist options
  • Save mattiamanzati/355ffad896be2ede4c769a3e1b7ea0d7 to your computer and use it in GitHub Desktop.
Save mattiamanzati/355ffad896be2ede4c769a3e1b7ea0d7 to your computer and use it in GitHub Desktop.
import * as task from "fp-ts/lib/Task"
type IObserve<T> = (newValue: T) => task.Task<any>
type IIntercept<T> = (newValue: T) => task.Task<T>
function createAtom<T>(initialValue: T) {
let storedValue = initialValue
let observers: IObserve<T>[] = []
let interceptors: IIntercept<T>[] = []
function read() {
return task.of(storedValue)
}
function tryRead() {
return storedValue
}
function put(newValue: T) {
return observers.reduce(
(task, observer) => task.chain((v) => observer(v).map(() => v)),
interceptors.reduce(
(task, interceptor) => task.chain(interceptor),
task.of(newValue)
).chain((currentValue) => {
storedValue = currentValue
return task.of(currentValue)
})
)
}
function intercept(fn: IIntercept<T>) {
interceptors.push(fn)
}
function observe(fn: IObserve<T>) {
observers.push(fn)
}
return { read, tryRead, put, intercept, observe }
}
// EXAMPLE
const delay = (n: number) => <T>(value: T) => new task.Task<T>(() => new Promise((resolve) => setTimeout(() => resolve(value), n)))
const getCodicePagamentoPerConto = (codiceConto: number) => delay(1500)(codiceConto === 0 ? 0 : codiceConto)
const codiceConto = createAtom(0)
const codicePagamento = createAtom(0)
// al cambio del conto, propongo il codice pagamento
codiceConto.observe(nuovoConto => {
console.log("cerco i default per il conto", nuovoConto)
return getCodicePagamentoPerConto(nuovoConto).chain(defaultPagamento => codicePagamento.put(defaultPagamento))
})
// al cambio del codice pagamento, log
codicePagamento.observe(nuovoPagamento => {
console.log("il codice pagamento è ora", nuovoPagamento)
return task.of(nuovoPagamento)
})
task.of(null)
.chain(() => codiceConto.put(1))
.chain(() => codicePagamento.put(100))
.chain(codicePagamento.read)
.run()
.then(v => console.log("il codice di pagamento è ", v, "per il conto", codiceConto.tryRead()))
/*
OUTPUT:
cerco i default per il conto 1
il codice pagamento è ora 1
il codice pagamento è ora 100
il codice di pagamento è 100 per il conto 1
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment