import { Disposable } from '@typed/disposable'
export type Resume = ValueResume | LazyResume
export type ValueResume = { readonly type: 'value'; readonly value: A }
export type LazyResume = {
readonly type: 'lazy'
readonly resume: (cb: (value: A) => Disposable) => Disposable
}
export namespace Resume {
export const of = (value: A): Resume => ({ type: 'value', value })
export const create = (resume: (cb: (value: A) => Disposable) => Disposable): Resume => ({
type: 'lazy',
resume,
})
export const run = (f: (value: A) => Disposable, resume: Resume) =>
isValue(resume) ? f(resume.value) : resume.resume(f)
export const chain = (fn: (value: A) => Resume, resume: Resume): Resume =>
isValue(resume) ? fn(resume.value) : create((cb) => run((a) => run(cb, fn(a)), resume))
export const isValue = (resume: Resume): resume is ValueResume => resume.type === 'value'
export const isLazy = (resume: Resume): resume is LazyResume => resume.type === 'lazy'
}