import { Disposable } from '@typed/disposable' import { createDeferred } from '@typed/promises' import { Fiber, FiberInfo, FiberState } from './Fiber' // Creates a fiber that automatically reacts to the mutation of its current info // Makes use of ES2015 Proxy, if required the available Proxy polyfills _should_ work for this use case. export function createFiber(): Fiber { const disposable = Disposable.lazy() const [promise, resolve, reject] = createDeferred() const handleFiberInfo = (info: FiberInfo) => { if (info.state === FiberState.Error) { return reject(info.error) } if (info.state === FiberState.Returned) { return resolve(info.value) } } // Besides observing when info is changed, it also coincidentally makes our fiber actually immutable for it's other fields function setFiberKey(target: Fiber, key: keyof Fiber, value: Fiber[keyof Fiber]) { if (key === 'info') { handleFiberInfo(value as FiberInfo) target[key] = value as FiberInfo return true } return false } const fiber: Fiber = new Proxy( { info: { state: FiberState.Running, promise }, ...disposable, }, { set: setFiberKey, }, ) return fiber }