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' }